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