Ejemplo n.º 1
0
def start_q_watcher(app, emu_window, proc_comms_q_to_em, proc_comms_q_from_em):
    # need to spawn a worker thread that watches the proc_comms_q
    # need to seperate queue function from queue thread
    # http://stackoverflow.com/questions/4323678/threading-and-signals-problem
    # -in-pyqt
    q_watcher = QueueWatcher(app, emu_window, proc_comms_q_to_em,
                             proc_comms_q_from_em)
    q_watcher_thread = QThread()
    q_watcher.moveToThread(q_watcher_thread)
    q_watcher_thread.started.connect(q_watcher.check_queue)

    # now that we've set up the thread, let's set up rest of signals/slots
    q_watcher.set_out_enable.connect(emu_window.set_output_enable)
    q_watcher.set_out_disable.connect(emu_window.set_output_disable)
    q_watcher.get_in.connect(emu_window.get_input)
    q_watcher.get_out.connect(emu_window.get_output)

    emu_window.send_output.connect(q_watcher.send_get_out_pin_result)
    emu_window.send_input.connect(q_watcher.send_get_in_pin_result)
    emu_window.interrupt_flagger.connect(q_watcher.handle_interrupt)

    # not sure why this doesn't work by connecting to q_watcher_thread.quit
    def about_to_quit():
        q_watcher_thread.quit()

    app.aboutToQuit.connect(about_to_quit)

    q_watcher_thread.start()
Ejemplo n.º 2
0
class QApplicationRunner(QObject):
    """ Application runner starts application in own thread """
    def __init__(self):
        QObject.__init__(self)
        self._thread = QThread()
        self.moveToThread(self._thread)
        self._thread.started.connect(self.start)
        self._ev = Event()
        self._app = None
        self._thread.start()

    @Slot()
    def start(self):
        self.app = Application()
        self._ev.set()
        self.app.exec_()

    def exit(self):
        self.app.exit() # perform polite disposal of resources
        if self._thread.isRunning():
            self._thread.wait(1000) # wait 1 sec
            self._thread.terminate() # no-way

    @property
    def app(self):
        if not self._ev.isSet():
            self._ev.wait()
        return self._app
    @app.setter
    def app(self, app):
        self._app = app
Ejemplo n.º 3
0
 def _btnTransferClicked(self):
     'Transfer Dives'
     idx = self._cbxComputer.currentIndex()
     dc = self._cbxComputer.itemData(idx, Qt.UserRole+0)
     
     if self._logbook.session.dirty:
         print "Flushing dirty session"
         self._logbook.rollback()
     
     self._txtLogbook.setEnabled(False)
     self._btnBrowse.setEnabled(False)
     self._cbxComputer.setEnabled(False)
     self._btnAddComputer.setEnabled(False)
     self._btnRemoveComputer.setEnabled(False)
     self._btnTransfer.setEnabled(False)
     self._btnExit.setEnabled(False)
     
     self._txtStatus.clear()
     
     thread = QThread(self)
     
     #FIXME: ZOMG HAX: Garbage Collector will eat TransferWorker when moveToThread is called
     #NOTE: Qt.QueuedConnection is important...
     self.worker = None
     self.worker = TransferWorker(dc)
     thread.started.connect(self.worker.start, Qt.QueuedConnection)
     self.worker.moveToThread(thread)
     self.worker.finished.connect(self._transferFinished, Qt.QueuedConnection)
     self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection)
     self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection)
     self.worker.progress.connect(self._transferProgress, Qt.QueuedConnection)
     self.worker.started.connect(self._transferStart, Qt.QueuedConnection)
     self.worker.status.connect(self._transferStatus, Qt.QueuedConnection)
     
     thread.start()
Ejemplo n.º 4
0
    def _refresh(self):
        'Refresh the list of Computers'
        self._btnRefresh.setEnabled(False)
        self._btnRefresh.setText('Scanning...')
        self._model.clear()
        
        typ = self.wizard().field('type')
        if typ == len(ComputerTypes):
            # Custom Computer Type
            didx = self.wizard().field('driver')
            drvr = list_drivers().keys()[didx]
            dopt = self.wizard().field('driveropt')
        else:
            # Predefined Computer Type
            drvr = ComputerTypes[typ]['driver']
            dopt = ComputerTypes[typ]['driveropt']
        
        dclass = list_drivers()[drvr]['class']
        doptions = [] if dopt == '' else dopt.split(':')
        
        thread = QThread(self)
        
        #FIXME: ZOMG HAX: Garbage Collector will eat DiscoveryWorker when moveToThread is called
        #NOTE: Qt.QueuedConnection is important...
        self.worker = None
        self.worker = DiscoveryWorker(dclass, doptions)
        self.worker.moveToThread(thread)
        thread.started.connect(self.worker.start, Qt.QueuedConnection)
        self.worker.foundDevice.connect(self._model.addItem, Qt.QueuedConnection)
        self.worker.finished.connect(self._discoverFinished, Qt.QueuedConnection)
        self.worker.finished.connect(self.worker.deleteLater, Qt.QueuedConnection)
        self.worker.finished.connect(thread.deleteLater, Qt.QueuedConnection)

        thread.start()
def start_q_watcher(app, emu_window, proc_comms_q_to_em, proc_comms_q_from_em):
    # need to spawn a worker thread that watches the proc_comms_q
    # need to seperate queue function from queue thread
    # http://stackoverflow.com/questions/4323678/threading-and-signals-problem
    # -in-pyqt
    q_watcher = QueueWatcher(
        app, emu_window, proc_comms_q_to_em, proc_comms_q_from_em)
    q_watcher_thread = QThread()
    q_watcher.moveToThread(q_watcher_thread)
    q_watcher_thread.started.connect(q_watcher.check_queue)

    # now that we've set up the thread, let's set up rest of signals/slots
    q_watcher.set_out_enable.connect(emu_window.set_output_enable)
    q_watcher.set_out_disable.connect(emu_window.set_output_disable)
    q_watcher.get_in.connect(emu_window.get_input)
    q_watcher.get_out.connect(emu_window.get_output)

    emu_window.send_output.connect(q_watcher.send_get_out_pin_result)
    emu_window.send_input.connect(q_watcher.send_get_in_pin_result)
    emu_window.interrupt_flagger.connect(q_watcher.handle_interrupt)

    # not sure why this doesn't work by connecting to q_watcher_thread.quit
    def about_to_quit():
        q_watcher_thread.quit()
    app.aboutToQuit.connect(about_to_quit)

    q_watcher_thread.start()
Ejemplo n.º 6
0
class QWebPageRunner(QObject):
    """ Web page runner starts WebPage instances in one separate thread and implements custom event loop. """
    #FIXME: consider using QEventLoop instead
    def __init__(self, app):
        QObject.__init__(self)
        self._thread = QThread()
        self.moveToThread(self._thread)
        self._thread.started.connect(self.start)
        self._destroying = Event()
        self._destroying.clear()
        self._result = None
        self._commandQueue = Queue()
        self._app = app
        self._thread.start()

    @Slot()
    def start(self):
        try:
            while not self._destroying.is_set():
                self._app.processEvents()
                try:
                    cmd = self._commandQueue.get(timeout=0.1)
                    args = ()
                    if isinstance(cmd, tuple):
                        if not len(cmd):
                            continue
                        args = cmd[1:]
                        cmd = cmd[0]
                    if isinstance(cmd, NewPage):
                        args = (self._app,)
                    if isinstance(cmd, Command):
                        cmd(*args)
                    else:
                        raise ValueError('Unknown command %s(%s).' % (cmd, args))
                except Empty:
                    pass
        except Exception as e:
            logger.exception(e)

    def exit(self):
        self._destroying.set()
        if self._thread.isRunning():
            self._thread.wait(1000) # wait 1 sec
            self._thread.terminate() # no-way

    def invoke(self, cmd, *args):
        if isinstance(cmd, type) and issubclass(cmd, Command):
            cmd = cmd()
        if not isinstance(cmd, Command):
            cmd = Command(cmd)
        cmd.event.clear()
        self._commandQueue.put((cmd,)+args)
        while not cmd.event.is_set():
            self._app.processEvents()
            cmd.event.wait(0.1)
        return cmd.result
Ejemplo n.º 7
0
class RendererExecutorGui(QObject):
    """A class to execute a rendering engine in Graphical User Interface mode.

    This class is designed to run a renderer in a separate thread, keeping GUI
    responsive.  Meanwhile, stdout/stderr are piped to FreeCAD console, in such
    a way it is possible to follow the evolution of the rendering.  To achieve
    that, renderer is executed in a separate thread, using **QThread**.
    Nota: in this class, it is assumed that Qt GUI is up, so it is not tested
    anywhere.
    """
    def __init__(self, cmd, img):
        """Initialize executor.

        Args:
            cmd -- command to execute (str)
            img -- path to resulting image (the renderer output) (str)
        """
        super().__init__(QCoreApplication.instance())
        self.thread = QThread()
        self.worker = Worker(cmd, img)
        self.thread.setObjectName("fcd-renderexec")

    def start(self):
        """Start executor."""
        # Move worker to thread
        self.worker.moveToThread(self.thread)

        # Connect signals and slots
        # pylint: disable=no-member
        self.thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.worker.finished.connect(self.thread.exit)
        self.thread.finished.connect(self.thread.deleteLater)
        # self.thread.finished.connect(lambda: print("Thread finished")) # Dbg

        self.worker.result_ready.connect(display_image)

        # Start the thread
        self.thread.start()

    def join(self):
        """Join thread.

        This method is provided for consistency with CLI executor, but it
        should not be of much use in GUI context.
        """
        loop = QEventLoop()
        self.thread.finished.connect(loop.quit)  # pylint: disable=no-member
        if not self.thread.isFinished():
            loop.exec_(flags=QEventLoop.ExcludeUserInputEvents)
Ejemplo n.º 8
0
def main():

    loadtesterplugins()

    qt.mainthread = QThread.currentThread()  # Store current thread
    qt.initialize_view()  # Get the view ready
    dispatch_thread = QThread()  # The QThread to put the dispatcher on
    qt.maindispatch = QTDispatcher(qt.mainview)  # Set up the dispatcher
    qt.qapp.lastWindowClosed.connect(dispatch_thread.quit)  # Connect the close signal to the thread quit signal
    qt.maindispatch.moveToThread(dispatch_thread)  # Move the dispatcher to the new thread
    dispatch_thread.start()  # Start the thread
    qt.mainview.show()  # Show the main window
    res = qt.qapp.exec_()  # Start the event loop, exits when the last window has been closed
    dispatch_thread.wait()  # Wait for the dispatcher thread to finish
    sys.exit(res)
Ejemplo n.º 9
0
def start_input_watcher(app, emu_window):
    input_watcher = InputWatcher()
    input_watcher_thread = QThread()
    input_watcher.moveToThread(input_watcher_thread)
    input_watcher_thread.started.connect(input_watcher.check_inputs)
    
    # signal / slots
    input_watcher.set_in_enable.connect(emu_window.set_input_enable)
    input_watcher.set_in_disable.connect(emu_window.set_input_disable)

    # qyit setup
    def about_to_quit():
        input_watcher_thread.quit()
    app.aboutToQuit.connect(about_to_quit)

    input_watcher_thread.start()
Ejemplo n.º 10
0
def start_interface_message_handler(
        app, emu_window, proc_comms_q_to_em, proc_comms_q_from_em):
    # need to spawn a worker thread that watches the proc_comms_q
    # need to seperate queue function from queue thread
    # http://stackoverflow.com/questions/4323678/threading-and-signals-problem
    # -in-pyqt
    handler_start = threading.Barrier(2)
    intface_msg_hand = InterfaceMessageHandler(
        app, proc_comms_q_to_em, proc_comms_q_from_em, handler_start)
    intface_msg_hand_thread = QThread()
    intface_msg_hand.moveToThread(intface_msg_hand_thread)
    intface_msg_hand_thread.started.connect(intface_msg_hand.check_queue)

    # now that we've set up the thread, let's set up rest of signals/slots
    intface_msg_hand.set_viewport_corner.connect(
        emu_window.slot_set_viewport_corner)
    intface_msg_hand.set_cursor.connect(emu_window.slot_set_cursor)
    intface_msg_hand.set_message.connect(emu_window.slot_set_message)
    intface_msg_hand.set_display_enable.connect(
        emu_window.slot_set_display_enable)
    intface_msg_hand.set_backlight_enable.connect(
        emu_window.slot_set_backlight_enable)
    intface_msg_hand.set_cursor_enable.connect(
        emu_window.slot_set_cursor_enable)
    intface_msg_hand.set_blink_enable.connect(
        emu_window.slot_set_blink_enable)
    intface_msg_hand.get_switch.connect(emu_window.slot_get_switch)
    intface_msg_hand.get_cursor.connect(emu_window.slot_get_cursor)
    intface_msg_hand.get_viewport_corner.connect(
        emu_window.slot_get_viewport_corner)
    intface_msg_hand.move_left.connect(emu_window.slot_move_left)
    intface_msg_hand.move_right.connect(emu_window.slot_move_right)
    intface_msg_hand.home.connect(emu_window.slot_home)
    intface_msg_hand.clear.connect(emu_window.slot_clear)
    intface_msg_hand.see_cursor.connect(emu_window.slot_see_cursor)

    emu_window.send_switch.connect(intface_msg_hand.send_get_switch_result)
    emu_window.send_cursor.connect(intface_msg_hand.send_get_cursor_result)
    emu_window.send_viewport_corner.connect(
        intface_msg_hand.send_get_viewport_corner_result)

    def about_to_quit():
        intface_msg_hand_thread.quit()
    app.aboutToQuit.connect(about_to_quit)

    intface_msg_hand_thread.start()
    handler_start.wait()
Ejemplo n.º 11
0
def start_input_watcher(app, emu_window):
    input_watcher = InputWatcher(emu_window)
    input_watcher_thread = QThread()
    input_watcher.moveToThread(input_watcher_thread)
    input_watcher_thread.started.connect(input_watcher.check_inputs)

    # signal / slots
    input_watcher.set_in_enable.connect(emu_window.set_input_enable)
    input_watcher.set_in_disable.connect(emu_window.set_input_disable)

    # quit setup
    def about_to_quit():
        input_watcher.stop_checking_inputs()
        input_watcher_thread.quit()

    app.aboutToQuit.connect(about_to_quit)

    input_watcher_thread.start()
Ejemplo n.º 12
0
def start_blinker(app, emu_window):
    # need to spawn a worker thread that watches the proc_comms_q
    # need to seperate queue function from queue thread
    # http://stackoverflow.com/questions/4323678/threading-and-signals-problem
    # -in-pyqt
    blinker_start = threading.Barrier(2)
    blinker = Blinker(emu_window, blinker_start)
    blinker_thread = QThread()
    blinker.moveToThread(blinker_thread)
    blinker_thread.started.connect(blinker.blink)

    blinker.blink_signal.connect(emu_window.blink)

    # not sure why this doesn't work by connecting to blinker_thread.quit
    def about_to_quit():
        blinker_thread.quit()
    app.aboutToQuit.connect(about_to_quit)

    blinker_thread.start()
    blinker_start.wait()
Ejemplo n.º 13
0
def main(argv = None):
    if argv is None:
        argv = sys.argv

    version = '20130216'      # modification date in yyyymmdd format

    connmgr = ConnectionManager()
    comm = SerialComm(connmgr)
    app = QApplication(argv)
    appwindow = MainWindow(connmgr, 'Projector Control Panel')
    commthread = QThread()

    comm.enumerateSerialPorts()
    comm.moveToThread(commthread)
    commthread.start()

    appwindow.show()
    appwindow.writeToLog('Software version ' + version + '.')

    result = app.exec_()
    commthread.quit()
    commthread.wait()

    return result
Ejemplo n.º 14
0
class SyncWindow(QMainWindow):
    """
    Application main window. This class is meant to handle
    every widget needed by the application, as well as other
    needed global objects and behavior.
    """

    failedLogIn = Signal()
    syncStarted = Signal()
    loginRequested = Signal((
        str,
        str,
    ))
    statusChanged = Signal((
        str,
        str,
        int,
    ))

    def __init__(self, parent=None):
        super(SyncWindow, self).__init__(parent)

        # Sets up several UI aspects
        self.tray = QSystemTrayIcon(self)
        self.tray.setIcon(QIcon(QPixmap(':/resources/icon.png')))
        self.tray.show()

        self.setStyleSheet('SyncWindow {background: white}')
        self.setWindowTitle('IQBox')
        self.setWindowIcon(QIcon(QPixmap(':/resources/logobar.png')))
        self.statusBar().setFont(View.labelsFont())
        self.syncThread = None

        # Initializes the window with a `LoginView` widget.
        self.loginView()

    def loginView(self):
        """
        Initializes a `LoginView` object and sets it up as the main window's
        central widget.
        """
        login = LoginView()

        login.login.connect(self.onLogin)
        self.failedLogIn.connect(login.onFailedLogIn)

        self.setCentralWidget(login)
        self.setFixedSize(login.size())
        self.statusBar().hide()

    def syncView(self):
        """
        Initializes a `SyncView` object and sets it up as the main window's
        central widget.
        """

        syncview = SyncView()

        self.setCentralWidget(syncview)
        self.setFixedSize(syncview.size())
        self.statusBar().show()

        self.statusChanged.connect(syncview.status.setMessage)
        syncview.sync.connect(self.onSync)

    @Slot(str, str, str, bool)
    def onLogin(self, host, username, passwd, ssl):
        """
        Slot. Triggers a log in request to the server.
        
        :param host: Indicates the hostname of the FTP server
        :param username: Username to log in into the FTP server
        :param passwd: Password to log in into the FTP server
        :param ssl: Indicates whether the FTP needs SSL support
        """

        self.sync = Sync(host, ssl)
        self.syncStarted.connect(self.sync.initQueue)
        self.sync.server.downloadProgress.connect(self.onDownloadProgress)
        self.sync.server.uploadProgress.connect(self.onUploadProgress)
        self.sync.server.fileEvent.connect(self.onFileEvent)
        self.sync.server.badFilenameFound.connect(self.badNameWarning)
        self.sync.server.loginCompleted.connect(self.onLoginCompleted)
        self.sync.server.fileEventCompleted.connect(self.onFileEventCompleted)
        self.sync.server.ioError.connect(self.onIOError)
        # Added by Si
        self.sync.server.textStatus.connect(self.setStatus)

        self.sync.statusChanged.connect(self.setStatus)
        self.loginRequested.connect(self.sync.server.onLogin)

        self.syncThread = QThread()
        self.sync.moveToThread(self.syncThread)
        self.syncThread.start()

        QApplication.instance().lastWindowClosed.connect(self.syncThread.quit)
        self.loginRequested.emit(username, passwd)

    @Slot(bool, str)
    def onLoginCompleted(self, ok, msg):
        if not ok:
            self.showMessageBox(msg)
            self.failedLogIn.emit()

        else:
            self.syncView()

    @Slot()
    def onFileEventCompleted(self):
        # Workaround because there's an exception
        # when there's a file IO error
        # Ideally it should be managed elsewhere
        # But I don't know the code intimately enough yet.
        try:
            self.currentFile
        except AttributeError:
            self.currentFile = ''

        self.statusChanged.emit('Completed', self.currentFile, 100)

    @Slot(str)
    def onSync(self, localdir):
        """
        Slot. Triggers a server checkout.
        
        :param localdir: Absolute local directory path where to keep the files
        """
        self.sync.setLocalDir(localdir)
        self.sync.local.ioError.connect(self.onIOError)
        self.syncStarted.emit()
        self.setStatus('Syncing')

    def showMessageBox(self, msg):
        warning = QMessageBox(self)
        warning.setFont(View.labelsFont())
        warning.setStyleSheet('QMessageBox {background: white}')
        warning.setWindowTitle("Error")
        warning.setText(msg)
        warning.setIcon(QMessageBox.Warning)
        warning.addButton("Ok",
                          QMessageBox.AcceptRole).setFont(View.editsFont())
        warning.exec_()

    @Slot(int, int)
    def onProgress(self, action, total, progress):
        """
        Slot. Triggers download progress update in the UI.
        
        :param total: Total size of the download in bytes
        :param progress: Current downdload progress in bytes
        """

        if progress <= 0:
            return
        else:
            percent = (progress * 100) / total
            self.statusChanged.emit(action, self.currentFile, percent)

    @Slot(str)
    def setStatus(self, msg):
        self.statusChanged.emit(msg, '', 0)

    @Slot(int, int)
    def onDownloadProgress(self, total, progress):
        """
        Slot. Triggers upload progress update in the UI.
        
        :param total: Total size of the download in bytes
        :param progress: Current downdload progress in bytes
        """

        self.onProgress('Downloading', total, progress)

    @Slot(int, int)
    def onUploadProgress(self, total, progress):
        """
        Slot. Triggers download progress update in the UI.
        
        :param total: Total size of the download in bytes
        :param progress: Current downdload progress in bytes
        """

        self.onProgress('Uploading', total, progress)

    @Slot(str)
    def onFileEvent(self, filename):
        """
        Slot. Updates the current download filename to be used in the UI
        
        :param filename: Name of the file that is being downloaded
        """

        self.currentFile = filename

    @Slot(str)
    def onIOError(self, filename):
        self.showMessageBox('Error reading: "{}"'.format(filename))

    @Slot(str)
    def badNameWarning(self, filename):
        self.showMessageBox(
            'Will not sync "{}". Invalid filename'.format(filename))
Ejemplo n.º 15
0
    debug_thread("rx_thread", rx_thread)
    if USE_DERIVED:
        # receiver = Derived()
        # receiver = DerivedTwo()
        # receiver = DerivedThree()
        # receiver = RelayDerived()
        receiver = DerivedFromNoSlot()
    else:
        receiver = Base()
        # receiver = RelayBase()
        # receiver = NoSlotBase()
    debug_object(receiver)
    receiver.moveToThread(rx_thread)
    debug_object(receiver)

    # Signals: startup
    tx_thread.started.connect(transmitter.start)
    rx_thread.started.connect(receiver.start)
    # ... shutdown
    transmitter.finished.connect(tx_thread.quit)
    tx_thread.finished.connect(rx_thread.quit)
    rx_thread.finished.connect(app.quit)
    # ... action
    transmitter.transmit.connect(receiver.receive)

    # Go
    rx_thread.start()
    tx_thread.start()
    report("Starting app")
    app.exec_()
Ejemplo n.º 16
0
class UnlockDialog(QDialog, Ui_Dialog):
    signal = QtCore.Signal(str, str)

    def __init__(self, fileName=None, parent=None):
        super(UnlockDialog, self).__init__(parent)
        if not admin.isUserAdmin():
            admin.runAsAdmin()
            # end the current instance of the program because it isn't uac. Results in two app windows otherwise.
            sys.exit(0)
        self.setupUi(self)
        # print psutil.Process(os.getpid()).parent
        fileArgPos = self._getRelevantCmdArgument(sys.argv)
        if fileArgPos != None:
            self.fileName = sys.argv[fileArgPos]
            self.stackedWidget.setCurrentIndex(0)
            self.setUnlockTextLabel(self.fileName)
            self.sameLocation = False
        # elif self._checkScriptNameInFolder():
        #     parentProcessName = psutil.Process(os.getpid()).parent().exe()
        #     if parentProcessName != "python.exe":
        #         scriptName = os.path.basename(parentProcessName)
        #     else:
        #         scriptName = os.path.basename(__file__)
        #     # get the script name without file extension
        #     scriptName = os.path.splitext(scriptName)[0] + ".exelocker"
        #     self.fileName = os.path.basename(scriptName)
        #     self.sameLocation = False
        #     self.setUnlockTextLabel(self.fileName)
        #     self.stackedWidget.setCurrentIndex(0)
        else:
            self.fileName = None
            self.sameLocation = True
            self.stackedWidget.setCurrentIndex(1)
            if self._argsHasDirectory():
                index = self._getRelevantDirectoryArg()
                self.fillListWidget(sys.argv[index])
            else:
                self.fillListWidget()

        self.setWindowFlags(QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
        self.setFixedSize(self.width(), self.height())

        # connect the unlock button
        self.unlockButton.clicked.connect(self.unlockFile)
        # self.passwordLineEdit.returnPressed.connect(self.unlockFile) # <-- This line of code ruined my whole f*****g day
        # The above line made two events fire when the exelocker filename is same as the script name. I don't f*****g understand it. F**K
        self.browseButton.clicked.connect(self.browseFiles)
        self.listWidgetUnlockButton.clicked.connect(self.listWidgetSelectedEvent)





        # connect with the thread
        self.signal.connect(self.fileUnlockedEvent)


    def _argsHasDirectory(self):
        """" Check if the argument has a directory """
        for index, args in enumerate(sys.argv):
            if os.path.isdir(args):
                return True

        return None

    def _getRelevantDirectoryArg(self):
        """ Return the index of the argument which is a directory """
        for index, args in enumerate(sys.argv):
            if os.path.isdir(args):
                return index

        return None


    def _checkScriptNameInFolder(self):
        parentProcessName = psutil.Process(os.getpid()).parent().name()
        if parentProcessName != "python.exe":
            scriptName = parentProcessName
        else:
            scriptName = os.path.basename(__file__)
        # get script name without extension
        scriptName = os.path.splitext(scriptName)[0]
        # change extension of script name to lock to .exelocker
        scriptName = scriptName + ".exelocker"
        # print scriptName
        fileList = self._getRelevantFilesInFolder()
        try:
            index = fileList.index(scriptName)
            print index
        except ValueError:
            index = None
        if index != None:
            return True
        else:
            return False

    def listWidgetSelectedEvent(self):
        self.fileName = self.listWidget.currentItem().text()
        self.setUnlockTextLabel(self.fileName)
        self.stackedWidget.setCurrentIndex(0)
        self.setUnlockTextLabel(self.fileName)

    def setUnlockTextLabel(self, fileName):
        if fileName and len(fileName):
            fileName = os.path.basename(fileName)
            string = u"Enter password for " + fileName + ":"
            self.unlockTextLabel.setText(string)

    def fillListWidget(self, location = None):
        if location != None:
            filteredList = self._getRelevantFilesInFolder(location)
        else:
            filteredList = self._getRelevantFilesInFolder()

        self.listWidget.addItems(filteredList)

    def _getRelevantFilesInFolder(self, location = None):
        if location == None:
            files = os.listdir('.')
        else:
            files = os.listdir(location)
        filteredList = []
        for f in files:
            if os.path.isfile(f):
                extension = os.path.splitext(f)[1]
                if extension == ".exelocker":
                    filteredList.append(f)
        return filteredList

    def browseFiles(self):
        dir = "."
        file = QFileDialog.getOpenFileName(self, "Select .exelocker file", dir, "EXE Locker file (*.exelocker)")
        if len(file[0]):
            self.fileName = file[0]
            self.stackedWidget.setCurrentIndex(0)
            self.setUnlockTextLabel(self.fileName)

    def fileUnlockedEvent(self, success, decryptedFileName):
        if success == 'True':
            QMessageBox.information(self, __appname__, "File Unlocked Successfully.")
        else:
            os.remove(decryptedFileName)
            EncryptedFile.replaceWithUnlockDialog(EncryptedFile.CALLER_LOCATION, decryptedFileName)
            QMessageBox.information(self, __appname__, "Wrong password. Couldn't unlock file.")

    def unlockFile(self):
        if EncryptedFile.isValidFile(self.fileName):
            eFile = EncryptedFile(self.fileName)
            unhashedPassword = self.passwordLineEdit.text()
            password = EncryptionHelper.generateKeyHash(unhashedPassword)
            self.thread = QThread()
            self.worker = Worker(eFile, password, self.signal, self.sameLocation)
            self.worker.moveToThread(self.thread)
            self.thread.started.connect(self.worker.run)
            self.worker.signal.connect(self.thread.quit)
            self.worker.signal.connect(self.worker.deleteLater)
            self.thread.finished.connect(self.thread.deleteLater)
            self.thread.start()
        else:
            QMessageBox.information(self, __appname__, "Invalid .exelocker file.")
        self.passwordLineEdit.setText("")



    def _getRelevantCmdArgument(self, args):
        for arg in args:
            if EncryptedFile.isValidFile(arg):
                return args.index(arg)

        return None
class Progress(QWidget, ProgressGui.Ui_Progress):
    # Signals
    completeProcessSig = Signal(str)
    endProcessEarlySig = Signal()

    """
    --------------------------------------------------------------------------------------------------------------------
    Constructor method
    --------------------------------------------------------------------------------------------------------------------
    """
    def __init__(self,
                 mode,
                 algo_type,
                 key,
                 keysize,
                 ciphertext_file_path,
                 plaintext_file_path,
                 parent=None):
        super(Progress, self).__init__(parent)
        self.setupUi(self)
        self.setWindowTitle(ApplicationStrings.APPLICATION_NAME)
        self.setFixedSize(500, 135)

        # set values from those passed in
        self.mode = mode
        self.algo_type = algo_type
        self.key = key
        self.keysize = keysize
        self.ciphertext_file_path = ciphertext_file_path
        self.plaintext_file_path = plaintext_file_path

        # create empty holders
        self.init_vector = None
        self.cipher = None
        self.cipher_process = None
        self.monitor_progress_thread = None
        self.progress_monitor = None

        # create Values to be shared between processes
        self.end_process_early = Value('i', 0)
        self.percent_done = Value('d', 0.0)
        self.pause_requested = Value('i', 0)
        self.paused = Value('i', 0)
        self.pause_sig_sent = Value('i', 0)

        # connect cancel btn signal and slot
        self.cancel_btn.clicked.connect(self.requestPause)
        # create the Value objects shared between processes
        self.setGuiValues()
        # create the initialization vector
        self.createInitVector()
        # create an instance of the appropriate cipher
        self.createCipher()
        # create and setup the monitor class
        self.setupMonitor()
        # create the Process that the Cipher will run in
        self.createCipherProcess()

    """
    --------------------------------------------------------------------------------------------------------------------
    Set the Gui Labels from data passed into constructor
    --------------------------------------------------------------------------------------------------------------------
    """
    def setGuiLabels(self):
        if self.mode == 'encryption':
            self.title_label.setText('Encrypting File: %s' \
                                     % self.plaintext_file_path[:3]+'.../'+self.plaintext_file_path.split('/')[-1])
        elif self.mode == 'decryption':
            self.title_label.setText('Decrypting File: %s' \
                                     % self.ciphertext_file_path[:3]+'.../'+self.ciphertext_file_path.split('/')[-1])
        self.key_label.setText('Key: %s' % binascii.hexlify(self.key).decode())
        self.progress_bar.reset()

    """
    --------------------------------------------------------------------------------------------------------------------
    Create the Initialization vector
    --------------------------------------------------------------------------------------------------------------------
    """
    def createInitVector(self):
        if kr.getFromKeyring('iv_source', 'admin') is None:
            self.init_vector = 1
        else:
            self.init_vector = int(kr.getFromKeyring('iv_source', 'admin')) + 1
        kr.saveToKeyring('iv_source', 'admin', str(self.init_vector))
        self.init_vector = hashlib.sha256(str(self.init_vector).encode('utf-8')).hexdigest()
        self.init_vector = bytearray.fromhex(self.init_vector)[:16]

    """
    --------------------------------------------------------------------------------------------------------------------
    Create the Cipher Algorithm
    --------------------------------------------------------------------------------------------------------------------
    """
    def createCipher(self):
        if self.algo_type == 'aes':
            self.cipher = AesCipher(self.keysize,
                                    self.plaintext_file_path,
                                    self.ciphertext_file_path,
                                    self.init_vector,
                                    self.key)
        elif self.algo_type == '3es':
            print('3es')
        elif self.algo_type == 'des':
            print('des')

    """
    --------------------------------------------------------------------------------------------------------------------
    Setup the monitor class and move to its own thread
    --------------------------------------------------------------------------------------------------------------------
    """
    def setupMonitor(self):
        self.monitor_progress_thread = QThread()
        self.progress_monitor = ProgressMonitor(self.percent_done,
                                               self.paused,
                                               self.pause_sig_sent,
                                               self.end_process_early)
        self.progress_monitor.moveToThread(self.monitor_progress_thread)
        # connect signals and slots
        self.monitor_progress_thread.started.connect(self.progress_monitor.beginMonitoring)
        self.progress_monitor.updateProcessSig.connect(self.update)
        self.progress_monitor.endProcessEarlySig.connect(self.endEarly)
        self.progress_monitor.endProcessSig.connect(self.complete)
        self.progress_monitor.pauseSig.connect(self.showCancelMessage)

    """
    --------------------------------------------------------------------------------------------------------------------
    Create the Cipher Process and set the target to the appropriate method in the Cipher instance
    --------------------------------------------------------------------------------------------------------------------
    """
    def createCipherProcess(self):
        if self.mode == 'encryption':
            self.cipher_process = Process(target=self.cipher.encrypt, args=(self.percent_done,
                                                                            self.pause_requested,
                                                                            self.paused))
        elif self.mode == 'decryption':
            self.cipher_process = Process(target=self.cipher.decrypt, args=(self.percent_done,
                                                                            self.pause_requested,
                                                                            self.paused))

    """
    --------------------------------------------------------------------------------------------------------------------
    Begin the encryption/decryption process and start the monitoring thread
    --------------------------------------------------------------------------------------------------------------------
    """
    def begin(self):
        self.monitor_progress_thread.start()
        self.cipher_process.start()

    """
    --------------------------------------------------------------------------------------------------------------------
    Update the progress bar with values from the encryption/decryption process
    --------------------------------------------------------------------------------------------------------------------
    """
    def update(self, percent_done):
        self.progress_bar.setValue(percent_done)

    """
    --------------------------------------------------------------------------------------------------------------------
    request the process to pause
    --------------------------------------------------------------------------------------------------------------------
    """
    def requestPause(self):
        self.pause_requested.value = 1

    """
    --------------------------------------------------------------------------------------------------------------------
    show the cancel message
    --------------------------------------------------------------------------------------------------------------------
    """
    def showCancelMessage(self):
        msgBox = QMessageBox()
        msgBox.setText("Are You Sure You Want To Cancel %s" % self.mode)
        msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        msgBox.setDefaultButton(QMessageBox.Cancel)
        ret = msgBox.exec_()

        if ret == QMessageBox.Ok:
            self.end_process_early.value = 1
        elif ret == QMessageBox.Cancel:
            self.paused.value = 0
            self.pause_requested.value = 0
            self.pause_sig_sent.value = 0
            self.pause_requested.value = 0

    """
    --------------------------------------------------------------------------------------------------------------------
    Complete encryption / decryption when done
    --------------------------------------------------------------------------------------------------------------------
    """
    def complete(self):
        self.cipher = None
        # terminate the update progress thread
        self.monitor_progress_thread.terminate()
        while self.monitor_progress_thread.isRunning():
            time.sleep(0.01)
        # terminate the cipher process
        self.cipher_process.terminate()
        while self.cipher_process.is_alive():
            time.sleep(0.01)
        self.close()
        # create the filepath to send back to the message box
        fp = ''
        if self.mode == 'encryption':
            fp = self.ciphertext_file_path
        elif self.mode == 'decryption':
            fp = self.plaintext_file_path
        # emit Signal
        self.completeProcessSig.emit(fp)

    """
    --------------------------------------------------------------------------------------------------------------------
    Cancel the encryption / decryption before completion
    --------------------------------------------------------------------------------------------------------------------
    """
    def endEarly(self):
        self.cipher = None
        # terminate the update progress thread
        self.monitor_progress_thread.terminate()
        while self.monitor_progress_thread.isRunning():
            time.sleep(0.01)
        # terminate the cipher process
        self.cipher_process.terminate()
        while self.cipher_process.is_alive():
            time.sleep(0.01)
        self.close()
        # emit Signal
        self.endProcessEarlySig.emit()
Ejemplo n.º 18
0
	def start(self):
		QThread.start(self)
		loop=QEventLoop()
		self._init.connect(loop.quit)
		loop.exec_()
Ejemplo n.º 19
0
class UnlockDialog(QDialog, Ui_Dialog):
    signal = QtCore.Signal(str, str)

    def __init__(self, fileName=None, parent=None):
        super(UnlockDialog, self).__init__(parent)
        if not admin.isUserAdmin():
            admin.runAsAdmin()
            # end the current instance of the program because it isn't uac. Results in two app windows otherwise.
            sys.exit(0)
        self.setupUi(self)
        # print psutil.Process(os.getpid()).parent
        fileArgPos = self._getRelevantCmdArgument(sys.argv)
        if fileArgPos != None:
            self.fileName = sys.argv[fileArgPos]
            self.stackedWidget.setCurrentIndex(0)
            self.setUnlockTextLabel(self.fileName)
            self.sameLocation = False
        # elif self._checkScriptNameInFolder():
        #     parentProcessName = psutil.Process(os.getpid()).parent().exe()
        #     if parentProcessName != "python.exe":
        #         scriptName = os.path.basename(parentProcessName)
        #     else:
        #         scriptName = os.path.basename(__file__)
        #     # get the script name without file extension
        #     scriptName = os.path.splitext(scriptName)[0] + ".exelocker"
        #     self.fileName = os.path.basename(scriptName)
        #     self.sameLocation = False
        #     self.setUnlockTextLabel(self.fileName)
        #     self.stackedWidget.setCurrentIndex(0)
        else:
            self.fileName = None
            self.sameLocation = True
            self.stackedWidget.setCurrentIndex(1)
            if self._argsHasDirectory():
                index = self._getRelevantDirectoryArg()
                self.fillListWidget(sys.argv[index])
            else:
                self.fillListWidget()

        self.setWindowFlags(QtCore.Qt.WindowSystemMenuHint
                            | QtCore.Qt.WindowTitleHint)
        self.setFixedSize(self.width(), self.height())

        # connect the unlock button
        self.unlockButton.clicked.connect(self.unlockFile)
        # self.passwordLineEdit.returnPressed.connect(self.unlockFile) # <-- This line of code ruined my whole f*****g day
        # The above line made two events fire when the exelocker filename is same as the script name. I don't f*****g understand it. F**K
        self.browseButton.clicked.connect(self.browseFiles)
        self.listWidgetUnlockButton.clicked.connect(
            self.listWidgetSelectedEvent)

        # connect with the thread
        self.signal.connect(self.fileUnlockedEvent)

    def _argsHasDirectory(self):
        """" Check if the argument has a directory """
        for index, args in enumerate(sys.argv):
            if os.path.isdir(args):
                return True

        return None

    def _getRelevantDirectoryArg(self):
        """ Return the index of the argument which is a directory """
        for index, args in enumerate(sys.argv):
            if os.path.isdir(args):
                return index

        return None

    def _checkScriptNameInFolder(self):
        parentProcessName = psutil.Process(os.getpid()).parent().name()
        if parentProcessName != "python.exe":
            scriptName = parentProcessName
        else:
            scriptName = os.path.basename(__file__)
        # get script name without extension
        scriptName = os.path.splitext(scriptName)[0]
        # change extension of script name to lock to .exelocker
        scriptName = scriptName + ".exelocker"
        # print scriptName
        fileList = self._getRelevantFilesInFolder()
        try:
            index = fileList.index(scriptName)
            print index
        except ValueError:
            index = None
        if index != None:
            return True
        else:
            return False

    def listWidgetSelectedEvent(self):
        self.fileName = self.listWidget.currentItem().text()
        self.setUnlockTextLabel(self.fileName)
        self.stackedWidget.setCurrentIndex(0)
        self.setUnlockTextLabel(self.fileName)

    def setUnlockTextLabel(self, fileName):
        if fileName and len(fileName):
            fileName = os.path.basename(fileName)
            string = u"Enter password for " + fileName + ":"
            self.unlockTextLabel.setText(string)

    def fillListWidget(self, location=None):
        if location != None:
            filteredList = self._getRelevantFilesInFolder(location)
        else:
            filteredList = self._getRelevantFilesInFolder()

        self.listWidget.addItems(filteredList)

    def _getRelevantFilesInFolder(self, location=None):
        if location == None:
            files = os.listdir('.')
        else:
            files = os.listdir(location)
        filteredList = []
        for f in files:
            if os.path.isfile(f):
                extension = os.path.splitext(f)[1]
                if extension == ".exelocker":
                    filteredList.append(f)
        return filteredList

    def browseFiles(self):
        dir = "."
        file = QFileDialog.getOpenFileName(self, "Select .exelocker file", dir,
                                           "EXE Locker file (*.exelocker)")
        if len(file[0]):
            self.fileName = file[0]
            self.stackedWidget.setCurrentIndex(0)
            self.setUnlockTextLabel(self.fileName)

    def fileUnlockedEvent(self, success, decryptedFileName):
        if success == 'True':
            QMessageBox.information(self, __appname__,
                                    "File Unlocked Successfully.")
        else:
            os.remove(decryptedFileName)
            EncryptedFile.replaceWithUnlockDialog(
                EncryptedFile.CALLER_LOCATION, decryptedFileName)
            QMessageBox.information(self, __appname__,
                                    "Wrong password. Couldn't unlock file.")

    def unlockFile(self):
        if EncryptedFile.isValidFile(self.fileName):
            eFile = EncryptedFile(self.fileName)
            unhashedPassword = self.passwordLineEdit.text()
            password = EncryptionHelper.generateKeyHash(unhashedPassword)
            self.thread = QThread()
            self.worker = Worker(eFile, password, self.signal,
                                 self.sameLocation)
            self.worker.moveToThread(self.thread)
            self.thread.started.connect(self.worker.run)
            self.worker.signal.connect(self.thread.quit)
            self.worker.signal.connect(self.worker.deleteLater)
            self.thread.finished.connect(self.thread.deleteLater)
            self.thread.start()
        else:
            QMessageBox.information(self, __appname__,
                                    "Invalid .exelocker file.")
        self.passwordLineEdit.setText("")

    def _getRelevantCmdArgument(self, args):
        for arg in args:
            if EncryptedFile.isValidFile(arg):
                return args.index(arg)

        return None
Ejemplo n.º 20
0
class MainWindow(QMainWindow):
    start_acq = Signal(str)
    start_rec = Signal(str)
    collect_frame = Signal(object)
    collect_threshed = Signal(object)

    def __init__(self, parent=None):
        ''' sets up the whole main window '''

        #standard init
        super(MainWindow, self).__init__(parent)

        #set the window title
        self.setWindowTitle('Open Ephys Control GUI')

        self.window_height = 700
        self.window_width = 1100

        self.screen2 = QDesktopWidget().screenGeometry(0)
        self.move(
            self.screen2.left() +
            (self.screen2.width() - self.window_width) / 2.,
            self.screen2.top() +
            (self.screen2.height() - self.window_height) / 2.)

        self.get_info()
        self.noinfo = True

        while self.noinfo:
            loop = QEventLoop()
            QTimer.singleShot(500., loop.quit)
            loop.exec_()

        subprocess.Popen('start %s' % open_ephys_path, shell=True)

        self.collect_frame.connect(self.update_frame)
        self.collect_threshed.connect(self.update_threshed)
        self.acquiring = False
        self.recording = False

        self.video_height = self.window_height * .52
        self.video_width = self.window_width * .48

        self.resize(self.window_width, self.window_height)

        #create QTextEdit window 'terminal' for receiving stdout and stderr
        self.terminal = QTextEdit(self)
        #set the geometry
        self.terminal.setGeometry(
            QRect(self.window_width * .02,
                  self.window_height * .15 + self.video_height,
                  self.video_width * .96, 150))

        #make widgets
        self.setup_video_frames()
        self.setup_thresh_buttons()

        self.overlay = True

        #create thread and worker for video processing
        self.videoThread = QThread(self)
        self.videoThread.start()
        self.videoproc_worker = VideoWorker(self)
        self.videoproc_worker.moveToThread(self.videoThread)

        self.vt_file = None
        """""" """""" """""" """""" """""" """""" """""" """
        set up menus
        """ """""" """""" """""" """""" """""" """""" """"""

        #create a QMenuBar and set geometry
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(
            QRect(0, 0, self.window_width * .5, self.window_height * .03))
        #set the QMenuBar as menu bar for main window
        self.setMenuBar(self.menubar)

        #create a QStatusBar
        statusbar = QStatusBar(self)
        #set it as status bar for main window
        self.setStatusBar(statusbar)

        #create icon toolbar with default image
        iconToolBar = self.addToolBar("iconBar.png")

        #create a QAction for the acquire button
        self.action_Acq = QAction(self)
        #make it checkable
        self.action_Acq.setCheckable(True)
        #grab an icon for the button
        acq_icon = self.style().standardIcon(QStyle.SP_MediaPlay)
        #set the icon for the action
        self.action_Acq.setIcon(acq_icon)
        #when the button is pressed, call the Acquire function
        self.action_Acq.triggered.connect(self.Acquire)

        #create a QAction for the record button
        self.action_Record = QAction(self)
        #make it checkable
        self.action_Record.setCheckable(True)
        #grab an icon for the button
        record_icon = self.style().standardIcon(QStyle.SP_DialogYesButton)
        #set the icon for the action
        self.action_Record.setIcon(record_icon)
        #when the button is pressed, call advanced_settings function
        self.action_Record.triggered.connect(self.Record)

        #create QAction for stop button
        action_Stop = QAction(self)
        #grab close icon
        stop_icon = self.style().standardIcon(QStyle.SP_MediaStop)
        #set icon for action
        action_Stop.setIcon(stop_icon)
        #when button pressed, close window
        action_Stop.triggered.connect(self.Stop)

        #show tips for each action in the status bar
        self.action_Acq.setStatusTip("Start acquiring")
        self.action_Record.setStatusTip("Start recording")
        action_Stop.setStatusTip("Stop acquiring/recording")

        #add actions to icon toolbar
        iconToolBar.addAction(self.action_Acq)
        iconToolBar.addAction(self.action_Record)
        iconToolBar.addAction(action_Stop)

        #        self.sort_button = QPushButton('Sort Now',self)
        #        self.sort_button.setGeometry(QRect(self.window_width*.85,0,self.window_width*.15,self.window_height*.05))
        #        self.sort_button.clicked.connect(self.sort_now)

        #show the window if minimized by windows
        self.showMinimized()
        self.showNormal()
        """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""
        """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    #this function acts as a slot to accept 'message' signal
    @Slot(str)
    def print_message(self, message):
        ''' print stdout and stderr to terminal window '''

        #move terminal cursor to end
        self.terminal.moveCursor(QTextCursor.End)
        #write message to terminal
        self.terminal.insertPlainText(message)

    def setup_thresh_buttons(self):
        ''' set up buttons for overlay/clearing thresh view '''

        self.button_frame = QFrame(self)
        self.button_frame.setGeometry(
            QRect(self.window_width * .52,
                  self.window_height * .13 + self.video_height,
                  self.video_width * .98, 50))
        button_layout = QHBoxLayout()
        self.button_frame.setLayout(button_layout)
        self.clear_button = QPushButton('Clear')
        self.overlay_button = QPushButton('Overlay')
        button_layout.addWidget(self.clear_button)
        button_layout.addWidget(self.overlay_button)

        self.clear_button.setEnabled(False)
        self.clear_button.clicked.connect(self.clear_threshed)
        self.overlay_button.setEnabled(False)
        self.overlay_button.clicked.connect(self.overlay_threshed)

    def setup_video_frames(self):
        ''' set up spots for playing video frames '''

        filler_frame = np.zeros((360, 540, 3))
        filler_frame = qimage2ndarray.array2qimage(filler_frame)

        self.raw_frame = QFrame(self)
        self.raw_label = QLabel()
        self.raw_label.setText('raw')
        self.raw_frame.setGeometry(
            QRect(self.window_width * .01, self.window_height * .15,
                  self.video_width, self.video_height))
        self.raw_frame
        raw_layout = QVBoxLayout()
        self.raw_frame.setLayout(raw_layout)
        raw_layout.addWidget(self.raw_label)

        self.threshed_frame = QFrame(self)
        self.threshed_label = QLabel()
        self.threshed_label.setText('Threshed')
        self.threshed_frame.setGeometry(
            QRect(self.window_width * .51, self.window_height * .15,
                  self.video_width, self.video_height))
        threshed_layout = QVBoxLayout()
        self.threshed_frame.setLayout(threshed_layout)
        threshed_layout.addWidget(self.threshed_label)

        self.label_frame = QFrame(self)
        self.label_frame.setGeometry(
            QRect(self.window_width * .01, self.window_height * .11,
                  self.video_width * 2, 50))
        self.label_rawlabel = QLabel()
        self.label_rawlabel.setText('Raw Video')
        self.label_threshedlabel = QLabel()
        self.label_threshedlabel.setText('Threshold View')
        label_layout = QHBoxLayout()
        self.label_frame.setLayout(label_layout)
        label_layout.addWidget(self.label_rawlabel)
        label_layout.addWidget(self.label_threshedlabel)

        self.raw_label.setPixmap(QPixmap.fromImage(filler_frame))
        self.threshed_label.setPixmap(QPixmap.fromImage(filler_frame))

    def Acquire(self):

        if self.action_Acq.isChecked():

            self.vidbuffer = []

            if self.recording:

                while 1:
                    try:
                        self.sock.send('StopRecord')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.recording = False

            else:
                #create and start a thread to transport a worker to later
                self.workerThread = QThread(self)
                self.workerThread.start()
                #create a worker object based on Worker class and move it to our
                #worker thread
                self.worker = Worker(self)
                self.worker.moveToThread(self.workerThread)

                try:
                    self.start_acq.disconnect()
                except:
                    pass

                while 1:
                    try:
                        self.sock.send('StartAcquisition')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.acquiring = True
                self.start_acq.connect(self.worker.acquire)
                self.start_acq.emit('start!')

            self.action_Acq.setEnabled(False)
            self.action_Record.setChecked(False)
            self.action_Record.setEnabled(True)

            record_icon = self.style().standardIcon(QStyle.SP_DialogYesButton)
            #set the icon for the action
            self.action_Record.setIcon(record_icon)

    def Record(self):

        if self.action_Record.isChecked():

            if not self.acquiring:
                self.workerThread = QThread(self)
                self.workerThread.start()

                self.worker = Worker(self)
                self.worker.moveToThread(self.workerThread)

                try:
                    self.start_rec.disconnect()
                except:
                    pass

                while 1:
                    try:
                        self.sock.send('StartAcquisition')
                        self.sock.recv()
                    except:
                        continue
                    break

                while 1:
                    try:
                        self.sock.send('StartRecord')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.vidbuffer = []
                self.start_rec.connect(self.worker.acquire)
                self.recording = True
                self.start_rec.emit('start!')

            else:

                while 1:
                    try:
                        self.sock.send('StartRecord')
                        self.sock.recv()
                    except:
                        continue
                    break

                self.vidbuffer = []
                self.recording = True

            record_icon = self.style().standardIcon(QStyle.SP_DialogNoButton)
            #set the icon for the action
            self.action_Record.setIcon(record_icon)
            self.action_Record.setEnabled(False)

            self.action_Acq.setChecked(False)
            self.action_Acq.setEnabled(True)

    def Stop(self):

        self.acquiring = False
        self.recording = False

        while 1:
            try:
                self.sock.send('isRecording')
                rec = self.sock.recv()
            except:
                continue
            break

        if rec == '1':
            while 1:
                try:
                    self.sock.send('StopRecord')
                    self.sock.recv()
                except:
                    continue
                break

            self.action_Record.setEnabled(True)
            self.action_Record.setChecked(False)

        while 1:
            try:
                self.sock.send('isAcquiring')
                acq = self.sock.recv_string()
            except:
                continue
            break

        if acq == '1':
            while 1:
                try:
                    self.sock.send('StopAcquisition')
                    self.sock.recv()
                except:
                    continue
                break

        self.action_Acq.setEnabled(True)
        self.action_Acq.setChecked(False)

        try:
            #open a csv file for saving tracking data
            with open(self.vt_file, 'a') as csvfile:
                #create a writer
                vidwriter = csv.writer(csvfile, dialect='excel-tab')
                #check if it's an empty file
                for row in self.vidbuffer:
                    vidwriter.writerow(row)

        except:
            pass

        record_icon = self.style().standardIcon(QStyle.SP_DialogYesButton)
        #set the icon for the action
        self.action_Record.setIcon(record_icon)

    def update_frame(self, image):
        self.raw_label.setPixmap(QPixmap.fromImage(image))

    def update_threshed(self, threshed_image):
        self.threshed_label.setPixmap(QPixmap.fromImage(threshed_image))

    def clear_threshed(self):
        self.green_frame = np.zeros_like(self.green_frame)
        self.red_frame = np.zeros_like(self.red_frame)

    def overlay_threshed(self):
        if self.overlay:
            self.overlay = False
        elif not self.overlay:
            self.overlay = True


#    def sort_now(self):
#
#        if self.recdir is not None:
#            os.chdir('./kilosort_control')
#            #create and show the main window
#            self.sort_frame = kilosort_control.sort_gui.MainWindow()
#            self.sort_frame.show()
#
#            #set up stream for stdout and stderr based on outputStream class
#            self.outputStream = kilosort_control.sort_gui.outputStream()
#            #when outputStream sends messages, connect to appropriate function for
#            #writing to terminal window
#            self.outputStream.message.connect(self.sort_frame.print_message)
#
#            #connect stdout and stderr to outputStream
#            sys.stdout = self.outputStream
#            sys.stderr = self.outputStream
#
#            self.sort_frame.run_now(self.recdir)
#
#            self.close()

    def get_info(self):

        self.info_window = QWidget()
        self.info_window.resize(400, 350)
        #set title
        self.info_window.setWindowTitle('Session Info')
        #give layout
        info_layout = QVBoxLayout(self.info_window)

        with open('info_fields.pickle', 'rb') as f:
            default_fields = pickle.load(f)
            f.close()

        #set label for pic_resolution setting
        experimenter_label = QLabel('Experimenter:')
        #make a QLineEdit box for displaying/editing settings
        experimenter = QComboBox(self.info_window)
        experimenter.setEditable(True)
        experimenter.addItems(default_fields['experimenter'])
        #add label and box to current window
        info_layout.addWidget(experimenter_label)
        info_layout.addWidget(experimenter)

        #set label for pic_resolution setting
        whose_animal_label = QLabel('Whose animal?')
        #make a QLineEdit box for displaying/editing settings
        whose_animal = QComboBox(self.info_window)
        whose_animal.setEditable(True)
        whose_animal.addItems(default_fields['whose_animal'])
        #add label and box to current window
        info_layout.addWidget(whose_animal_label)
        info_layout.addWidget(whose_animal)

        animal_number_label = QLabel('Animal number:')
        animal_number = QComboBox(self.info_window)
        animal_number.setEditable(True)
        animal_number.addItems(default_fields['animal_number'])
        info_layout.addWidget(animal_number_label)
        info_layout.addWidget(animal_number)

        session_number_label = QLabel('Session number:')
        session_number = QTextEdit(self.info_window)
        session_number.setText('1')
        info_layout.addWidget(session_number_label)
        info_layout.addWidget(session_number)

        session_type_label = QLabel('Session type:')
        session_type = QComboBox(self.info_window)
        session_type.setEditable(True)
        session_type.addItems(default_fields['session_type'])
        info_layout.addWidget(session_type_label)
        info_layout.addWidget(session_type)

        def save_info(self):

            info_fields = {}
            info_fields['experimenter'] = [
                experimenter.itemText(i) for i in range(experimenter.count())
            ]
            info_fields['whose_animal'] = [
                whose_animal.itemText(i) for i in range(whose_animal.count())
            ]
            info_fields['animal_number'] = [
                animal_number.itemText(i) for i in range(animal_number.count())
            ]
            info_fields['session_type'] = [
                session_type.itemText(i) for i in range(session_type.count())
            ]

            with open('info_fields.pickle', 'wb') as f:
                pickle.dump(info_fields, f, protocol=2)
                f.close()

            current_experimenter = str(experimenter.currentText())
            current_whose_animal = str(whose_animal.currentText())
            current_animal_number = str(animal_number.currentText())
            current_session_number = str(session_number.toPlainText())
            current_session_type = str(session_type.currentText())

            recdir = data_save_dir + current_whose_animal + '/' + current_animal_number

            if not os.path.exists(recdir):
                os.makedirs(recdir)

            self.experiment_info = '###### Experiment Info ######\r\n'
            self.experiment_info += 'Experimenter: %s\r\n' % current_experimenter
            self.experiment_info += 'Whose animal? %s\r\n' % current_whose_animal
            self.experiment_info += 'Animal number: %s\r\n' % current_animal_number
            self.experiment_info += 'Session number: %s\r\n' % current_session_number
            self.experiment_info += 'Session type: %s\r\n' % current_session_type

            self.experiment_info = self.experiment_info.encode()

            config_file = config_path + '/' + current_animal_number + '.xml'

            if not os.path.exists(config_file):
                shutil.copy(default_config, config_file)

            tree = et.parse(config_file)
            root = tree.getroot()
            for child in root:
                if child.tag == 'CONTROLPANEL':
                    child.attrib['recordPath'] = recdir.replace('/', '\\')
            tree.write(config_file)
            tree.write(default_config)

            self.info_window.close()
            self.noinfo = False

        ready_button = QPushButton('Ready!')
        ready_button.clicked.connect(lambda: save_info(self))
        info_layout.addWidget(ready_button)

        self.info_window.show()
Ejemplo n.º 21
0
class MainWindow(QMainWindow, Ui_MainWindow):

    add_name_signal = Signal(unicode)

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        # Create the name manager instance and move it to another thread.
        # This will cause all the slots to be run in that other thread
        # instead of our GUI thread.
        self.name_manager = NameManager()
        self.name_manager_thread = QThread()
        self.name_manager.moveToThread(self.name_manager_thread)
        self.name_manager_thread.start()

        # Create our network manager
        self.network_manager = NetworkManager()

        # When the name manager emits it's full name list, we want to
        # repopulate our list.
        self.name_manager.names_signal.connect(self.populate_list)

        # When the restore list button is clicked, let the name manager
        # know we need all the names in long term storage
        self.restore_list_button.clicked.connect(self.name_manager.get_all_names)

        self.add_name_signal.connect(self.name_manager.store_name)
        self.add_name_signal.connect(self.cache_name)
        self.submit_button.clicked.connect(self.say_hello)
        self.clear_list_button.clicked.connect(self.clear_list)

    def clean_up(self):
        """
        You can't rely on __del__ properly closing down all your threads. So use
        a clean_up method that will be called manually.
        :return:
        """
        if hasattr(self, 'network_manager_thread'):
            self.network_manager.api.end_connection()
            self.network_manager.api.join()
            self.network_manager_thread.quit()

        self.name_manager_thread.quit()

    def start_api(self, ip, port):
        """
        Connect to an external API service which will send us names
        :param ip: IP address of server
        :param port: Port of service
        :return:
        """
        self.network_manager_thread = QThread()
        self.network_manager.moveToThread(self.network_manager_thread)
        self.network_manager.message_signal.connect(self.handle_message)
        self.network_manager_thread.start()

        self.network_manager.connect_signal.emit(ip, port)

    @Slot()
    def handle_message(self, message):
        """
        Handle incoming names from the API. We simply want to follow the
        established procedure to add a new name. So we just emit on that
        signal.
        :param message: String name
        :return:
        """
        self.add_name_signal.emit(message)

    @Slot()
    def say_hello(self):
        self.add_name_signal.emit(self.name_text.text())
        self.hello_label.setText(u"{} {}".format(GREETING, self.name_text.text()))
        self.name_text.setText('')

    @Slot()
    def cache_name(self, name):
        self.names_list.addItem(name)

    @Slot()
    def clear_list(self):
        self.names_list.clear()

    @Slot()
    def populate_list(self, names):
        """
        Clears and repopulates the list with the given list
        :param names: List of names
        :return:
        """
        self.clear_list()
        for name in names:
            self.names_list.addItem(name)
Ejemplo n.º 22
0
class SyncWindow(QMainWindow):
    """
    Application main window. This class is meant to handle
    every widget needed by the application, as well as other
    needed global objects and behavior.
    """
    
    failedLogIn = Signal()
    syncStarted = Signal()
    loginRequested = Signal((str, str,))
    statusChanged = Signal((str, str, int,))
    
    def __init__(self, parent=None):
        super(SyncWindow, self).__init__(parent)
        
        # Sets up several UI aspects
        self.tray = QSystemTrayIcon(self)
        self.tray.setIcon(QIcon(QPixmap(':/resources/icon.png')))
        self.tray.show()
        
        self.setStyleSheet('SyncWindow {background: white}')
        self.setWindowTitle('IQBox')
        self.setWindowIcon(QIcon(QPixmap(':/resources/logobar.png')))
        self.statusBar().setFont(View.labelsFont())
        self.syncThread = None
        
        # Initializes the window with a `LoginView` widget.
        self.loginView()
        
    def loginView(self):
        """
        Initializes a `LoginView` object and sets it up as the main window's
        central widget.
        """
        login = LoginView()
        
        login.login.connect(self.onLogin)
        self.failedLogIn.connect(login.onFailedLogIn)
        
        self.setCentralWidget(login)
        self.setFixedSize(login.size())
        self.statusBar().hide()
        
    def syncView(self):
        """
        Initializes a `SyncView` object and sets it up as the main window's
        central widget.
        """        
        
        syncview = SyncView()
        
        self.setCentralWidget(syncview)
        self.setFixedSize(syncview.size())
        self.statusBar().show()
       
        self.statusChanged.connect(syncview.status.setMessage)
        syncview.sync.connect(self.onSync)
        
    @Slot(str, str, str, bool)
    def onLogin(self, host, username, passwd, ssl):
        """
        Slot. Triggers a log in request to the server.
        
        :param host: Indicates the hostname of the FTP server
        :param username: Username to log in into the FTP server
        :param passwd: Password to log in into the FTP server
        :param ssl: Indicates whether the FTP needs SSL support
        """

        self.sync = Sync(host, ssl)
        self.syncStarted.connect(self.sync.initQueue)
        self.sync.server.downloadProgress.connect(self.onDownloadProgress)
        self.sync.server.uploadProgress.connect(self.onUploadProgress)
        self.sync.server.fileEvent.connect(self.onFileEvent)
        self.sync.server.badFilenameFound.connect(self.badNameWarning)
        self.sync.server.loginCompleted.connect(self.onLoginCompleted)
        self.sync.server.fileEventCompleted.connect(self.onFileEventCompleted)
        self.sync.server.ioError.connect(self.onIOError)
        # Added by Si
        self.sync.server.textStatus.connect(self.setStatus)
        
        self.sync.statusChanged.connect(self.setStatus)
        self.loginRequested.connect(self.sync.server.onLogin) 

        self.syncThread = QThread()
        self.sync.moveToThread(self.syncThread)
        self.syncThread.start()
    
        QApplication.instance().lastWindowClosed.connect(self.syncThread.quit)
        self.loginRequested.emit(username, passwd)

    @Slot(bool, str)
    def onLoginCompleted(self, ok, msg):
        if not ok:
            self.showMessageBox(msg)
            self.failedLogIn.emit()

        else:
            self.syncView()
                
    @Slot()
    def onFileEventCompleted(self):
        # Workaround because there's an exception
        # when there's a file IO error
        # Ideally it should be managed elsewhere
        # But I don't know the code intimately enough yet.
        try:
          self.currentFile
        except AttributeError:
          self.currentFile = ''
        
        self.statusChanged.emit('Completed', self.currentFile, 100)

    @Slot(str)
    def onSync(self, localdir):
        """
        Slot. Triggers a server checkout.
        
        :param localdir: Absolute local directory path where to keep the files
        """
        self.sync.setLocalDir(localdir)
        self.sync.local.ioError.connect(self.onIOError)
        self.syncStarted.emit()
        self.setStatus('Syncing')
    
    def showMessageBox(self, msg):
        warning = QMessageBox(self)
        warning.setFont(View.labelsFont())
        warning.setStyleSheet('QMessageBox {background: white}')
        warning.setWindowTitle("Error")
        warning.setText(msg)
        warning.setIcon(QMessageBox.Warning)
        warning.addButton("Ok", QMessageBox.AcceptRole).setFont(View.editsFont())
        warning.exec_()
            
        
    @Slot(int, int)
    def onProgress(self, action, total, progress):
        """
        Slot. Triggers download progress update in the UI.
        
        :param total: Total size of the download in bytes
        :param progress: Current downdload progress in bytes
        """
        
        if progress <= 0:
            return
        else:
            percent = (progress * 100) / total
            self.statusChanged.emit(action, self.currentFile, percent)
        
    @Slot(str)
    def setStatus(self, msg):
        self.statusChanged.emit(msg, '', 0)

    @Slot(int, int)
    def onDownloadProgress(self, total, progress):
        """
        Slot. Triggers upload progress update in the UI.
        
        :param total: Total size of the download in bytes
        :param progress: Current downdload progress in bytes
        """
        
        self.onProgress('Downloading', total, progress)
        
    @Slot(int, int)
    def onUploadProgress(self, total, progress):
        """
        Slot. Triggers download progress update in the UI.
        
        :param total: Total size of the download in bytes
        :param progress: Current downdload progress in bytes
        """
        
        self.onProgress('Uploading', total, progress)
        
    @Slot(str)
    def onFileEvent(self, filename):
        """
        Slot. Updates the current download filename to be used in the UI
        
        :param filename: Name of the file that is being downloaded
        """
        
        self.currentFile = filename
       
    @Slot(str)
    def onIOError(self, filename):
        self.showMessageBox('Error reading: "{}"'.format(filename))

    @Slot(str)
    def badNameWarning(self, filename):
        self.showMessageBox(
                'Will not sync "{}". Invalid filename'.format(filename))