def startGUI(args): """Create the QT4 application and GUI. A (possibly empty) list of command line options should be provided. QT4 wil remove the recognized QT4 and X11 options. """ # This seems to be the only way to make sure the numeric conversion is # always correct # QtCore.QLocale.setDefault(QtCore.QLocale.c()) # #pf.options.debug = -1 pf.debug("Arguments passed to the QApplication: %s" % args) pf.app = QtGui.QApplication(args) # pf.debug("Arguments left after constructing the QApplication: %s" % args) pf.debug("Arguments left after constructing the QApplication: %s" % pf.app.arguments().join('\n')) #pf.options.debug = 0 # As far as I have been testing this, the args passed to the Qt application are # NOT acknowledged and neither are they removed!! pf.app.setOrganizationName("pyformex.org") pf.app.setOrganizationDomain("pyformex.org") pf.app.setApplicationName("pyFormex") pf.app.setApplicationVersion(pf.__version__) ## pf.settings = QtCore.QSettings("pyformex.org", "pyFormex") ## pf.settings.setValue("testje","testvalue") #QtCore.QObject.connect(pf.app,QtCore.SIGNAL("lastWindowClosed()"),pf.app,QtCore.SLOT("quit()")) QtCore.QObject.connect(pf.app,QtCore.SIGNAL("lastWindowClosed()"),quitGUI) #QtCore.QObject.connect(pf.app,QtCore.SIGNAL("aboutToQuit()"),quitGUI) # Check if we have DRI viewport.setOpenGLFormat() dri = viewport.opengl_format.directRendering() # Check for existing pyFormex processes windowname,running = findOldProcesses() while len(running) > 0: if len(running) >= 16: print("Too many open pyFormex windows --- bailing out") return -1 pids = [ i[2] for i in running if i[2] is not None ] warning = """.. pyFormex is already running on this screen ------------------------------------------ A main pyFormex window already exists on your screen. If you really intended to start another instance of pyFormex, you can just continue now. The window might however be a leftover from a previously crashed pyFormex session, in which case you might not even see the window anymore, nor be able to shut down that running process. In that case, you would better bail out now and try to fix the problem by killing the related process(es). If you think you have already killed those processes, you may check it by rerunning the tests. """ actions = ['Really Continue','Rerun the tests','Bail out and fix the problem'] if pids: warning += """ I have identified the process(es) by their PID as:: %s If you trust me enough, you can also have me kill this processes for you. """ % pids actions[2:2] = ['Kill the running processes'] if dri: answer = draw.ask(warning,actions) else: warning += """ I have detected that the Direct Rendering Infrastructure is not activated on your system. Continuing with a second instance of pyFormex may crash your XWindow system. You should seriously consider to bail out now!!! """ answer = draw.warning(warning,actions) if answer == 'Really Continue': break # OK, Go ahead elif answer == 'Rerun the tests': windowname,running = findOldProcesses() # try again elif answer == 'Kill the running processes': killProcesses(pids) windowname,running = findOldProcesses() # try again else: return -1 # I'm out of here! # Load the splash image splash = None if os.path.exists(pf.cfg['gui/splash']): pf.debug('Loading splash %s' % pf.cfg['gui/splash']) splashimage = QtGui.QPixmap(pf.cfg['gui/splash']) splash = QtGui.QSplashScreen(splashimage) splash.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) splash.setFont(QtGui.QFont("Helvetica",24)) splash.showMessage(pf.Version,QtCore.Qt.AlignHCenter,QtCore.Qt.red) splash.show() # create GUI, show it, run it pf.GUI = GUI(windowname, pf.cfg.get('gui/size',(800,600)), pf.cfg.get('gui/pos',(0,0)), pf.cfg.get('gui/bdsize',(800,600)), ) # set the appearance pf.GUI.setAppearence() # setup the message board pf.board = pf.GUI.board pf.board.write("""%s (C) Benedict Verhegghe pyFormex comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU General Public License, version 3 or later. See Help->License or the file COPYING for details. """ % pf.Version) # Set interaction functions def show_warning(message,category,filename,lineno,file=None,line=None): """Replace the default warnings.showwarning We display the warnings using our interactive warning widget. This feature can be turned off by setting cfg['warnings/popup'] = False """ full_message = warnings.formatwarning(message,category,filename,lineno,line) ## from widgets import simpleInputItem as I ## res = draw.askItems([ ## I('message',message,itemtype='label',text='warning'), ## I('filter',False,text='Suppress this message in future sessions'), ## ],actions=[('OK',)],legacy=False) #print res pf.message(full_message) res,check = draw.showMessage(full_message,level='warning',check="Do not show this warning anymore in future sessions") if check[0]: oldfilters = pf.prefcfg['warnings/filters'] newfilters = oldfilters + [(str(message),)] pf.prefcfg.update({'filters':newfilters},name='warnings') ## def format_warning(message,category,filename,lineno,line=None): ## """Replace the default warnings.formatwarning ## We display the warnings using our interactive warning widget. ## This feature can be turned off by setting ## cfg['nice_warnings'] = False ## """ ## import messages ## message = messages.getMessage(message) ## message = """.. ## pyFormex Warning ## ================ ## %s ## `Called from:` %s `line:` %s ## """ % (message,filename,lineno) ## if line: ## message += "%s\n" % line ## return message ## if pf.cfg['warnings/nice']: ## warnings.formatwarning = format_warning if pf.cfg['warnings/popup']: warnings.showwarning = show_warning pf.message = draw.message pf.warning = draw.warning # setup the canvas pf.GUI.viewports.changeLayout(1) pf.GUI.viewports.setCurrent(0) pf.canvas = pf.GUI.viewports.current draw.reset() # setup the status bar pf.GUI.addInputBox() pf.GUI.toggleInputBox(False) pf.GUI.addCoordsTracker() pf.GUI.toggleCoordsTracker(pf.cfg.get('gui/coordsbox',False)) pf.debug("Using window name %s" % pf.GUI.windowTitle()) # Create additional menus (put them in a list to save) # History Menu pf.GUI.history = scriptMenu.ScriptMenu('History',files=pf.cfg['gui/history'],max=pf.cfg['gui/history_max']) if pf.cfg.get('gui/history_in_main_menu',False): before = pf.GUI.menu.item('help') pf.GUI.menu.insertMenu(before,pf.GUI.history) else: filemenu = pf.GUI.menu.item('file') before = filemenu.item('---1') filemenu.insertMenu(before,pf.GUI.history) # Scripts menu pf.GUI.scriptmenu = scriptMenu.createScriptMenu(pf.GUI.menu,before='help') # Create databases createDatabases() # PLugin menus import plugins ## filemenu = pf.GUI.menu.item('file') ## pf.gui.saveobj = plugins.create_plugin_menus(filemenu,before='options') ## # Load configured plugins, ignore if not found plugins.loadConfiguredPlugins() #for p in pf.cfg['gui/plugins']: # plugins.load(p) pf.GUI.setBusy(False) pf.GUI.addStatusBarButtons() # remove the splash window if splash is not None: splash.finish(pf.GUI) pf.GUI.setBusy(False) if os.path.isdir(pf.cfg['workdir']): # Make the workdir the current dir os.chdir(pf.cfg['workdir']) pf.debug("Setting workdir to %s" % pf.cfg['workdir']) else: # Save the current dir as workdir prefMenu.updateSettings({'workdir':os.getcwd(),'Save changes':True}) pf.GUI.show() pf.GUI.update() pf.app_started = True pf.GUI.processEvents() return 0
def runApp(args): """Create and run the qt application.""" # # FIX FOR A BUG IN NUMPY (It's always sane anyway) # import locale GD.debug("LC_NUMERIC = %s" % locale.setlocale(locale.LC_NUMERIC)) # GD.app = QtGui.QApplication(args) # GD.debug("LC_NUMERIC = %s" % locale.setlocale(locale.LC_NUMERIC)) locale.setlocale(locale.LC_NUMERIC, 'C') GD.debug("LC_NUMERIC = %s" % locale.setlocale(locale.LC_NUMERIC)) # # # QtCore.QObject.connect(GD.app,QtCore.SIGNAL("lastWindowClosed()"),GD.app,QtCore.SLOT("quit()")) QtCore.QObject.connect(GD.app,QtCore.SIGNAL("aboutToQuit()"),quit) # Load the splash image splash = None if os.path.exists(GD.cfg['gui/splash']): GD.debug('Loading splash %s' % GD.cfg['gui/splash']) splashimage = QtGui.QPixmap(GD.cfg['gui/splash']) splash = QtGui.QSplashScreen(splashimage) splash.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) splash.setFont(QtGui.QFont("Helvetica",24)) splash.showMessage(GD.Version,QtCore.Qt.AlignHCenter,QtCore.Qt.red) splash.show() # create GUI, show it, run it viewport.setOpenGLFormat() dri = viewport.opengl_format.directRendering() windowname = GD.Version count = 0 while windowExists(windowname): if count > 255: print "Can not open the main window --- bailing out" return 1 count += 1 windowname = '%s (%s)' % (GD.Version,count) if count > 0: warning = """ Another instance of pyFormex is already running on this screen. This may be a leftover from a previously crashed program. In that case you should bail out now and first kill the crashed program. On the other hand, if you really want to run another pyFormex in parallel, you can just continue now. """ actions = ['Really Continue','Bail out and fix the problem'] if dri: answer = draw.ask(warning,actions) if not dri: warning += """ I have detected that the Direct Rendering Infrastructure is not activated on your system. Continuing with a second instance of pyFormex may crash you XWindow system. You should seriously consider to bail out now!!! """ answer = draw.warning(warning,actions) if answer != 'Really Continue': return 1 GD.gui = GUI(windowname, GD.cfg.get('gui/size',(800,600)), GD.cfg.get('gui/pos',(0,0)), GD.cfg.get('gui/bdsize',(800,600)) ) # set the appearence GD.gui.setStyle(GD.cfg.get('gui/style','Plastique')) font = GD.cfg.get('gui/font',None) if font: GD.gui.setFont(font) else: fontfamily = GD.cfg.get('gui/fontfamily',None) if fontfamily: GD.gui.setFontFamily(fontfamily) fontsize = GD.cfg.get('gui/fontsize',None) if fontsize: GD.gui.setFontSize(fontsize) GD.gui.viewports.changeLayout(1) GD.gui.viewports.setCurrent(0) GD.board = GD.gui.board GD.board.write("""%s (C) Benedict Verhegghe pyFormex comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU General Public License, version 3 or later. See Help->License or the file COPYING for details. """ % GD.Version) GD.gui.show() GD.debug("Using window name %s" % GD.gui.windowTitle()) # Create additional menus (put them in a list to save) # History Menu history = GD.cfg.get('history',None) if type(history) == list: GD.gui.history = scriptsMenu.ScriptsMenu('History',files=history,max=20) if GD.cfg.get('gui/history_in_main_menu',False): before = GD.gui.menu.item('help').menuAction() GD.gui.menu.insertMenu(before,GD.gui.history) else: filemenu = GD.gui.menu.item('file') before = filemenu.item('---1') filemenu.insertMenu(before,GD.gui.history) # Script menu scriptmenu = createScriptMenu() # Set interaction functions GD.message = draw.message GD.warning = draw.warning draw.reset() # Load plugins, ignore if not found import plugins for p in GD.cfg.get('gui/plugins',[]): try: m = getattr(plugins,p) if hasattr(m,'show_menu'): m.show_menu() except: GD.debug('ERROR while loading plugin %s' % p) GD.gui.setBusy(False) GD.gui.update() GD.gui.addStatusBarButtons() # remove the splash window if splash is not None: splash.finish(GD.gui) GD.gui.setBusy(False) GD.gui.update() if os.path.isdir(GD.cfg['workdir']): # Make the workdir the current dir os.chdir(GD.cfg['workdir']) else: # Save the current dir as workdir GD.cfg['workdir'] = os.getcwd() GD.app_started = True if GD.gui.easter_egg: draw.playScript(utils.mergeme(*GD.gui.easter_egg)) # remaining args are interpreted as scripts and their parameters script.runApp(args) # Go into interactive mode GD.debug("Start main loop") GD.app.exec_() GD.debug("Exit main loop") return 0
def runApp(args): """Create and run the qt application.""" GD.app = QtGui.QApplication(args) QtCore.QObject.connect(GD.app,QtCore.SIGNAL("lastWindowClosed()"),GD.app,QtCore.SLOT("quit()")) QtCore.QObject.connect(GD.app,QtCore.SIGNAL("aboutToQuit()"),quit) # Set some globals GD.image_formats_qt = map(str,QtGui.QImageWriter.supportedImageFormats()) GD.image_formats_qtr = map(str,QtGui.QImageReader.supportedImageFormats()) if GD.cfg.get('imagesfromeps',False): GD.image_formats_qt = [] if GD.options.debug: print "Qt image types for saving: ",GD.image_formats_qt print "Qt image types for input: ",GD.image_formats_qtr print "gl2ps image types:",GD.image_formats_gl2ps print "image types converted from EPS:",GD.image_formats_fromeps # Load the splash image splash = None if os.path.exists(GD.cfg['gui/splash']): GD.debug('Loading splash %s' % GD.cfg['gui/splash']) splashimage = QtGui.QPixmap(GD.cfg['gui/splash']) splash = QtGui.QSplashScreen(splashimage) splash.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) splash.setFont(QtGui.QFont("Helvetica",24)) splash.showMessage(GD.Version,QtCore.Qt.AlignHCenter,QtCore.Qt.red) splash.show() # create GUI, show it, run it viewport.setOpenGLFormat() dri = viewport.opengl_format.directRendering() windowname = GD.Version count = 0 while windowExists(windowname): if count > 255: print "Can not open the main window --- bailing out" return 1 count += 1 windowname = '%s (%s)' % (GD.Version,count) if count > 0: warning = """ Another instance of pyFormex is already running on this screen. This may be a leftover from a previously crashed program. In that case you should bail out now and first kill the crashed program. On the other hand, if you really want to run another pyFormex in parallel, you can just continue now. """ actions = ['Really Continue','Bail out and fix the problem'] if dri: answer = draw.ask(warning,actions) if not dri: warning += """ I have detected that the Direct Rendering Infrastructure is not activated on your system. Continuing with a second instance of pyFormex may crash you XWindow system. You should seriously consider to bail out now!!! """ answer = draw.warning(warning,actions) if answer != 'Really Continue': return 1 GD.gui = GUI(windowname, GD.cfg.get('gui/size',(800,600)), GD.cfg.get('gui/pos',(0,0)), GD.cfg.get('gui/bdsize',(800,600)) ) # set the appearence GD.gui.setStyle(GD.cfg.get('gui/style','Plastique')) font = GD.cfg.get('gui/font',None) if font: GD.gui.setFont(font) else: fontfamily = GD.cfg.get('gui/fontfamily',None) if fontfamily: GD.gui.setFontFamily(fontfamily) fontsize = GD.cfg.get('gui/fontsize',None) if fontsize: GD.gui.setFontSize(fontsize) GD.gui.viewports.changeLayout(1) GD.gui.viewports.setCurrent(0) GD.board = GD.gui.board GD.board.write("""%s (C) B. Verhegghe pyFormex comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See Help->License or the file COPYING for details. """ % GD.Version) GD.gui.show() GD.debug("Using window name %s" % GD.gui.windowTitle()) # Create additional menus (put them in a list to save) # History Menu history = GD.cfg.get('history',None) if type(history) == list: GD.gui.history = scriptsMenu.ScriptsMenu('History',files=history,max=20) if GD.cfg.get('gui/history_in_main_menu',False): before = GD.gui.menu.item('help').menuAction() GD.gui.menu.insertMenu(before,GD.gui.history) else: filemenu = GD.gui.menu.item('file') before = filemenu.item('---1') filemenu.insertMenu(before,GD.gui.history) # Create a menu with pyFormex examples # and insert it before the help menu menus = [] scriptdirs = GD.cfg['scriptdirs'] knownscriptdirs = { 'examples': GD.cfg['examplesdir'] } if GD.cfg.get('gui/separate_script_dirs',False): # This will create separate menus for all scriptdirs pass else: # The default is to collect all scriptdirs in a single main menu if len(scriptdirs) > 1: scriptsmenu = widgets.Menu('Scripts',GD.gui.menu) before = GD.gui.menu.item('help').menuAction() GD.gui.menu.insertMenu(before,scriptsmenu) before = None else: scriptsmenu = GD.gui.menu before = scriptsmenu.itemAction('help') for title,dirname in scriptdirs: GD.debug("Loading script dir %s" % dirname) if not dirname: dirname = knownscriptdirs[title.lower()] if os.path.exists(dirname): m = scriptsMenu.ScriptsMenu(title,dirname,autoplay=True) scriptsmenu.insert_menu(m,before) menus.append(m) # Needed to keep m linked to a name, # else the menu is destroyed! # Set interaction functions GD.message = draw.message GD.warning = draw.warning draw.reset() # Load plugins, ignore if not found import plugins for p in GD.cfg.get('gui/plugins',[]): try: m = getattr(plugins,p) if hasattr(m,'show_menu'): m.show_menu() except: GD.debug('ERROR while loading plugin %s' % p) GD.gui.setBusy(False) GD.gui.update() # remove the splash window if splash is not None: splash.finish(GD.gui) # Add the autorun script to the remaining args if GD.gui.easter_egg: draw.playScript(utils.mergeme(*GD.gui.easter_egg)) ar = GD.cfg.get('autorun','') if ar: if type(ar) == str: ar = [ar] args = ar + args # remaining args are interpreted as scripts for arg in args: if os.path.exists(arg): draw.play(arg) GD.gui.setBusy(False) GD.gui.update() if os.path.isdir(GD.cfg['workdir']): # Make the workdir the current dir os.chdir(GD.cfg['workdir']) else: # Save the current dir as workdir GD.cfg['workdir'] = os.getcwd() GD.app_started = True GD.app.exec_() # Cleanup draw.drawrelease() GD.gui.setBusy(False) # store the history and main window size/pos GD.cfg['history'] = GD.gui.history.files # Sometimes, a negative value is stored, making restart partially obscured x,y = Pos(GD.gui) if x < 0: x = 0 if y < 0: y = 0 GD.cfg.update({'size':Size(GD.gui), 'pos':(x,y), 'bdsize':Size(GD.gui.board), },name='gui') return 0
def hasDRI(): """Check whether the OpenGL canvas has DRI enabled.""" viewport.setOpenGLFormat() dri = viewport.opengl_format.directRendering() return dri