def saveTask(self, promptSaveLocation): printf("GUI| Saving project") # If there is no filename, ask for one if promptSaveLocation or self.fileName is None: Global.ensurePathExists(Paths.saves_dir) filename, _ = QtWidgets.QFileDialog.getSaveFileName(parent=self, caption="Save Task", filter="Task (*.task)", directory=Paths.saves_dir) if filename == "": return False #If user hit cancel self.fileName = filename self.env.updateSettings("lastOpenedFile", self.fileName) # Update the save file saveData = self.controlPanel.getSaveData() json.dump(saveData, open(self.fileName, 'w'), sort_keys=False, indent=3, separators=(',', ': ')) self.loadData = deepcopy(saveData) #Update what the latest saved changes are self.setWindowTitle(self.programTitle + ' ' + self.fileName) printf("GUI| Project Saved Successfully") return True
def __init__(self, settingsPath, objectsPath, cascadePath): """ :param settingsPath: The full path to Settings.txt :param objectsPath: The path to directory that holds Objects, for ObjectManager :param cascadePath: The path to the directory that holds the eye_cascade.xml, face_cascade.xml, and smile_cascade.xml """ # Initialize Global Variables Global.init() # Load settings before any objects are created self.__settingsPath = settingsPath self.__settings = self.__loadSettings() # Set up environment objects self.__vStream = Video.VideoStream() # Gets frames constantly self.__robot = Robot.Robot() self.__vision = Vision( self.__vStream, cascadePath ) # Performs computer vision tasks, using images from vStream self.__objectMngr = ObjectManager.ObjectManager(objectsPath) self.__transform = None # If the settings have any information, try to instantiate objects. Otherwise, GUI will do this as user requests cameraID = self.__settings['cameraID'] if cameraID is not None: self.__vStream.setNewCamera(cameraID) robotID = self.__settings['robotID'] if robotID is not None: self.__robot.setUArm(robotID) ptPairs = self.__settings["coordCalibrations"]["ptPairs"] if ptPairs is not None: self.__transform = Transform(ptPairs)
def bugReport(self): # Open the bug report link & zip the log files prompt the log.zip folder webbrowser.open_new(Paths.bugreport_link) with ZipFile(Paths.bugreport_zipfile, 'w') as logzip: logzip.write(Paths.ucs_log) logzip.write(Paths.error_log) Global.openFile(Paths.bugreport_dir)
def __init__(self, settingsPath, objectsPath, cascadePath): """ :param settingsPath: The full path to Settings.txt :param objectsPath: The path to directory that holds Objects, for ObjectManager :param cascadePath: The path to the directory that holds the eye_cascade.xml, face_cascade.xml, and smile_cascade.xml """ # Initialize Global Variables Global.init() # Load settings before any objects are created self.__settingsPath = settingsPath self.__settings = self.__loadSettings() # Set up environment objects self.__vStream = Video.VideoStream() # Gets frames constantly self.__robot = Robot.Robot() self.__vision = Vision(self.__vStream, cascadePath) # Performs computer vision tasks, using images from vStream self.__objectMngr = ObjectManager.ObjectManager(objectsPath) self.__transform = None # If the settings have any information, try to instantiate objects. Otherwise, GUI will do this as user requests cameraID = self.__settings['cameraID'] if cameraID is not None: self.__vStream.setNewCamera(cameraID) robotID = self.__settings['robotID'] if robotID is not None: self.__robot.setUArm(robotID) ptPairs = self.__settings["coordCalibrations"]["ptPairs"] if ptPairs is not None: self.__transform = Transform(ptPairs)
def __init__(self, settingsPath=Paths.settings_txt, resourcePath=Paths.resourcesLoc): # Initialize Global Variables Global.init() # Load settings before any objects are created self.__settingsPath = settingsPath self.__settings = self.__loadSettings() # Set up environment objects self.__vStream = Video.VideoStream() # Gets frames constantly self.__robot = Robot.Robot() self.__vision = Vision(self.__vStream) # Performs computer vision tasks, using images from vStream self.__objectMngr = ObjectManager.ObjectManager() # If the settings have any information, try to instantiate objects. Otherwise, GUI will do this as user requests cameraID = self.__settings['cameraID'] if cameraID is not None: self.__vStream.setNewCamera(cameraID) robotID = self.__settings['robotID'] if robotID is not None: self.__robot.setUArm(robotID) self.__objectMngr.loadAllObjects()
return super(Application, self).notify(receiver, event) if __name__ == '__main__': # Install a global exception hook to catch pyQt errors that fall through (helps with debugging a ton) #TODO: Remove for builds sys.__excepthook = sys.excepthook sys._excepthook = sys.excepthook def exception_hook(exctype, value, traceback): sys._excepthook(exctype, value, traceback) sys.exit(1) sys.excepthook = exception_hook # Initialize global variables Global.init() # Create the Application base global app,trans app = Application(sys.argv) trans = QtCore.QTranslator(app) # app = QtGui.QApplication(sys.argv) # Apply a stylesheet (theme) of choice here # app.setStyleSheet(fancyqt.firefox.style) # Set Application Font font = QtGui.QFont() font.setFamily("Verdana")
if __name__ == '__main__': '''Install a global exception hook to catch pyQt errors that fall through (helps with debugging a ton) sys.__excepthook = sys.excepthook sys._excepthook = sys.excepthook def exception_hook(exctype, value, traceback): sys._excepthook(exctype, value, traceback) sys.exit(1) sys.excepthook = exception_hook ''' # Initialize global variables Global.init() # Create the Application base app = Application(sys.argv) # Apply a theme of choice here # app.setStyleSheet(fancyqt.firefox.style) # Set Application Font font = QtGui.QFont() font.setFamily("Verdana") font.setPixelSize(12)
""" This is a global call for only the interpreter to pay attention to, and when it is True, the Interpreter and any command inside of it will try to exit as quickly as possible. This global is so that recursively running Interpreters can exit quickly, and there's passing around of an exit variable all the time. """ global exitingFlag exitingFlag = False """ This variable is so that if the Interpreter needs to end abruptly, it'll write down the erros, and the GUI will later display them to the user in a message. This variable can be retrieved using Interpreter.getExitErrors() """ global exitErrors exitErrors = None """ This is a dictionary of each command Type in Commands.py, and each event Type in Events.py This is used so that loading scripts will be faster in Interpreter.initializeScript Furthermore, its safer than using getattr("Commands", thecommand) since it doesn't pull any other modules that are imported in Commands. This way people can't have save files that run arbitrary code. They can only access types that are classes in Commands.py and Events.py """ commandClasses = Global.getModuleClasses(Commands) eventClasses = Global.getModuleClasses(Events) """ This function will print the latest stacktrace error in a format that is friendly to the Console widget """ printTraceback = lambda: printf( "Interpreter| \n" + "-" * 35 + "ERROR" + "-" * 35 + "\n", traceback.format_exc(), "-" * 75 + "\n")
def initUI(self): # Create "File" Menu menuBar = self.menuBar() menuBar.setNativeMenuBar(False) # Connect any slots that need connecting self.consoleWidget.settingsChanged.connect(lambda: self.env.updateSettings("consoleSettings", self.consoleWidget.settings)) # Create File Menu and actions fileMenu = menuBar.addMenu(self.tr('File')) newAction = QtWidgets.QAction( QtGui.QIcon(Paths.file_new), self.tr('New Task'), self) saveAction = QtWidgets.QAction(QtGui.QIcon(Paths.file_save), self.tr('Save Task'), self) saveAsAction = QtWidgets.QAction(QtGui.QIcon(Paths.file_save), self.tr('Save Task As'), self) loadAction = QtWidgets.QAction(QtGui.QIcon(Paths.file_load), self.tr('Load Task'), self) homeDirAction = QtWidgets.QAction(QtGui.QIcon(Paths.file_homedir), self.tr('Open Home Folder'), self) aboutMessage = lambda: QtWidgets.QMessageBox.information(self, self.tr("About"), self.tr("Version: ") + version + "\n\n" + self.tr("Protocol Version: ") + PROTOCOL_VERSION) saveAction.setShortcut("Ctrl+S") newAction.triggered.connect( lambda: self.newTask(promptSave=True)) saveAction.triggered.connect( self.saveTask) saveAsAction.triggered.connect( lambda: self.saveTask(True)) homeDirAction.triggered.connect(lambda: Global.openFile(Paths.ucs_home_dir)) fileMenu.addAction(newAction) fileMenu.addAction(saveAction) fileMenu.addAction(saveAsAction) fileMenu.addAction(loadAction) fileMenu.addAction(homeDirAction) # Create Community Menu communityMenu = menuBar.addMenu(self.tr('Community')) forumAction = QtWidgets.QAction( QtGui.QIcon(Paths.taskbar), self.tr('Visit the forum!'), self) redditAction = QtWidgets.QAction(QtGui.QIcon(Paths.reddit_link), self.tr('Visit our subreddit!'), self) forumAction.triggered.connect( lambda: webbrowser.open("https://forum.ufactory.cc/", new=0, autoraise=True)) redditAction.triggered.connect(lambda: webbrowser.open("https://www.reddit.com/r/uArm/", new=0, autoraise=True)) communityMenu.addAction(forumAction) communityMenu.addAction(redditAction) # Create Resources Menu resourceMenu = menuBar.addMenu(self.tr('New Resource')) visAction = QtWidgets.QAction( QtGui.QIcon(Paths.event_recognize), self.tr('Vision Object'), self) grpAction = QtWidgets.QAction( QtGui.QIcon(Paths.event_recognize), self.tr('Vision Group'), self) recAction = QtWidgets.QAction( QtGui.QIcon(Paths.record_start), self.tr('Movement Recording'), self) fncAction = QtWidgets.QAction(QtGui.QIcon(Paths.command_run_func), self.tr('Function'), self) visAction.triggered.connect(lambda: MakeObjectWindow( None, self.env, parent=self)) grpAction.triggered.connect(lambda: MakeGroupWindow( None, self.env, parent=self)) recAction.triggered.connect(lambda: MakeRecordingWindow(None, self.env, parent=self)) fncAction.triggered.connect(lambda: MakeFunctionWindow( None, self.env, parent=self)) resourceMenu.addAction(visAction) resourceMenu.addAction(grpAction) resourceMenu.addAction(recAction) resourceMenu.addAction(fncAction) # Settings Menug settingsMenu = menuBar.addMenu(self.tr('Settings')) resetLayoutAction = QtWidgets.QAction(QtGui.QIcon(Paths.file_layout), self.tr('Reset Layout'), self) resetLayoutAction.triggered.connect(self.resetLayoutState) settingsMenu.addAction(resetLayoutAction) # Create Languages Menu languageMenu = settingsMenu.addMenu(self.tr('Languages')) enLanAction = QtWidgets.QAction(QtGui.QIcon(Paths.languages_english), self.tr('English'), self) cnLanAction = QtWidgets.QAction(QtGui.QIcon(Paths.languages_chinese), self.tr('Chinese'), self) cnLanAction.triggered.connect(lambda: self.updateLanguageSetting(Global.ZH_CN)) enLanAction.triggered.connect(lambda: self.updateLanguageSetting(Global.EN_US)) languageMenu.addAction(enLanAction) languageMenu.addAction(cnLanAction) # Create survey Action surveyMenu = menuBar.addMenu(self.tr('Win A Gift!')) surveyMenu.setObjectName('surveyMenu') # surveyMenu.setStyleSheet('QMenu::item {color: Red; }') surveyLinkAction = QtWidgets.QAction(self.tr('Win A Gift!'), self) surveyLinkAction.triggered.connect(lambda: webbrowser.open_new(Paths.survey_link)) surveyMenu.addAction(surveyLinkAction) # Create Help Menu helpMenu = menuBar.addMenu(self.tr('Help')) bugReportAction = QtWidgets.QAction(QtGui.QIcon(Paths.help_bugreport), self.tr('Bug Report'), self) aboutAction = QtWidgets.QAction( QtGui.QIcon(Paths.file_about), self.tr('About'), self) helpAction = QtWidgets.QAction( QtGui.QIcon(Paths.file_help), self.tr('User Manual'), self) loadAction.triggered.connect( self.loadTask) aboutAction.triggered.connect( aboutMessage) helpAction.triggered.connect( lambda: Global.openFile(Paths.user_manual)) bugReportAction.triggered.connect(self.bugReport) helpMenu.addAction(bugReportAction) helpMenu.addAction(aboutAction) helpMenu.addAction(helpAction) # Add menus to menuBar menuBar.addMenu(fileMenu) menuBar.addMenu(communityMenu) menuBar.addMenu(resourceMenu) menuBar.addMenu(settingsMenu) menuBar.addMenu(helpMenu) menuBar.addMenu(surveyMenu) # Create Toolbar toolbar = self.addToolBar(self.tr("MainToolbar")) toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) calibrateBtn = QtWidgets.QAction(QtGui.QIcon(Paths.calibrate), self.tr('Calibrate'), self) objMngrBtn = QtWidgets.QAction(QtGui.QIcon(Paths.objectManager), self.tr('Resources'), self) self.scriptToggleBtn.setToolTip(self.tr('Run/Pause the command script (Ctrl+R)')) self.devicesBtn.setToolTip( self.tr('Open Camera and Robot settings')) calibrateBtn.setToolTip( self.tr('Open Robot and Camera Calibration Center')) objMngrBtn.setToolTip( self.tr('Open Resource Manager')) self.scriptToggleBtn.setShortcut(self.tr('Ctrl+R')) self.scriptToggleBtn.triggered.connect(self.toggleScript) self.devicesBtn.triggered.connect(self.openDevices) calibrateBtn.triggered.connect(self.openCalibrations) objMngrBtn.triggered.connect(self.openObjectManager) toolbar.addAction(self.scriptToggleBtn) toolbar.addAction(self.devicesBtn) toolbar.addAction(calibrateBtn) toolbar.addAction(objMngrBtn) # Add Camera Widget, as a QDockWidget def createDockWidget(widget, name): dockWidget = QtWidgets.QDockWidget() dockWidget.setObjectName(name) # Without this, self.restoreState() won't work dockWidget.setWindowTitle(name) dockWidget.setWidget(widget) dockWidget.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable | QtWidgets.QDockWidget.DockWidgetMovable) # titleBarWidget = QtWidgets.QWidget() # iconLbl = QtWidgets.QLabel() # iconLbl.setPixmap(QtGui.QPixmap(icon)) # titleLbl = QtWidgets.QLabel(name) # mainHLayout = QtWidgets.QHBoxLayout() # mainHLayout.addWidget(iconLbl) # mainHLayout.addWidget(titleLbl) # titleBarWidget.setLayout(mainHLayout) # dockWidget.setTitleBarWidget(titleBarWidget) return dockWidget cameraDock = createDockWidget( self.cameraWidget, self.tr('Camera')) consoleDock = createDockWidget(self.consoleWidget, self.tr('Console')) # Add the consoleWidgets to the window, and tabify them self.addDockWidget(QtCore.Qt.RightDockWidgetArea, cameraDock) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, consoleDock) self.tabifyDockWidget(consoleDock, cameraDock) # Create the main layout self.setCentralWidget(self.controlPanel) # Final touches self.setWindowTitle(self.programTitle) self.setWindowIcon(QtGui.QIcon(Paths.taskbar)) self.show()
exit quickly, and there's passing around of an exit variable all the time. """ global exitingFlag exitingFlag = False """ This variable is so that if the Interpreter needs to end abruptly, it'll write down the erros, and the GUI will later display them to the user in a message. This variable can be retrieved using Interpreter.getExitErrors() """ global exitErrors exitErrors = None """ This is a dictionary of each command Type in Commands.py, and each event Type in Events.py This is used so that loading scripts will be faster in Interpreter.initializeScript Furthermore, its safer than using getattr("Commands", thecommand) since it doesn't pull any other modules that are imported in Commands. This way people can't have save files that run arbitrary code. They can only access types that are classes in Commands.py and Events.py """ commandClasses = Global.getModuleClasses(Commands) eventClasses = Global.getModuleClasses(Events) """ This function will print the latest stacktrace error in a format that is friendly to the Console widget """ printTraceback = lambda: printf("Interpreter| \n" + "-" * 35 + "ERROR" + "-" * 35 + "\n", traceback.format_exc(), "-" * 75 + "\n")
from os.path import expanduser from Logic import Global import logging from __init__ import version if getattr(sys, 'frozen', False): APPLICATION_PATH = os.path.dirname(sys.executable) elif __file__: APPLICATION_PATH = os.path.dirname(__file__) #TODO: Make it possible to check if this is being run from within a package manager, and load icons from a diff dir. ################ PROGRAM RESOUCES ################ ## Check OS type if Global.getOSType() == Global.MACOSX and getattr( sys, 'frozen', False): # Mac os x frozen app resourcesLoc = os.path.join(APPLICATION_PATH, "..", "Resources") elif Global.getOSType( ) == Global.MACOSX and __file__: # Mac os x run in scripts resourcesLoc = os.path.join(APPLICATION_PATH, "Resources") elif Global.getOSType() == Global.WINDOWS: resourcesLoc = os.path.join('.', "Resources") elif Global.getOSType() == Global.LINUX: resourcesLoc = os.path.join('.', "Resources") def resourcePath(relative_path): """ Get absolute path to resource, works for dev and for PyInstaller """ if hasattr(sys, '_MEIPASS'): return os.path.join(sys._MEIPASS, relative_path)