Package Camelot :: Package camelot :: Package view :: Module main |
[frames] | no frames]

# Source Code for Module Camelot.camelot.view.main

      1  """Main function, to be called to start the GUI interface"""
      2  from PyQt4.QtCore import QObject
      3

      4 -class Application(QObject):
      5      """The camelot application.  This class will take care of the order of

      6      initialization of various stuff needed to get the application up and

      7      running, each of its methods will be called in subsequent order,

      8      overwrite any of them to customize its behaviour.

      9

     10      This class will create the QApplication and call its processEvents

     11      method regulary will starting up the application

     12      """
     13

     14 -    def __init__(self, application_admin):
     15          """:param application_admin: a subclass of camelot.admin.application_admin.ApplicationAdmin

     16          customized to your app"""
     17          self.application_admin = application_admin
     18

     19 -    def show_splashscreen(self):
     20          """:return: the splash window"""
     21          from PyQt4 import QtGui
     22          pixmap = self.application_admin.get_splashscreen()
     23          # don't let splash screen stay on top, this might hinder

     24          # registration wizards or others that wait for user input

     25          # while camelot is starting up

     26          # flag = QtCore.Qt.WindowStaysOnTopHint

     27          splash_window = QtGui.QSplashScreen(pixmap) #, flag)
     28          splash_window.show()
     29          return splash_window
     30

     31 -    def show_splash_message(self, splash_window, message):
     32          """:param message: displays a message on the splash screen, informing

     33          the user of the status of the application"""
     34          from PyQt4 import QtCore
     35          msgalign = QtCore.Qt.AlignBottom #| QtCore.Qt.AlignRight
     36          msgcolor = QtCore.Qt.white
     37          splash_window.showMessage(message, msgalign, msgcolor)
     38

     39 -    def set_application_attributes(self, application):
     40          """Sets the attributes of the QApplication object

     41          :param application: the QApplication object"""
     42          application.setOrganizationName(self.application_admin.get_organization_name())
     43          application.setOrganizationDomain(self.application_admin.get_organization_domain())
     44          application.setApplicationName(self.application_admin.get_name())
     45          application.setWindowIcon(self.application_admin.get_icon())
     46

     47 -    def pre_initialization(self):
     48          """Method that is called before the model thread is started, while the app is still

     49          running single threaded"""
     50          pass
     51

     52 -    def start_model_thread(self):
     53          """Launch the second thread where the model lives"""
     54          from camelot.view.model_thread import get_model_thread, construct_model_thread
     55          from camelot.view.remote_signals import construct_signal_handler
     56          construct_model_thread()
     57          construct_signal_handler()
     58          get_model_thread().start()
     59

     60 -    def load_translations(self, application):
     61          """Fill the QApplication with the needed translations

     62          :param application: the QApplication on which to install the translator

     63          """
     64          from camelot.core.utils import load_translations
     65          from camelot.view.model_thread import get_model_thread
     66          get_model_thread().post(load_translations)
     67          translator = self.application_admin.get_translator()
     68          application.installTranslator(translator)
     69

     70 -    def initialization(self):
     71          """Method that is called afther the model has been set up, before the main

     72          window is constructed"""
     73          pass
     74

     75 -    def create_main_window(self):
     76          """:return: a QWidget representing the main window, upon its appearance, the splash

     77          screen will be closed"""
     78          return self.application_admin.create_main_window()
     79

     80 -    def close_splashscreen(self, splash_window, main_window):
     81          """closes the splashcreen on appearance of the main window

     82          :param splash_window: the splash screen window, as generated by the

     83          show splashcreen function

     84          """
     85          main_window.show()
     86          splash_window.finish(main_window)
     87

     88 -    def start_event_loop(self, application):
     89          """Starts the application's main event loop, wait until it is finished, then

     90          exit

     91          :param application: the QApplication to run"""
     92          import sys
     93          sys.exit(application.exec_())
     94

     95 -    def initialization_exception(self, exception_info):
     96          """This method is called whenever an exception occurs before the event

     97          loop has been started, by default, this method pops up a message box to

     98          inform the user

     99          :param exception_info: a tuple (exception, traceback_print) where traceback_print

    100          is a string representation of the traceback

    101          """
    102          from camelot.view.controls import exception
    103          exception.model_thread_exception_message_box(exception_info)
    104

    105 -    def main(self):
    106          """the main function of the application, this will call all other

    107          functions before starting the event loop"""
    108          import logging
    109          logger = logging.getLogger('camelot.view.main')
    110          try:
    111              #

    112              # before anything else happens or is imported, the splash screen should be there

    113              #

    114              import sys
    115              from PyQt4 import QtGui, QtCore
    116              app = QtGui.QApplication([a for a in sys.argv if a])
    117              splash_window = self.show_splashscreen()
    118

    119              self.show_splash_message(splash_window, 'Initialize application...')
    120              # regularly call processEvents to keep the splash alive

    121              app.processEvents()
    122              #  font = app.font()

    123              #  font.setStyleStrategy(QtGui.QFont.PreferAntialias)

    124              #  font.setPointSize(font.pointSize()+1)

    125              #  app.setFont(font)

    126

    127              QT_MAJOR_VERSION = float('.'.join(str(QtCore.QT_VERSION_STR).split('.')[0:2]))
    128              logger.debug('qt version %s, pyqt version %s' %

    129                           (QtCore.QT_VERSION_STR, QtCore.PYQT_VERSION_STR))
    130              logger.debug('qt major version %f' % QT_MAJOR_VERSION)
    131              app.processEvents()
    132              import sqlalchemy, elixir
    133              logger.debug('sqlalchemy version %s'%sqlalchemy.__version__)
    134              logger.debug('elixir version %s'%elixir.__version__)
    135              app.processEvents()
    136              self.set_application_attributes(app)
    137              self.pre_initialization()
    138              app.processEvents()
    139              # regularly call processEvents to keep the splash alive

    140              self.show_splash_message(splash_window, 'Setup database...')
    141              app.processEvents()
    142              self.start_model_thread()
    143              app.processEvents()
    144

    145              #

    146              # WEIRD, if we put this code in a method, the translations

    147              # don't work

    148              #

    149              from camelot.core.utils import load_translations
    150              from camelot.view.model_thread import get_model_thread
    151              get_model_thread().post(load_translations)
    152              self.show_splash_message(splash_window, 'Load translations...')
    153              translator = self.application_admin.get_translator()
    154              app.installTranslator(translator)
    155

    156              #self.load_translations(app)

    157              app.processEvents()
    158              # Set the style sheet

    159              self.show_splash_message(splash_window, 'Create main window...')
    160              stylesheet = self.application_admin.get_stylesheet()
    161              if stylesheet:
    162                  app.setStyleSheet(stylesheet)
    163              app.processEvents()
    164              self.initialization()
    165              app.processEvents()
    166              main_window = self.create_main_window()
    167              self.close_splashscreen(splash_window, main_window)
    168              return self.start_event_loop(app)
    169          except Exception, e:
    170              logger.error( 'exception in initialization', exc_info = e )
    171              import traceback, cStringIO
    172              sio = cStringIO.StringIO()
    173              traceback.print_exc(file=sio)
    174              traceback_print = sio.getvalue()
    175              sio.close()
    176              exception_info = (e, traceback_print)
    177              self.initialization_exception(exception_info)
    178

    179 -def main(application_admin,

    180           initialization=lambda:None,

    181           pre_initialization=lambda:None):
    182      """shortcut main function, call this function to start the GUI interface with minimal hassle

    183      and without the need to construct an Application object.  If you need to customize the initialization

    184      process, construct an Application subclass and use it's main method.

    185

    186      @param application_admin: object of type ApplicationAdmin (as defined in application_admin.py)

    187      that specifies the look of the GUI interface

    188      @param initialization: function that will be called during the appearance of the splash

    189      screen, put all time consuming initialization here.  this function will be called after the

    190      model thread has been started.

    191      @param pre-initialization: function that will be called before the model thread has been started,

    192      but after the QApplication has been created.  This function can be used to run a configuration

    193      wizard before a connection to the database was made or any gui element has been constructed.

    194      """
    195

    196      class ShortcutApplication(Application):
    197

    198          def initialization(self):
    199              initialization()
    200

    201          def pre_initialization(self):
    202              pre_initialization()
    203

    204      app = ShortcutApplication(application_admin)
    205      app.main()
    206

    207  if __name__ == '__main__':
    208      from application_admin import ApplicationAdmin
    209      main(ApplicationAdmin())
    210