예제 #1
0
    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
예제 #2
0
    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)
예제 #3
0
 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)
예제 #4
0
    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
예제 #5
0
    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()
예제 #7
0
        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")
예제 #8
0
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)
예제 #9
0
"""
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")
예제 #10
0
    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()
예제 #11
0
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")
예제 #12
0
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)