def onInit(self, showSplash=True, testMode=False): """ :Parameters: testMode: bool If set to True then startup wizard won't appear and stdout/stderr won't be redirected to the Coder """ self.version = psychopy.__version__ self.SetAppName('PsychoPy2') # import localization after wx: from psychopy.app import localization # needed by splash screen self.localization = localization self.locale = localization.wxlocale self.locale.AddCatalog(self.GetAppName()) # set default paths and prefs self.prefs = psychopy.prefs if self.prefs.app['debugMode']: logging.console.setLevel(logging.DEBUG) # indicates whether we're running for testing purposes self.testMode = testMode self.osf_session = None if showSplash: # show splash screen splashFile = os.path.join( self.prefs.paths['resources'], 'psychopySplash.png') splashBitmap = wx.Image(name=splashFile).ConvertToBitmap() splash = AS.AdvancedSplash(None, bitmap=splashBitmap, timeout=3000, style=AS.AS_TIMEOUT | wx.FRAME_SHAPED, shadowcolour=wx.RED) # transparency? splash.SetTextPosition((10, 240)) splash.SetText(_translate(" Loading libraries...")) else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self if splash: splash.SetText(_translate(" Loading PsychoPy2...")) from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, dialogs, urls self.keys = self.prefs.keys self.prefs.pageCurrent = 0 # track last-viewed page, can return there self.IDs = IDStore() self.urls = urls.urls self.quitting = False # check compatibility with last run version (before opening windows) self.firstRun = False if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: self.firstrunWizard() # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # get preferred view(s) from prefs and previous view if self.prefs.app['defaultView'] == 'last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation allowed = ['last', 'coder', 'builder', 'both'] if self.prefs.app['defaultView'] in allowed: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] # then override the prev files by command options and passed files if len(sys.argv) > 1: if sys.argv[1] == __name__: # program was executed as "python.exe PsychoPyIDE.py %1' args = sys.argv[2:] else: # program was executed as "PsychoPyIDE.py %1' args = sys.argv[1:] # choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame = 'builder' args = args[1:] # can remove that argument elif args[0] in ['coder', '--coder', '-c']: mainFrame = 'coder' args = args[1:] # can remove that argument # did we get .py or .psyexp files? elif args[0][-7:] == '.psyexp': mainFrame = 'builder' exps = [args[0]] elif args[0][-3:] == '.py': mainFrame = 'coder' scripts = [args[0]] else: args = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) self._codeFont.SetFaceName(self.prefs.coder['codeFont']) # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) self.coder = None self.copiedRoutine = None self.copiedCompon = None self._allFrames = [] # ordered; order updated with self.onNewTopWindow if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None prefsConn = self.prefs.connections if prefsConn['checkForUpdates'] or prefsConn['allowUsageStats']: connectThread = threading.Thread( target=connections.makeConnections, args=(self,)) connectThread.start() # query github in the background to populate a local cache about # what versions are available for download: from psychopy.tools import versionchooser as vc versionsThread = threading.Thread(target=vc._remoteVersions, args=(True,)) versionsThread.start() ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if self.prefs.app['showStartupTips'] and not self.testMode: tipFile = os.path.join( self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() if self.prefs.connections['checkForUpdates']: self.Bind(wx.EVT_IDLE, self.checkUpdates) else: self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: if wx.version() >= '3.0' and sys.platform == 'darwin': _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if mainFrame in ['both', 'builder']: self.showBuilder() else: self.showCoder() return True
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool """ self.SetAppName('PsychoPy3') if showSplash: #showSplash: # show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashImage = wx.Image(name=splashFile) splashImage.ConvertAlphaToMask() splash = AS.AdvancedSplash( None, bitmap=splashImage.ConvertToBitmap(), timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN, ) # transparency? w, h = splashImage.GetSize() splash.SetTextPosition((int(340), h - 30)) splash.SetText( _translate("Copyright (C) 2020 OpenScienceTools.org")) else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, runner, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: pass # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] runlist = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) try: self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) except wx._core.wxAssertionError: # if no SYS_ANSI_FIXED_FONT then try generic FONTFAMILY_MODERN self._codeFont = wx.Font(self._mainFont.GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) # that gets most of the properties of _codeFont but the FaceName # FaceName is set in the setting of the theme: self.theme = self.prefs.app['theme'] # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) # Parse incoming call parser = argparse.ArgumentParser(prog=self) parser.add_argument('--builder', dest='builder', action="store_true") parser.add_argument('-b', dest='builder', action="store_true") parser.add_argument('--coder', dest='coder', action="store_true") parser.add_argument('-c', dest='coder', action="store_true") parser.add_argument('--runner', dest='runner', action="store_true") parser.add_argument('-r', dest='runner', action="store_true") view, args = parser.parse_known_args(sys.argv) print(args) # Check from filetype if any windows need to be open if any(arg.endswith('.psyexp') for arg in args): view.builder = True exps = [file for file in args if file.endswith('.psyexp')] if any(arg.endswith('.psyrun') for arg in args): view.runner = True runlist = [file for file in args if file.endswith('.psyrun')] # If still no window specified, use default from prefs if not any( getattr(view, key) for key in ['builder', 'coder', 'runner']): if self.prefs.app['defaultView'] in view: setattr(view, self.prefs.app['defaultView'], True) elif self.prefs.app['defaultView'] == 'all': view.builder = True view.coder = True view.runner = True # Create windows if view.runner: self.showRunner(fileList=runlist) if view.coder: self.showCoder(fileList=scripts) if view.builder: self.showBuilder(fileList=exps) # if darwin, check for inaccessible keyboard if sys.platform == 'darwin': from psychopy.hardware import keyboard if keyboard.macPrefsBad: title = _translate("Mac keyboard security") if platform.mac_ver()[0] < '10.15': settingName = 'Accessibility' setting = 'Privacy_Accessibility' else: setting = 'Privacy_ListenEvent' settingName = 'Input Monitoring' msg = _translate( "To use high-precision keyboard timing you should " "enable {} for PsychoPy in System Preferences. " "Shall we go there (and you can drag PsychoPy app into " "the box)?").format(settingName) dlg = dialogs.MessageDialog(title=title, message=msg, type='Query') resp = dlg.ShowModal() if resp == wx.ID_YES: from AppKit import NSWorkspace from Foundation import NSURL sys_pref_link = ('x-apple.systempreferences:' 'com.apple.preference.security?' '{}'.format(setting)) # create workspace object workspace = NSWorkspace.sharedWorkspace() # Open System Preference workspace.openURL_(NSURL.URLWithString_(sys_pref_link)) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None self.news = None self.tasks = None prefsConn = self.prefs.connections ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if (self.prefs.app['showStartupTips'] and not self.testMode and not blockTips): tipFile = os.path.join(self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) < v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if prefs.app['defaultView'] in [ 'all', 'builder', 'coder', 'runner' ]: self.showBuilder() else: self.showCoder() # after all windows are created (so errors flushed) create output self._appLoaded = True if self.coder: self.coder.setOutputWindow() # takes control of sys.stdout # flush any errors to the last run log file logging.flush() sys.stdout.flush() # we wanted debug mode while loading but safe to go back to info mode if not self.prefs.app['debugMode']: logging.console.setLevel(logging.INFO) # Runner captures standard streams until program closed if self.runner and not self.testMode: sys.stdout = self.runner.stdOut sys.stderr = self.runner.stdOut return True
def onInit(self, showSplash=True, testMode=False): """ :Parameters: testMode: bool If set to True then startup wizard won't appear and stdout/stderr won't be redirected to the Coder """ self.version=psychopy.__version__ self.SetAppName('PsychoPy2') #set default paths and prefs self.prefs = psychopy.prefs if self.prefs.app['debugMode']: logging.console.setLevel(logging.DEBUG) self.testMode = testMode #indicates whether we're running for testing purposes if showSplash: #show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashBitmap = wx.Image(name = splashFile).ConvertToBitmap() splash = AS.AdvancedSplash(None, bitmap=splashBitmap, timeout=3000, style=AS.AS_TIMEOUT|wx.FRAME_SHAPED, shadowcolour=wx.RED)#could use this in future for transparency splash.SetTextPosition((10,240)) splash.SetText(" Loading libraries...") else: splash=None #LONG IMPORTS - these need to be imported after splash screen starts (they're slow) #but then that they end up being local so keep track in self if splash: splash.SetText(" Loading PsychoPy2...") from psychopy import compatibility from psychopy.app import coder, builder, dialogs, wxIDs, urls #import coder and builder here but only use them later self.keys = self.prefs.keys self.prefs.pageCurrent = 0 # track last-viewed page of prefs, to return there self.IDs=wxIDs self.urls=urls.urls self.quitting=False #check compatibility with last run version (before opening windows) self.firstRun = False if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData.keys(): last=self.prefs.appData['lastVersion']='1.73.04'#must be before 1.74.00 self.firstRun = True else: last=self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: self.firstrunWizard() #setup links for URLs #on a mac, don't exit when the last frame is deleted, just show a menu if sys.platform=='darwin': self.menuFrame=MenuFrame(parent=None, app=self) #get preferred view(s) from prefs and previous view if self.prefs.app['defaultView']=='last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation (?), but doesn't: if self.prefs.app['defaultView'] in ['last', 'coder', 'builder', 'both']: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' #fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts=self.prefs.appData['coder']['prevFiles'] else: scripts=[] if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in self.prefs.appData['builder'].keys()): exps=self.prefs.appData['builder']['prevFiles'] else: exps=[] #then override the prev files by command options and passed files if len(sys.argv)>1: if sys.argv[1]==__name__: args = sys.argv[2:] # program was executed as "python.exe PsychoPyIDE.py %1' else: args = sys.argv[1:] # program was executed as "PsychoPyIDE.py %1' #choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame='builder' args = args[1:]#can remove that argument elif args[0] in ['coder','--coder', '-c']: mainFrame='coder' args = args[1:]#can remove that argument #did we get .py or .psyexp files? elif args[0][-7:]=='.psyexp': mainFrame='builder' exps=[args[0]] elif args[0][-3:]=='.py': mainFrame='coder' scripts=[args[0]] else: args=[] self.dpi = int(wx.GetDisplaySize()[0]/float(wx.GetDisplaySizeMM()[0])*25.4) if not (50<self.dpi<120): self.dpi=80#dpi was unreasonable, make one up if sys.platform=='win32': #wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT) if hasattr(self._mainFont, 'Larger'): # Font.Larger is available since wyPython version 2.9.1 # PsychoPy still supports 2.8 (see ensureMinimal above) self._mainFont = self._mainFont.Larger() self._codeFont = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FIXED_FONT) self._codeFont.SetFaceName(self.prefs.coder['codeFont']) self._codeFont.SetPointSize(self._mainFont.GetPointSize()) #unify font size #create both frame for coder/builder as necess if splash: splash.SetText(" Creating frames...") self.coder = None self.builderFrames = [] self.copiedRoutine=None self.allFrames=[]#these are ordered and the order is updated with self.onNewTopWindow if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) #send anonymous info to www.psychopy.org/usage.php #please don't disable this - it's important for PsychoPy's development self._latestAvailableVersion=None self.updater=None if self.prefs.connections['checkForUpdates'] or self.prefs.connections['allowUsageStats']: connectThread = threading.Thread(target=connections.makeConnections, args=(self,)) connectThread.start() ok, msg = compatibility.checkCompatibility(last, self.version, self.prefs, fix=True) if not ok and not self.firstRun and not self.testMode: #tell the user what has changed dlg = dialogs.MessageDialog(parent=None,message=msg,type='Info', title="Compatibility information") dlg.ShowModal() if self.prefs.app['showStartupTips'] and not self.testMode: tipIndex = self.prefs.appData['tipIndex'] tp = wx.CreateFileTipProvider(os.path.join(self.prefs.paths['resources'],"tips.txt"), tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() if self.prefs.connections['checkForUpdates']: self.Bind(wx.EVT_IDLE, self.checkUpdates) else: self.Bind(wx.EVT_IDLE, self.onIdle) return True
def onInit(self, showSplash=True, testMode=False): """ :Parameters: testMode: bool If set to True then startup wizard won't appear and stdout/stderr won't be redirected to the Coder """ self.version=psychopy.__version__ self.SetAppName('PsychoPy2') #set default paths and prefs self.prefs = psychopy.prefs if self.prefs.app['debugMode']: logging.console.setLevel(logging.DEBUG) self.testMode = testMode #indicates whether we're running for testing purposes if showSplash: #show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashBitmap = wx.Image(name = splashFile).ConvertToBitmap() splash = AS.AdvancedSplash(None, bitmap=splashBitmap, timeout=3000, style=AS.AS_TIMEOUT|wx.FRAME_SHAPED, shadowcolour=wx.RED)#could use this in future for transparency splash.SetTextPosition((10,240)) splash.SetText(" Loading libraries...") else: splash=None #LONG IMPORTS - these need to be imported after splash screen starts (they're slow) #but then that they end up being local so keep track in self if splash: splash.SetText(" Loading PsychoPy2...") from psychopy import compatibility from psychopy.app import coder, builder, dialogs, wxIDs, urls #import coder and builder here but only use them later self.keys = self.prefs.keys self.prefs.pageCurrent = 0 # track last-viewed page of prefs, to return there self.IDs=wxIDs self.urls=urls.urls self.quitting=False #check compatibility with last run version (before opening windows) self.firstRun = False if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData.keys(): last=self.prefs.appData['lastVersion']='1.73.04'#must be before 1.74.00 self.firstRun = True else: last=self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: self.firstrunWizard() #setup links for URLs #on a mac, don't exit when the last frame is deleted, just show a menu if sys.platform=='darwin': self.menuFrame=MenuFrame(parent=None, app=self) #get preferred view(s) from prefs and previous view if self.prefs.app['defaultView']=='last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation (?), but doesn't: if self.prefs.app['defaultView'] in ['last', 'coder', 'builder', 'both']: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' #fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts=self.prefs.appData['coder']['prevFiles'] else: scripts=[] if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in self.prefs.appData['builder'].keys()): exps=self.prefs.appData['builder']['prevFiles'] else: exps=[] #then override the prev files by command options and passed files if len(sys.argv)>1: if sys.argv[1]==__name__: args = sys.argv[2:] # program was executed as "python.exe PsychoPyIDE.py %1' else: args = sys.argv[1:] # program was executed as "PsychoPyIDE.py %1' #choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame='builder' args = args[1:]#can remove that argument elif args[0] in ['coder','--coder', '-c']: mainFrame='coder' args = args[1:]#can remove that argument #did we get .py or .psyexp files? elif args[0][-7:]=='.psyexp': mainFrame='builder' exps=[args[0]] elif args[0][-3:]=='.py': mainFrame='coder' scripts=[args[0]] else: args=[] self.dpi = int(wx.GetDisplaySize()[0]/float(wx.GetDisplaySizeMM()[0])*25.4) if not (50<self.dpi<120): self.dpi=80#dpi was unreasonable, make one up #create both frame for coder/builder as necess if splash: splash.SetText(" Creating frames...") self.coder = None self.builderFrames = [] self.copiedRoutine=None self.allFrames=[]#these are ordered and the order is updated with self.onNewTopWindow if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) #send anonymous info to www.psychopy.org/usage.php #please don't disable this - it's important for PsychoPy's development self._latestAvailableVersion=None self.updater=None if self.prefs.connections['checkForUpdates'] or self.prefs.connections['allowUsageStats']: connectThread = threading.Thread(target=connections.makeConnections, args=(self,)) connectThread.start() ok, msg = compatibility.checkCompatibility(last, self.version, self.prefs, fix=True) if not ok and not self.firstRun and not self.testMode: #tell the user what has changed dlg = dialogs.MessageDialog(parent=None,message=msg,type='Info', title="Compatibility information") dlg.ShowModal() if self.prefs.app['showStartupTips'] and not self.testMode: tipIndex = self.prefs.appData['tipIndex'] tp = wx.CreateFileTipProvider(os.path.join(self.prefs.paths['resources'],"tips.txt"), tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() if self.prefs.connections['checkForUpdates']: self.Bind(wx.EVT_IDLE, self.checkUpdates) else: self.Bind(wx.EVT_IDLE, self.onIdle) return True
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool """ self.SetAppName('PsychoPy3') if False: # show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashImage = wx.Image(name=splashFile) splashImage.ConvertAlphaToMask() splash = AS.AdvancedSplash( None, bitmap=splashImage.ConvertToBitmap(), timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN, ) # transparency? w, h = splashImage.GetSize() splash.SetTextPosition((int(w - 130), h - 20)) splash.SetText(_translate("Loading libraries...")) wx.Yield() else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self if splash: splash.SetText(_translate("Loading PsychoPy3...")) wx.Yield() from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: pass # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # get preferred view(s) from prefs and previous view if self.prefs.app['defaultView'] == 'last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation allowed = ['last', 'coder', 'builder', 'both'] if self.prefs.app['defaultView'] in allowed: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] # then override the prev files by command options and passed files if len(sys.argv) > 1: if sys.argv[1] == __name__: # program was executed as "python.exe psychopyApp.py %1' args = sys.argv[2:] else: # program was executed as "psychopyApp.py %1' args = sys.argv[1:] # choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame = 'builder' args = args[1:] # can remove that argument elif args[0] in ['coder', '--coder', '-c']: mainFrame = 'coder' args = args[1:] # can remove that argument # did we get .py or .psyexp files? elif args[0][-7:] == '.psyexp': mainFrame = 'builder' exps = [args[0]] elif args[0][-3:] == '.py': mainFrame = 'coder' scripts = [args[0]] else: args = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) self._codeFont.SetFaceName(self.prefs.coder['codeFont']) # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None prefsConn = self.prefs.connections if prefsConn['checkForUpdates'] or prefsConn['allowUsageStats']: connectThread = threading.Thread( target=connections.makeConnections, args=(self, )) connectThread.start() # query github in the background to populate a local cache about # what versions are available for download: from psychopy.tools import versionchooser as vc versionsThread = threading.Thread(target=vc._remoteVersions, args=(True, )) versionsThread.start() try: import imageio haveImageio = True except ImportError: haveImageio = False if haveImageio: # Use pre-installed ffmpeg if available. # Otherwise, download ffmpeg binary. try: imageio.plugins.ffmpeg.get_exe() except imageio.core.NeedDownloadError: ffmpegDownloader = threading.Thread( target=imageio.plugins.ffmpeg.download) ffmpegDownloader.start() ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if self.prefs.app['showStartupTips'] and not self.testMode: tipFile = os.path.join(self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() if self.prefs.connections['checkForUpdates']: self.Bind(wx.EVT_IDLE, self.checkUpdates) else: self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) < v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if mainFrame in ['both', 'builder']: self.showBuilder() else: self.showCoder() # after all windows are created (so errors flushed) create output self._appLoaded = True if self.coder: self.coder.setOutputWindow() # takes control of sys.stdout return True
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool """ self.SetAppName('PsychoPy3') if showSplash: #showSplash: # show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashImage = wx.Image(name=splashFile) splashImage.ConvertAlphaToMask() splash = AS.AdvancedSplash( None, bitmap=splashImage.ConvertToBitmap(), timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN, ) # transparency? w, h = splashImage.GetSize() splash.SetTextPosition((int(340), h - 30)) splash.SetText( _translate("Copyright (C) 2021 OpenScienceTools.org")) else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, runner, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: pass # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] runlist = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) # detect retina displays self.isRetina = self.dpi > 80 and wx.Platform == '__WXMAC__' if self.isRetina: fontScale = 1.2 # fonts are looking tiny on macos (only retina?) right now else: fontScale = 1 # adjust dpi to something reasonable if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up # Manage fonts if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) # rescale for tiny retina fonts if hasattr(wx.Font, "AddPrivateFont") and sys.platform != "darwin": # Load packaged fonts if possible for fontFile in (Path(__file__).parent / "Resources" / "fonts").glob("*"): if fontFile.suffix in ['.ttf', '.truetype']: wx.Font.AddPrivateFont(str(fontFile)) # Set fonts as those loaded self._codeFont = wx.Font( wx.FontInfo( self._mainFont.GetPointSize()).FaceName("JetBrains Mono")) else: # Get system defaults if can't load fonts try: self._codeFont = wx.SystemSettings.GetFont( wx.SYS_ANSI_FIXED_FONT) except wx._core.wxAssertionError: # if no SYS_ANSI_FIXED_FONT then try generic FONTFAMILY_MODERN self._codeFont = wx.Font(self._mainFont.GetPointSize(), wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) if self.isRetina: self._codeFont.SetPointSize( int(self._codeFont.GetPointSize() * fontScale)) self._mainFont.SetPointSize( int(self._mainFont.GetPointSize() * fontScale)) # that gets most of the properties of _codeFont but the FaceName # FaceName is set in the setting of the theme: self.theme = self.prefs.app['theme'] # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) # Parse incoming call parser = argparse.ArgumentParser(prog=self) parser.add_argument('--builder', dest='builder', action="store_true") parser.add_argument('-b', dest='builder', action="store_true") parser.add_argument('--coder', dest='coder', action="store_true") parser.add_argument('-c', dest='coder', action="store_true") parser.add_argument('--runner', dest='runner', action="store_true") parser.add_argument('-r', dest='runner', action="store_true") parser.add_argument('-x', dest='direct', action='store_true') view, args = parser.parse_known_args(sys.argv) # Check from filetype if any windows need to be open if any(arg.endswith('.psyexp') for arg in args): view.builder = True exps = [file for file in args if file.endswith('.psyexp')] if any(arg.endswith('.psyrun') for arg in args): view.runner = True runlist = [file for file in args if file.endswith('.psyrun')] # If still no window specified, use default from prefs if not any( getattr(view, key) for key in ['builder', 'coder', 'runner']): if self.prefs.app['defaultView'] in view: setattr(view, self.prefs.app['defaultView'], True) elif self.prefs.app['defaultView'] == 'all': view.builder = True view.coder = True view.runner = True # set the dispatcher for standard output self.stdStreamDispatcher = console.StdStreamDispatcher(self) self.stdStreamDispatcher.redirect() # Create windows if view.runner: self.showRunner(fileList=runlist) if view.coder: self.showCoder(fileList=scripts) if view.builder: self.showBuilder(fileList=exps) if view.direct: self.showRunner() for exp in [ file for file in args if file.endswith('.psyexp') or file.endswith('.py') ]: self.runner.panel.runFile(exp) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None self.news = None self.tasks = None prefsConn = self.prefs.connections ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if (self.prefs.app['showStartupTips'] and not self.testMode and not blockTips): tipFile = os.path.join(self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) < v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if prefs.app['defaultView'] in [ 'all', 'builder', 'coder', 'runner' ]: self.showBuilder() else: self.showCoder() # after all windows are created (so errors flushed) create output self._appLoaded = True if self.coder: self.coder.setOutputWindow() # takes control of sys.stdout # flush any errors to the last run log file logging.flush() sys.stdout.flush() # we wanted debug mode while loading but safe to go back to info mode if not self.prefs.app['debugMode']: logging.console.setLevel(logging.INFO) return True
def onInit(self, showSplash=True, testMode=False): """ :Parameters: testMode: bool If set to True then startup wizard won't appear and stdout/stderr won't be redirected to the Coder """ self.version = psychopy.__version__ self.SetAppName("PsychoPy2") # set default paths and prefs self.prefs = psychopy.prefs if self.prefs.app["debugMode"]: logging.console.setLevel(logging.DEBUG) self.testMode = testMode # indicates whether we're running for testing purposes if showSplash: # show splash screen splashFile = os.path.join(self.prefs.paths["resources"], "psychopySplash.png") splashBitmap = wx.Image(name=splashFile).ConvertToBitmap() splash = AS.AdvancedSplash( None, bitmap=splashBitmap, timeout=3000, style=AS.AS_TIMEOUT | wx.FRAME_SHAPED, shadowcolour=wx.RED ) # could use this in future for transparency splash.SetTextPosition((10, 240)) splash.SetText(" Loading libraries..." + uidRootFlag) else: splash = None # LONG IMPORTS - these need to be imported after splash screen starts (they're slow) # but then that they end up being local so keep track in self if splash: splash.SetText(" Loading PsychoPy2..." + uidRootFlag) from psychopy import compatibility from psychopy.app import ( coder, builder, dialogs, wxIDs, urls, ) # import coder and builder here but only use them later self.keys = self.prefs.keys self.prefs.pageCurrent = 0 # track last-viewed page of prefs, to return there self.IDs = wxIDs self.urls = urls.urls self.quitting = False # check compatibility with last run version (before opening windows) self.firstRun = False if "--firstrun" in sys.argv: del sys.argv[sys.argv.index("--firstrun")] self.firstRun = True if "lastVersion" not in self.prefs.appData.keys(): last = self.prefs.appData["lastVersion"] = "1.73.04" # must be before 1.74.00 self.firstRun = True else: last = self.prefs.appData["lastVersion"] if self.firstRun and not self.testMode: self.firstrunWizard() # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show a menu if sys.platform == "darwin": self.menuFrame = MenuFrame(parent=None, app=self) # get preferred view(s) from prefs and previous view if self.prefs.app["defaultView"] == "last": mainFrame = self.prefs.appData["lastFrame"] else: # configobjValidate should take care of this situation (?), but doesn't: if self.prefs.app["defaultView"] in ["last", "coder", "builder", "both"]: mainFrame = self.prefs.app["defaultView"] else: self.prefs.app["defaultView"] = "both" mainFrame = "both" # fetch prev files if that's the preference if self.prefs.coder["reloadPrevFiles"]: scripts = self.prefs.appData["coder"]["prevFiles"] else: scripts = [] if self.prefs.builder["reloadPrevExp"] and ("prevFiles" in self.prefs.appData["builder"].keys()): exps = self.prefs.appData["builder"]["prevFiles"] else: exps = [] # then override the prev files by command options and passed files if len(sys.argv) > 1: if sys.argv[1] == __name__: args = sys.argv[2:] # program was excecuted as "python.exe PsychoPyIDE.py %1' else: args = sys.argv[1:] # program was excecuted as "PsychoPyIDE.py %1' # choose which frame to start with if args[0] in ["builder", "--builder", "-b"]: mainFrame = "builder" args = args[1:] # can remove that argument elif args[0] in ["coder", "--coder", "-c"]: mainFrame = "coder" args = args[1:] # can remove that argument # did we get .py or .psyexp files? elif args[0][-7:] == ".psyexp": mainFrame = "builder" exps = [args[0]] elif args[0][-3:] == ".py": mainFrame = "coder" scripts = [args[0]] else: args = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up # create both frame for coder/builder as necess if splash: splash.SetText(" Creating frames..." + uidRootFlag) self.coder = None self.builderFrames = [] self.copiedRoutine = None self.allFrames = [] # these are ordered and the order is updated with self.onNewTopWindow if mainFrame in ["both", "coder"]: self.showCoder(fileList=scripts) if mainFrame in ["both", "builder"]: self.showBuilder(fileList=exps) # send anonymous info to www.psychopy.org/usage.php # please don't disable this - it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None if self.prefs.connections["checkForUpdates"] or self.prefs.connections["allowUsageStats"]: connectThread = threading.Thread(target=connections.makeConnections, args=(self,)) connectThread.start() ok, msg = compatibility.checkCompatibility(last, self.version, self.prefs, fix=True) if not ok and not self.firstRun and not self.testMode: # tell the user what has changed dlg = dialogs.MessageDialog(parent=None, message=msg, type="Info", title="Compatibility information") dlg.ShowModal() if self.prefs.app["showStartupTips"] and not self.testMode: tipIndex = self.prefs.appData["tipIndex"] tp = wx.CreateFileTipProvider(os.path.join(self.prefs.paths["resources"], "tips.txt"), tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData["tipIndex"] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app["showStartupTips"] = showTip self.prefs.saveUserPrefs() if self.prefs.connections["checkForUpdates"]: self.Bind(wx.EVT_IDLE, self.checkUpdates) else: self.Bind(wx.EVT_IDLE, self.onIdle) return True
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool If set to True then startup wizard won't appear and stdout/stderr won't be redirected to the Coder """ self.SetAppName('PsychoPy2') if showSplash: # show splash screen splashFile = os.path.join( self.prefs.paths['resources'], 'psychopySplash.png') splashBitmap = wx.Image(name=splashFile).ConvertToBitmap() splash = AS.AdvancedSplash(None, bitmap=splashBitmap, timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN, shadowcolour=wx.RED) # transparency? splash.SetTextPosition((10, 240)) splash.SetText(_translate(" Loading libraries...")) else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self if splash: splash.SetText(_translate(" Loading PsychoPy2...")) from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: self.firstrunWizard() # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # get preferred view(s) from prefs and previous view if self.prefs.app['defaultView'] == 'last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation allowed = ['last', 'coder', 'builder', 'both'] if self.prefs.app['defaultView'] in allowed: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] # then override the prev files by command options and passed files if len(sys.argv) > 1: if sys.argv[1] == __name__: # program was executed as "python.exe psychopyApp.py %1' args = sys.argv[2:] else: # program was executed as "psychopyApp.py %1' args = sys.argv[1:] # choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame = 'builder' args = args[1:] # can remove that argument elif args[0] in ['coder', '--coder', '-c']: mainFrame = 'coder' args = args[1:] # can remove that argument # did we get .py or .psyexp files? elif args[0][-7:] == '.psyexp': mainFrame = 'builder' exps = [args[0]] elif args[0][-3:] == '.py': mainFrame = 'coder' scripts = [args[0]] else: args = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) self._codeFont.SetFaceName(self.prefs.coder['codeFont']) # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None prefsConn = self.prefs.connections if prefsConn['checkForUpdates'] or prefsConn['allowUsageStats']: connectThread = threading.Thread( target=connections.makeConnections, args=(self,)) connectThread.start() # query github in the background to populate a local cache about # what versions are available for download: from psychopy.tools import versionchooser as vc versionsThread = threading.Thread(target=vc._remoteVersions, args=(True,)) versionsThread.start() try: import imageio haveImageio = True except ImportError: haveImageio = False if haveImageio: # Use pre-installed ffmpeg if available. # Otherwise, download ffmpeg binary. try: imageio.plugins.ffmpeg.get_exe() except imageio.core.NeedDownloadError: ffmpegDownloader = threading.Thread(target=imageio.plugins.ffmpeg.download) ffmpegDownloader.start() ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if self.prefs.app['showStartupTips'] and not self.testMode: tipFile = os.path.join( self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() if self.prefs.connections['checkForUpdates']: self.Bind(wx.EVT_IDLE, self.checkUpdates) else: self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) <v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if mainFrame in ['both', 'builder']: self.showBuilder() else: self.showCoder() return True
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool """ self.SetAppName('PsychoPy3') if False: # show splash screen splashFile = os.path.join( self.prefs.paths['resources'], 'psychopySplash.png') splashImage = wx.Image(name=splashFile) splashImage.ConvertAlphaToMask() splash = AS.AdvancedSplash(None, bitmap=splashImage.ConvertToBitmap(), timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN, ) # transparency? w, h = splashImage.GetSize() splash.SetTextPosition((int(w-130), h-20)) splash.SetText(_translate("Loading libraries...")) wx.Yield() else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self if splash: splash.SetText(_translate("Loading PsychoPy3...")) wx.Yield() from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: pass # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # get preferred view(s) from prefs and previous view if self.prefs.app['defaultView'] == 'last': mainFrame = self.prefs.appData['lastFrame'] else: # configobjValidate should take care of this situation allowed = ['last', 'coder', 'builder', 'both'] if self.prefs.app['defaultView'] in allowed: mainFrame = self.prefs.app['defaultView'] else: self.prefs.app['defaultView'] = 'both' mainFrame = 'both' # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] # then override the prev files by command options and passed files if len(sys.argv) > 1: if sys.argv[1] == __name__: # program was executed as "python.exe psychopyApp.py %1' args = sys.argv[2:] else: # program was executed as "psychopyApp.py %1' args = sys.argv[1:] # choose which frame to start with if args[0] in ['builder', '--builder', '-b']: mainFrame = 'builder' args = args[1:] # can remove that argument elif args[0] in ['coder', '--coder', '-c']: mainFrame = 'coder' args = args[1:] # can remove that argument # did we get .py or .psyexp files? elif args[0][-7:] == '.psyexp': mainFrame = 'builder' exps = [args[0]] elif args[0][-3:] == '.py': mainFrame = 'coder' scripts = [args[0]] else: args = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) try: self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) except wx._core.wxAssertionError: # if no SYS_ANSI_FIXED_FONT then try generic FONTFAMILY_MODERN self._codeFont = wx.Font(self._mainFont.GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self._codeFont.SetFaceName(self.prefs.coder['codeFont']) # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) if mainFrame in ['both', 'coder']: self.showCoder(fileList=scripts) if mainFrame in ['both', 'builder']: self.showBuilder(fileList=exps) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None self.news = None self.tasks = None prefsConn = self.prefs.connections ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if (self.prefs.app['showStartupTips'] and not self.testMode and not blockTips): tipFile = os.path.join( self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) <v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if mainFrame in ['both', 'builder']: self.showBuilder() else: self.showCoder() # after all windows are created (so errors flushed) create output self._appLoaded = True if self.coder: self.coder.setOutputWindow() # takes control of sys.stdout return True
def onInit(self, showSplash=True, testMode=False): """This is launched immediately *after* the app initialises with wx :Parameters: testMode: bool """ self.SetAppName('PsychoPy3') # Single instance check is done here prior to loading any GUI stuff. # This permits one instance of PsychoPy from running at any time. # Clicking on files will open them in the extant instance rather than # loading up a new one. # # Inter-process messaging is done via a memory-mapped file created by # the first instance. Successive instances will write their args to # this file and promptly close. The main instance will read this file # periodically for data and open and file names stored to this buffer. # # This uses similar logic to this example: # https://github.com/wxWidgets/wxPython-Classic/blob/master/wx/lib/pydocview.py # Create the memory-mapped file if not present, this is handled # differently between Windows and UNIX-likes. if wx.Platform == '__WXMSW__': tfile = tempfile.TemporaryFile(prefix="ag", suffix="tmp") fno = tfile.fileno() self._sharedMemory = mmap.mmap(fno, self.mmap_sz, "shared_memory") else: tfile = open( os.path.join( tempfile.gettempdir(), tempfile.gettempprefix() + self.GetAppName() + '-' + wx.GetUserId() + "AGSharedMemory"), 'w+b') # insert markers into the buffer tfile.write(b"*") tfile.seek(self.mmap_sz) tfile.write(b" ") tfile.flush() fno = tfile.fileno() self._sharedMemory = mmap.mmap(fno, self.mmap_sz) # use wx to determine if another instance is running self._singleInstanceChecker = wx.SingleInstanceChecker( self.GetAppName() + '-' + wx.GetUserId(), tempfile.gettempdir()) # If another instance is running, message our args to it by writing the # path the the buffer. if self._singleInstanceChecker.IsAnotherRunning(): # Message the extant running instance the arguments we want to # process. args = sys.argv[1:] # if there are no args, tell the user another instance is running if not args: errMsg = "Another instance of PsychoPy is already running." errDlg = wx.MessageDialog(None, errMsg, caption="PsychoPy Error", style=wx.OK | wx.ICON_ERROR, pos=wx.DefaultPosition) errDlg.ShowModal() errDlg.Destroy() self.quit(None) # serialize the data data = pickle.dumps(args) # Keep alive until the buffer is free for writing, this allows # multiple files to be opened in succession. Times out after 5 # seconds. attempts = 0 while attempts < 5: # try to write to the buffer self._sharedMemory.seek(0) marker = self._sharedMemory.read(1) if marker == b'\0' or marker == b'*': self._sharedMemory.seek(0) self._sharedMemory.write(b'-') self._sharedMemory.write(data) self._sharedMemory.seek(0) self._sharedMemory.write(b'+') self._sharedMemory.flush() break else: # wait a bit for the buffer to become free time.sleep(1) attempts += 1 else: if not self.testMode: # error that we could not access the memory-mapped file errMsg = \ "Cannot communicate with running PsychoPy instance!" errDlg = wx.MessageDialog(None, errMsg, caption="PsychoPy Error", style=wx.OK | wx.ICON_ERROR, pos=wx.DefaultPosition) errDlg.ShowModal() errDlg.Destroy() # since were not the main instance, exit ... self.quit(None) # ---- if showSplash: # show splash screen splashFile = os.path.join(self.prefs.paths['resources'], 'psychopySplash.png') splashImage = wx.Image(name=splashFile) splashImage.ConvertAlphaToMask() splash = AS.AdvancedSplash(None, bitmap=splashImage.ConvertToBitmap(), timeout=3000, agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN) w, h = splashImage.GetSize() splash.SetTextPosition((340, h - 30)) splash.SetText( _translate("Copyright (C) 2022 OpenScienceTools.org")) else: splash = None # SLOW IMPORTS - these need to be imported after splash screen starts # but then that they end up being local so keep track in self from psychopy.compatibility import checkCompatibility # import coder and builder here but only use them later from psychopy.app import coder, builder, runner, dialogs if '--firstrun' in sys.argv: del sys.argv[sys.argv.index('--firstrun')] self.firstRun = True if 'lastVersion' not in self.prefs.appData: # must be before 1.74.00 last = self.prefs.appData['lastVersion'] = '1.73.04' self.firstRun = True else: last = self.prefs.appData['lastVersion'] if self.firstRun and not self.testMode: pass # setup links for URLs # on a mac, don't exit when the last frame is deleted, just show menu if sys.platform == 'darwin': self.menuFrame = MenuFrame(parent=None, app=self) # fetch prev files if that's the preference if self.prefs.coder['reloadPrevFiles']: scripts = self.prefs.appData['coder']['prevFiles'] else: scripts = [] appKeys = list(self.prefs.appData['builder'].keys()) if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys): exps = self.prefs.appData['builder']['prevFiles'] else: exps = [] runlist = [] self.dpi = int(wx.GetDisplaySize()[0] / float(wx.GetDisplaySizeMM()[0]) * 25.4) # detect retina displays self.isRetina = self.dpi > 80 and wx.Platform == '__WXMAC__' if self.isRetina: fontScale = 1.2 # fonts are looking tiny on macos (only retina?) right now # mark icons as being retina icons.retStr = "@2x" else: fontScale = 1 # adjust dpi to something reasonable if not (50 < self.dpi < 120): self.dpi = 80 # dpi was unreasonable, make one up # Manage fonts if sys.platform == 'win32': # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32 self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) else: self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT) # rescale for tiny retina fonts if hasattr(wx.Font, "AddPrivateFont") and sys.platform != "darwin": # Load packaged fonts if possible for fontFile in (Path(__file__).parent / "Resources" / "fonts").glob("*"): if fontFile.suffix in ['.ttf', '.truetype']: wx.Font.AddPrivateFont(str(fontFile)) # Set fonts as those loaded self._codeFont = wx.Font( wx.FontInfo( self._mainFont.GetPointSize()).FaceName("JetBrains Mono")) else: # Get system defaults if can't load fonts try: self._codeFont = wx.SystemSettings.GetFont( wx.SYS_ANSI_FIXED_FONT) except wx._core.wxAssertionError: # if no SYS_ANSI_FIXED_FONT then try generic FONTFAMILY_MODERN self._codeFont = wx.Font(self._mainFont.GetPointSize(), wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) if self.isRetina: self._codeFont.SetPointSize( int(self._codeFont.GetPointSize() * fontScale)) self._mainFont.SetPointSize( int(self._mainFont.GetPointSize() * fontScale)) # that gets most of the properties of _codeFont but the FaceName # FaceName is set in the setting of the theme: self.theme = prefs.app['theme'] # removed Aug 2017: on newer versions of wx (at least on mac) # this looks too big # if hasattr(self._mainFont, 'Larger'): # # Font.Larger is available since wyPython version 2.9.1 # # PsychoPy still supports 2.8 (see ensureMinimal above) # self._mainFont = self._mainFont.Larger() # self._codeFont.SetPointSize( # self._mainFont.GetPointSize()) # unify font size # create both frame for coder/builder as necess if splash: splash.SetText(_translate(" Creating frames...")) # Parse incoming call parser = argparse.ArgumentParser(prog=self) parser.add_argument('--builder', dest='builder', action="store_true") parser.add_argument('-b', dest='builder', action="store_true") parser.add_argument('--coder', dest='coder', action="store_true") parser.add_argument('-c', dest='coder', action="store_true") parser.add_argument('--runner', dest='runner', action="store_true") parser.add_argument('-r', dest='runner', action="store_true") parser.add_argument('-x', dest='direct', action='store_true') view, args = parser.parse_known_args(sys.argv) # Check from filetype if any windows need to be open if any(arg.endswith('.psyexp') for arg in args): view.builder = True exps = [file for file in args if file.endswith('.psyexp')] if any(arg.endswith('.psyrun') for arg in args): view.runner = True runlist = [file for file in args if file.endswith('.psyrun')] # If still no window specified, use default from prefs if not any( getattr(view, key) for key in ['builder', 'coder', 'runner']): if self.prefs.app['defaultView'] in view: setattr(view, self.prefs.app['defaultView'], True) elif self.prefs.app['defaultView'] == 'all': view.builder = True view.coder = True view.runner = True # set the dispatcher for standard output # self.stdStreamDispatcher = console.StdStreamDispatcher(self) # self.stdStreamDispatcher.redirect() # Create windows if view.runner: self.showRunner(fileList=runlist) if view.coder: self.showCoder(fileList=scripts) if view.builder: self.showBuilder(fileList=exps) if view.direct: self.showRunner() for exp in [ file for file in args if file.endswith('.psyexp') or file.endswith('.py') ]: self.runner.panel.runFile(exp) # send anonymous info to www.psychopy.org/usage.php # please don't disable this, it's important for PsychoPy's development self._latestAvailableVersion = None self.updater = None self.news = None self.tasks = None prefsConn = self.prefs.connections ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True) # tell the user what has changed if not ok and not self.firstRun and not self.testMode: title = _translate("Compatibility information") dlg = dialogs.MessageDialog(parent=None, message=msg, type='Info', title=title) dlg.ShowModal() if self.prefs.app['showStartupTips'] and not self.testMode: tipFile = os.path.join(self.prefs.paths['resources'], _translate("tips.txt")) tipIndex = self.prefs.appData['tipIndex'] if parse_version(wx.__version__) >= parse_version('4.0.0a1'): tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.adv.ShowTip(None, tp) else: tp = wx.CreateFileTipProvider(tipFile, tipIndex) showTip = wx.ShowTip(None, tp) self.prefs.appData['tipIndex'] = tp.GetCurrentTip() self.prefs.saveAppData() self.prefs.app['showStartupTips'] = showTip self.prefs.saveUserPrefs() self.Bind(wx.EVT_IDLE, self.onIdle) # doing this once subsequently enables the app to open & switch among # wx-windows on some platforms (Mac 10.9.4) with wx-3.0: v = parse_version if sys.platform == 'darwin': if v('3.0') <= v(wx.version()) < v('4.0'): _Showgui_Hack() # returns ~immediately, no display # focus stays in never-land, so bring back to the app: if prefs.app['defaultView'] in [ 'all', 'builder', 'coder', 'runner' ]: self.showBuilder() else: self.showCoder() # after all windows are created (so errors flushed) create output self._appLoaded = True if self.coder: self.coder.setOutputWindow() # takes control of sys.stdout # flush any errors to the last run log file logging.flush() sys.stdout.flush() # we wanted debug mode while loading but safe to go back to info mode if not self.prefs.app['debugMode']: logging.console.setLevel(logging.INFO) # if the program gets here, there are no other instances running self._timer = wx.PyTimer(self._bgCheckAndLoad) self._timer.Start(250) return True