示例#1
0
class QtCustomSlider(QtWidgets.QSlider):
    def __init__(self, parent):
        QtWidgets.QSlider.__init__(self)
        self.label = QLabel(self)
        self._qtTool = weakref.ref(parent)
        self.label.setFixedSize(QSize(20, 20))
        self.label.setAutoFillBackground(True)
        self.label.setAutoFillBackground(True)
        palette = QPalette()
        palette.setColor(QPalette.Background, Qt.white)
        self.label.setPalette(palette)
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setVisible(False)
        self.label.move(0, 3)
        self.setMaximum(100)
        self.setOrientation(Qt.Horizontal)
        self.setPageStep(0)

    @property
    def qtTool(self):
        return self._qtTool()

    def mousePressEvent(self, event):
        if not self.label.isVisible():
            self.label.setVisible(True)
        x = event.pos().x()
        pos = x / self.width()

        w = self.width()
        size = int(w * self.value() / (self.maximum()))
        x2 = self.sliderPosition()
        print(x, x2, w, size)

        if not (size - 5 <= x <= size + 5):
            self.setValue(int(pos * (self.maximum()) + self.minimum()))
            self.label.setText(str(self.value()))
            size = int((self.width() - self.label.width()) * self.value() /
                       (self.maximum()))
            self.label.move(size, 3)
        super(self.__class__, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if self.label.isVisible():
            self.label.setVisible(False)
            self.qtTool.SkipPicture()
        super(self.__class__, self).mouseReleaseEvent(event)

    def mouseMoveEvent(self, event):
        self.label.setText(str(self.value()))
        size = int((self.width() - self.label.width()) * self.value() /
                   (self.maximum() - self.minimum()))
        self.label.move(size, 3)
        super(self.__class__, self).mouseMoveEvent(event)

    def leaveEvent(self, event):
        super(self.__class__, self).leaveEvent(event)
示例#2
0
class ViewTeacherDeskLabel(QWidget):
    def __init__(self, text, bg_color):
        """
        Teacher's position in the class. Two possibilities: teacher's view are student's view.

        :param text: Label's text
        :type text: str
        :param bg_color: background color (when activated)
        :type bg_color: QColor
        """
        QWidget.__init__(self)

        self.setFixedSize(QSize(200, 30))

        self.label = QLabel(text)
        self.label.setToolTip(tr("perspective_tootip"))
        self.label.setStyleSheet(
            f"border-radius: 5px; background: {bg_color}; color: white;")
        self.label.setAlignment(Qt.AlignCenter)
        self.label.setFixedSize(QSize(200, 30))

        layout = QHBoxLayout()
        layout.setMargin(0)
        layout.addWidget(self.label)
        self.setLayout(layout)

    def set_label_visible(self, b_visible: bool):
        """
        Sets the visibility state of the label

        :param b_visible: True shows the label
        """
        self.label.setVisible(b_visible)

    def mousePressEvent(self, event):
        super().mousePressEvent(event)

        if self.label.isVisible():
            self.on_click()

    def on_click(self):
        pass
class Window(QWidget):
    def __init__(self, app, parent=None):

        print("Window init")

        super().__init__(parent)

        # self.win_event_filter = WinEventFilter("window")
        # self.installNativeEventFilter(self.win_event_filter)

        self.app = app

        self.window_size = QtCore.QSize(400, 250)
        self.window_size_offset = QtCore.QSize(0, 150)
        self.window_position = QtCore.QPoint(0, 0)
        self.window_position_offset = QtCore.QPoint(0, 0)

        # self.setWindowFlags(
        #    QtCore.Qt.Window |
        #    QtCore.Qt.CustomizeWindowHint |
        #    QtCore.Qt.WindowTitleHint |
        #    QtCore.Qt.WindowCloseButtonHint |
        #    QtCore.Qt.WindowStaysOnTopHint
        # )

        self.setWindowFlags(self.windowFlags() |
                            QtCore.Qt.FramelessWindowHint)
        self.setWindowFlags(self.windowFlags() |
                            QtCore.Qt.WindowStaysOnTopHint)

        self.setWindowFlags(
            QtCore.Qt.FramelessWindowHint |
            QtCore.Qt.WindowStaysOnTopHint |
            QtCore.Qt.Tool)
        # hlayout = QHBoxLayout()
        # hlayout.setMargin(0)
        # hlayout.setContentsMargins(0, 0, 0, 0)
        # hlayout.setSpacing(0)

        # buttonslayout = QVBoxLayout()

        self.labels = []

        self.menuButton = QPushButton(u"\U00002261")
        self.menuLabel = QLabel("Menu")
        myFontBold = self.menuLabel.font()
        myFontBold.setBold(True)
        # buttons
        myFont = self.menuButton.font()
        myFont2 = self.menuButton.font()
        if (myFont.pointSize() > 0):
            myFont.setPointSizeF(1.25 * myFont.pointSizeF())
            myFont2.setPointSizeF(1.4 * myFont.pointSizeF())
        else:
            myFont.setPixelSize(1.25 * myFont.pixelSize())
            myFont2.setPixelSize(1.4 * myFont.pixelSize())
        self.menuLabel.setFont(myFontBold)
        width = self.menuButton.fontMetrics().boundingRect("OO").width() + 7
        height = width  # okButton.height()
        self.menuButton.setFont(myFont2)
        self.menuButton.setMaximumWidth(width)
        self.menuButton.setMinimumWidth(width)
        self.menuButton.setFlat(True)
        self.menuButton.clicked.connect(self.menuPressed)

        mainButton = QPushButton(u"\U0000239A")
        mainLabel = QLabel("Main")
        width = mainButton.fontMetrics().boundingRect("OO").width() + 7
        height = width  # okButton.height()
        mainButton.setFont(myFont2)
        mainButton.setMaximumWidth(width)
        mainButton.setMinimumWidth(width)
        mainButton.clicked.connect(self.main)
        mainButton.setFlat(True)
        setupButton = QPushButton(u"\U0001F527")
        setupLabel = QLabel("Setup")
        setupButton.setFont(myFont)
        setupButton.setFlat(True)
        setupButton.setMaximumWidth(width)
        setupButton.setMinimumWidth(width)
        setupButton.clicked.connect(self.setup)

        identifyButton = QPushButton(u"\U00002755")
        identifyLabel = QLabel("Identify")
        identifyButton.setFont(myFont)
        identifyButton.setFlat(True)
        identifyButton.setMaximumWidth(width)
        identifyButton.setMinimumWidth(width)
        identifyButton.clicked.connect(self.identify)

        self.refreshButton = QPushButton(u"\U000021BB")
        self.refreshLabel = QLabel("Detect")
        self.refreshButton.setFont(myFont)
        self.refreshButton.setFlat(True)
        self.refreshButton.setMaximumWidth(width)
        self.refreshButton.setMinimumWidth(width)
        self.refreshButton.clicked.connect(self.refreshPressed)

        aboutButton = QPushButton(u"\U00002754")
        aboutLabel = QLabel("About")
        aboutButton.setFont(myFont)
        aboutButton.setFlat(True)
        aboutButton.setMaximumWidth(width)
        aboutButton.setMinimumWidth(width)
        aboutButton.clicked.connect(self.about)

        # closeButton = QPushButton(u"\U00002573")
        closeButton = QPushButton(u"\U000026CC")
        closeLabel = QLabel("Close")
        closeButton.setFont(myFont)
        closeButton.setFlat(True)
        closeButton.setMaximumWidth(width)
        closeButton.setMinimumWidth(width)
        closeButton.clicked.connect(self.close_)

        buttongrid = QGridLayout()
        buttongrid.addWidget(self.menuButton, 0, 0)
        buttongrid.addWidget(mainButton, 1, 0)
        buttongrid.addWidget(setupButton, 2, 0)
        buttongrid.addWidget(self.refreshButton, 3, 0)
        buttongrid.addWidget(identifyButton, 4, 0)
        buttongrid.addWidget(aboutButton, 6, 0)
        buttongrid.addWidget(closeButton, 7, 0)

        buttongrid.addWidget(self.menuLabel, 0, 1)
        buttongrid.addWidget(mainLabel, 1, 1)
        buttongrid.addWidget(setupLabel, 2, 1)
        buttongrid.addWidget(self.refreshLabel, 3, 1)
        buttongrid.addWidget(identifyLabel, 4, 1)
        buttongrid.addWidget(aboutLabel, 6, 1)
        buttongrid.addWidget(closeLabel, 7, 1)
        self.labels.append(self.menuLabel)
        self.labels.append(mainLabel)
        self.labels.append(setupLabel)
        self.labels.append(self.refreshLabel)
        self.labels.append(identifyLabel)
        self.labels.append(aboutLabel)
        self.labels.append(closeLabel)
        self.menuLabel .mousePressEvent = self.menuLabelPressed
        mainLabel .mousePressEvent = self.mainLabel
        setupLabel.mousePressEvent = self.setupLabel
        self.refreshLabel.mousePressEvent = self.refreshLabelPressed
        identifyLabel.mousePressEvent = self.identifyLabel
        aboutLabel.mousePressEvent = self.aboutLabel
        closeLabel.mousePressEvent = self.closeLabel

        buttongrid.setRowStretch(0, 0)
        buttongrid.setRowStretch(1, 0)
        buttongrid.setRowStretch(2, 0)
        buttongrid.setRowStretch(3, 0)
        buttongrid.setRowStretch(4, 0)
        buttongrid.setRowStretch(5, 1)
        buttongrid.setRowStretch(6, 0)
        buttongrid.setRowStretch(7, 0)
        self.labels_set_visible(False)

        self.layout = QHBoxLayout()

        # buttonslayout.addWidget(mainButton)
        # buttonslayout.addWidget(setupButton)
        # buttonslayout.addStretch(1)
        # buttonslayout.addWidget(aboutButton)
        # hlayout.addLayout(buttonslayout)
        # hlayout.addLayout(buttongrid)

        # grid.addLayout(hlayout, 1, 1)
        buttongrid.setSpacing(0)

        self.layout.addLayout(buttongrid)

        self.body_layout = QVBoxLayout()
        self.body_layout.setContentsMargins(0, 0, 0, 1)
        self.body_layout.setSpacing(0)

        self.title_layout = QHBoxLayout()
        self.title_layout.setContentsMargins(0, 0, 0, 0)
        self.title_layout.setSpacing(0)
        self.titleLabel = QLabel("Monitor Control")
        self.titleLabel.setWordWrap(True)
        self.titleLabel.setSizeIncrement(10, 10)
        myFont = self.titleLabel.font()
        myFont.setBold(True)
        self.titleLabel.setFont(myFont)
        width = self.titleLabel.fontMetrics().boundingRect("OO").width() + 7
        height = width  # okButton.height()
        self.titleLabel.mousePressEvent = self.mainLabel

        self.backButton = QPushButton(u"\U00002190", self)
        myFont = self.backButton.font()
        myFont.setBold(True)
        self.backButton.setFont(myFont)
        self.backButton.setMaximumWidth(width)
        self.backButton.setMinimumWidth(width)
        self.backButton.setFlat(True)
        self.backButton.clicked.connect(self.main)
        self.titleLabel.setMinimumHeight(self.backButton.height())

        self.title_layout.addWidget(self.backButton, 0, QtCore.Qt.AlignVCenter)
        self.title_layout.addSpacing(20)
        self.title_layout.addWidget(self.titleLabel, 1, QtCore.Qt.AlignVCenter)
        # self.backButton.setAlignment(Qt.AlignTop)
        self.title_layout.setAlignment(QtCore.Qt.AlignTop)

        self.body_layout.addLayout(self.title_layout)

        self.main_frame = QtWidgets.QFrame(self)
        self.main_layout = QVBoxLayout()
        self.feature_brightness = FeatureWidget(
            self.main_frame, "Brightness", self.app.brightness)
        self.feature_contrast = FeatureWidget(
            self.main_frame, "Contrast", self.app.contrast)
        self.main_layout.addWidget(self.feature_brightness)
        self.main_layout.addWidget(self.feature_contrast)
        self.main_layout.addStretch(1)
        self.main_frame.setLayout(self.main_layout)
        self.main_frame.hide()
        self.body_layout.addWidget(self.main_frame, 1)

        self.setup_frame = QtWidgets.QFrame(self)

        leftButton = QPushButton("<", self.setup_frame)
        width = leftButton.fontMetrics().boundingRect("<").width() + 7
        leftButton.setFlat(True)
        leftButton.setMaximumWidth(width)
        leftButton.setMinimumWidth(width)
        leftButton.setSizePolicy(QtWidgets.QSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.Expanding))

        self.setup_layout = QHBoxLayout()
        self.setup_layout.addWidget(leftButton)
        self.feature_setup_widget = FeatureSetupWidget(
            self.app, self.setup_frame)
        # hlayout.addWidget(self.feature_setup_widget, 1)
        self.feature_setup_widget.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding)
        rightButton = QPushButton(">", self.setup_frame)
        rightButton.setFlat(True)
        rightButton.setMaximumWidth(width)
        rightButton.setMinimumWidth(width)
        rightButton.setSizePolicy(QtWidgets.QSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.Expanding))
        self.setup_layout.addWidget(self.feature_setup_widget, 1)
        self.setup_layout.addWidget(rightButton)
        self.setup_layout.setContentsMargins(0, 0, 0, 0)
        self.setup_layout.setSpacing(0)
        leftButton.clicked.connect(self.feature_setup_widget.previous)
        rightButton.clicked.connect(self.feature_setup_widget.next)

        self.setup_frame.setLayout(self.setup_layout)

        # self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(10)
        self.body_layout.addWidget(self.setup_frame, 1)

        self.layout.addLayout(self.body_layout, 1)

        self.about_frame = QtWidgets.QFrame(self)
        self.about_layout = QVBoxLayout()
        self.aboutLabel1 = QLabel("About", self.about_frame)
        self.aboutLabel1.setWordWrap(True)
        myFont = self.aboutLabel1.font()
        myFont.setBold(True)
        self.aboutLabel1.setFont(myFont)
        about = "©️ ™️ Juno\n\nMonitor Control synchronizes your monitor hardware properties like brightness and contrast.\nThese properties can be changed by the software sliders, or monitor buttons. These changes are monitored and read, and subsequently set to the other monitors using a calibration. This will ensure an input change has the same result on all monitors.\n"
        self.aboutLabel2 = QLabel("{}".format(about), self.about_frame)
        self.aboutLabel2.setAlignment(
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
        self.aboutLabel2.setWordWrap(True)
        self.about_layout.addWidget(self.aboutLabel1)
        self.about_layout.addWidget(self.aboutLabel2, 1)
        self.about_frame.setLayout(self.about_layout)
        self.about_frame.hide()
        self.body_layout.addWidget(self.about_frame, 1)

        # self.layout.setSizeConstraint(QtGui.QLayout.setFixedSize)

        self.setLayout(self.layout)

        self.setWindowIcon(QtGui.QIcon('artifacts/icon.png'))
        # set the title
        self.setWindowTitle("Monitors Control")

        self.main()

        self.setFixedSize(400, 250)

    def labels_set_visible(self, visible):
        for label in self.labels:
            if (self.refreshLabel == label) and visible:
                self.refreshLabel.setVisible(self.refreshButton.isVisible())
            else:
                label.setVisible(visible)

    def refresh_visible(self, visible):
        if (visible):
            self.refreshButton.setVisible(visible)
            self.refreshLabel.setVisible(self.menuLabel.isVisible())
        else:
            self.refreshLabel.setVisible(visible)
            self.refreshButton.setVisible(visible)

    def focusOutEvent(self, event):
        print('Lost focus')

    def menuLabelPressed(self, event):
        self.menuPressed()

    def menuPressed(self):
        print("Menu")
        self.labels_set_visible(not self.labels[0].isVisible())

    def aboutLabel(self, event):
        self.about()

    def about(self):
        print("About")
        self.setupUpdate()

        self.setMinimumSize(200, 130)

        # self.feature_setup_widget.hide()
        self.setup_frame.hide()
        self.main_frame.hide()
        self.refresh_visible(False)
        self.backButton.show()
        self.about_frame.show()

        self.move(self.window_position)
        self.setFixedSize(self.window_size)

    def closeLabel(self, event):
        self.close_()

    def close_(self):
        print("Close {}".format(len(self.app.identifyWindows)))
        self.setupUpdate()
        if (len(self.app.identifyWindows) == 0):
            self.hide()

    def setupLabel(self, event):
        self.setup()

    def setup(self):
        print("Setup")
        self.move(self.window_position + self.window_position_offset)
        self.setFixedSize(self.window_size + self.window_size_offset)

        self.app.monitors._calibrations.loadYaml()

        self.feature_setup_widget.init()
        self.backButton.show()

        self.main_frame.hide()
        self.about_frame.hide()
        self.refresh_visible(True)
        self.setup_frame.show()

        self.setMinimumSize(200, 130)

    def setupUpdate(self):
        if (self.setup_frame.isVisible()):
            self.app.monitors._calibrations.saveYaml()

    def mainLabel(self, event):
        self.main()

    def main(self):
        print("Main")

        self.setMinimumSize(200, 130)
        self.setupUpdate()

        self.refresh_visible(False)
        self.backButton.hide()
        # self.feature_setup_widget.hide()
        self.setup_frame.hide()
        self.about_frame.hide()
        self.main_frame.hide()

        self.move(self.window_position)
        self.setFixedSize(self.window_size)

        self.main_frame.show()

    def identifyLabel(self, event):
        self.identify()

    def identify(self):
        print("Identify")

        self.app.identify()

    def refreshLabelPressed(self, event):
        self.refreshPressed()

    def refreshPressed(self):
        QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        print("detect")
        self.feature_setup_widget.clear()
        self.app.detect()
        self.setup()
        self.feature_setup_widget.set_infos(self.app.monitors)
        self.feature_setup_widget.init()

        self.app.list_monitors()

        QApplication.restoreOverrideCursor()

    def position_show(self):
        print("position_show")
        self.app.position_next_to_tray()
        self.main()
        self.show()
        # self.requestActivate()
        # QtCore.Qt.ActiveWindowFocusReason
        self.activateWindow()
        self.setFocus(QtCore.Qt.PopupFocusReason)

    def contrast(self, value):
        # from gui
        self.app.contrast(value)

    def brightness(self, value):
        # from gui
        self.app.brightness(value)

    def set_contrast(self, value):
        # to gui
        self.feature_contrast.set_value(value)
        self.feature_setup_widget.set_contrast(value)

    def set_brightness(self, value):
        # to gui
        self.feature_brightness.set_value(value)
        self.feature_setup_widget.set_brightness(value)

    def show(self):
        # to gui
        value = self.app.monitors.get_contrast()
        if (value is not None):
            self.set_contrast(value)

        value = self.app.monitors.get_brightness()
        if (value is not None):
            self.set_brightness(value)

        self.feature_setup_widget.set_infos(self.app.monitors)

        super().show()
示例#4
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        #window setup
        resolution = QDesktopWidget().screenGeometry()
        self.screen_w = resolution.width()
        self.screen_h = resolution.height()
        self.setGeometry(0, 0, 650, 550)
        self.setWindowTitle('MARS_v1_8')
        self.setWindowIcon(QIcon('icons/mouse.png'))
        self.queue = Queue()
        self.queue_list = []
        self.str_proc = ''
        self.fname = ''

        #center window
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        #adjust size
        self.resize(self.screen_w / 2, self.screen_h / 2)
        self.Menu()
        self.Layout()

        central_widget = QWidget()
        central_widget.setLayout(self.main_layout)
        self.setCentralWidget(central_widget)

    def Menu(self):
        #this creates an action exit, a shortcut and status tip
        exitAction = QAction(QIcon('icons/exit.png'), '&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        openFile = QAction(QIcon('icons/open.png'), '&Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.triggered.connect(self.browse)

        runAction = QAction(QIcon('icons/run.png'), '&Run', self)
        runAction.setShortcut('Ctrl+R')
        runAction.setStatusTip('Run Mars')
        runAction.triggered.connect(self.run_event)

        resetAction = QAction(QIcon('icons/reset.png'), '&Reset', self)
        resetAction.setShortcut('Ctrl+X')
        resetAction.setStatusTip('Reset Mars')
        resetAction.triggered.connect(self.reset)

        #create status bar to show tooltip
        statusbar = QStatusBar(self)
        self.setStatusBar(statusbar)

        #create menu
        self.menu_File = QMenu('&File', self)
        self.menuBar().addMenu(self.menu_File)
        self.menu_File.addAction(openFile)
        self.menu_File.addAction(runAction)
        self.menu_File.addAction(resetAction)
        self.menu_File.addSeparator()
        self.menu_File.addAction(exitAction)

        #create toolbar
        self.toolbar = QToolBar("Toolbar", self)
        self.toolbar.addAction(openFile)
        self.toolbar.addAction(runAction)
        self.toolbar.addAction(resetAction)
        self.toolbar.addSeparator()
        # self.toolbar.move(5, 5)
        self.toolbar2 = QToolBar("ToolbarExit", self)
        self.toolbar2.addAction(exitAction)

        self.toto = QFrame(self)
        self.toto.setFrameShape(QFrame.HLine)
        self.toto.setFrameShadow(QFrame.Sunken)
        self.toto.setLineWidth(2)

    def Layout(self):
        #LAYOUT
        self.select_video = QLabel(self)
        self.select_video.setText("Folder Selected:")
        self.select_video.setVisible(False)

        self.browse_btn = QPushButton("Browse", self)
        self.browse_btn.setStatusTip(" Browse Folder")
        # self.browse_btn.setStyleSheet("background-color: rgb(186, 186, 186); border-radius: 15px;border-style: solid;border-width: 2px;border-color: black;");
        self.browse_btn.clicked.connect(self.browse)

        self.VideoName = QLabel(self)

        self.todo = QLabel(self)
        self.todo.setText("What do you want to do?")
        self.todo.setVisible(False)

        ## Various checkboxes for activities to perform within MARS.
        self.doPose = False
        self.pose_chbox = QCheckBox('[Pose]', self)
        self.pose_chbox.stateChanged.connect(self.checkDoPose)
        self.pose_chbox.setVisible(False)

        self.doFeats = False
        self.feat_chbox = QCheckBox('[Features]', self)
        self.feat_chbox.stateChanged.connect(self.checkDoFeat)
        self.feat_chbox.setVisible(False)

        self.doActions = False
        self.actions_chbox = QCheckBox('[Classify Actions]', self)
        self.actions_chbox.stateChanged.connect(self.checkDoActions)
        self.actions_chbox.setVisible(False)

        # self.ddlist_label = QLabel(self)
        # self.ddlist_label.setText("Classifier:")
        # self.ddlist_label.move(200, 150)
        # self.ddlist_label.resize(150, 30)
        # self.ddlist_label.setVisible(False)
        #
        # self.ddlist = QComboBox(self)
        # self.ddlist.setVisible(False)
        # self.ddlist.setStatusTip('Choose the classifier you\'d like to use.')
        # self.ddlist.move(220, 120)
        # self.ddlist.resize(150, 50)
        # self.ddlist.setSizeAdjustPolicy(QComboBox.AdjustToContents)

        self.doVideo = False
        self.video_chbox = QCheckBox('[Produce Video]', self)
        self.video_chbox.stateChanged.connect(self.checkDoVideo)
        self.video_chbox.setVisible(False)

        self.doOverwrite = False
        self.overwrite_chbox = QCheckBox('[Overwrite]', self)
        self.overwrite_chbox.setStyleSheet("background-color: #ff7a7a")
        self.overwrite_chbox.stateChanged.connect(self.checkDoOverwrite)
        self.overwrite_chbox.setVisible(False)

        ## Checkboxes that pick which view(s) to use, as well as the internal values they represent.
        self.doTop = False
        self.top_chbox = QCheckBox('[Top]', self)
        self.top_chbox.stateChanged.connect(self.checkDoTop)
        self.top_chbox.setVisible(False)

        self.doToppcf = False
        # self.toppcf_chbox = QCheckBox('[Top (w/ Front pixel features)]', self)
        # self.toppcf_chbox.stateChanged.connect(self.checkDoToppcf)
        # self.toppcf_chbox.setVisible(False)

        self.doFront = False
        self.front_chbox = QCheckBox('[Front]', self)
        self.front_chbox.stateChanged.connect(self.checkDoFront)
        self.front_chbox.setVisible(False)

        # Button to run MARS.
        self.run_mars = QPushButton("[Run MARS]", self)
        self.run_mars.setVisible(False)
        self.run_mars.setStatusTip('Run detection and actions classification')
        self.run_mars.setStyleSheet(
            "background-color: rgb(142, 229, 171); border-radius: 15px;")
        self.run_mars.clicked.connect(self.run_event)

        # Button to reset the form for MARS.
        self.reset_btn = QPushButton("[Reset]", self)
        self.reset_btn.setVisible(False)
        self.reset_btn.setStatusTip('Reset buttons')
        self.reset_btn.setStyleSheet(
            "background-color: rgb(229, 200, 142);border-radius: 15px")
        self.reset_btn.clicked.connect(self.reset)

        # Button for adding things to queue.
        self.add2queue_btn = QPushButton("[Enqueue]", self)
        self.add2queue_btn.setVisible(False)
        self.add2queue_btn.setStyleSheet(
            "background-color: rgb(216,191,216);border-radius: 50px")
        self.add2queue_btn.clicked.connect(self.addToQueue)

        self.progress = QLabel(self)
        self.progress.setVisible(True)

        # Progress bar above the global progress, shows the progress on the current task.
        self.progbar = QProgressBar(self)
        self.progbar.setStyleSheet(
            "background-color: #FFA07A; border: 3px solid #000000;")
        self.progbar.setVisible(True)
        self.progbar.setAlignment(QtCore.Qt.AlignCenter)
        # Label for progress bar.
        self.progbar_label = QLabel(self)
        self.progbar_label.setText("Current Task Progress:")

        # Big progress bar at the bottom. Global progress.
        self.big_progbar = QProgressBar(self)
        self.big_progbar.setVisible(True)
        self.big_progbar.setStyleSheet(
            "background-color: #add8e6; border: 3px solid #FFFFFF;")
        self.big_progbar.setAlignment(QtCore.Qt.AlignCenter)
        # Label for big progress bar.
        self.big_progbar_label = QLabel(self)
        self.big_progbar_label.setText("Global Video Progress:")

        # Layout for the browsing span.
        self.button_layout = QHBoxLayout()
        self.button_layout.addWidget(self.browse_btn)
        self.button_layout.addWidget(self.select_video)
        self.button_layout.addWidget(self.VideoName)
        self.button_layout.addWidget(self.add2queue_btn)
        self.button_layout.addStretch(0.5)

        # Layout for the menu at the top.
        self.menu_layout = QHBoxLayout()
        self.menu_layout.addWidget(self.toolbar)
        self.menu_layout.addStretch()
        self.menu_layout.addWidget(self.toolbar2)

        # Layout for the view selection (Top, Toppcf, Front)
        self.view_layout = QHBoxLayout()
        self.view_layout.addWidget(self.top_chbox)
        # self.view_layout.addWidget(self.toppcf_chbox)
        self.view_layout.addWidget(self.front_chbox)
        self.view_layout.addStretch()

        # Layout for the checkboxes.
        self.chbox_layout = QHBoxLayout()
        self.chbox_layout.setSpacing(10)
        self.chbox_layout.addWidget(self.pose_chbox)
        self.chbox_layout.addWidget(self.feat_chbox)
        self.chbox_layout.addWidget(self.actions_chbox)
        self.chbox_layout.addWidget(self.video_chbox)
        self.chbox_layout.addWidget(self.overwrite_chbox)
        self.chbox_layout.addStretch(1)

        # Layout for the activity buttons, RUN and RESET.
        self.active_layout = QHBoxLayout()
        self.active_layout.addWidget(self.run_mars, stretch=2)
        self.active_layout.addWidget(self.reset_btn, stretch=1)

        # # Layout for the task progress bar.
        # self.task_progbar_layout = QtGui.QHBoxLayout()
        # self.task_progbar_layout.addWidget(self.progbar_label)
        # self.task_progbar_layout.addWidget(self.progbar, stretch=1)
        #
        # # Layout for the global progress bar.
        # self.global_progbar_layout = QtGui.QHBoxLayout()
        # self.global_progbar_layout.addWidget(self.big_progbar_label)
        # self.global_progbar_layout.addWidget(self.big_progbar)

        # Layout for the labels, to get ther vertically-aligned.
        self.progbar_label_layout = QVBoxLayout()
        self.progbar_label_layout.addWidget(self.progbar_label)
        self.progbar_label_layout.addWidget(self.big_progbar_label)

        # Layout for the progress bars themselves, to get them vertically-aligned.
        self.progbar_bar_layout = QVBoxLayout()
        self.progbar_bar_layout.addWidget(self.progbar)
        self.progbar_bar_layout.addWidget(self.big_progbar)

        # Layout for the combined progress bars and labels.
        self.progbar_layout = QHBoxLayout()
        self.progbar_layout.addLayout(self.progbar_label_layout)
        self.progbar_layout.addLayout(self.progbar_bar_layout, stretch=1)

        # This layout puts everything on the screen.
        self.main_layout = QVBoxLayout()
        self.main_layout.addLayout(self.menu_layout)
        self.main_layout.addWidget(self.toto)
        self.main_layout.addLayout(self.button_layout)
        self.main_layout.addWidget(self.todo)
        self.main_layout.addLayout(self.view_layout)
        self.main_layout.addLayout(self.chbox_layout)
        self.main_layout.addLayout(self.active_layout)
        self.main_layout.addWidget(self.progress)

        self.main_layout.addStretch()
        self.main_layout.addLayout(self.progbar_layout)
#        self.main_layout.addLayout(self.task_progbar_layout)
#        self.main_layout.addLayout(self.global_progbar_layout)

    def addToQueue(self):
        self.queue.put(self.fname)
        self.queue_list.append(self.fname)
        barMsg = self.fname + " added to the list!\n"
        msg = barMsg
        self.updateProgess(barMsg, msg)

    def browse(self):
        # sender = self.sender()
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.Directory)
        dialog.setOption(QFileDialog.ShowDirsOnly)
        if os.path.exists(self.fname):
            dir_to_use = self.fname
        else:
            dir_to_use = os.path.curdir

        self.fname = dialog.getExistingDirectory(self, 'Choose Directory',
                                                 dir_to_use)
        self.statusBar().showMessage(self.fname + ' selected ')
        if os.path.exists(self.fname) and os.path.isdir(
                self.fname) and self.fname != '':
            files = os.listdir(self.fname)
            seq_files = [
                f for f in files if f.endswith('.seq') or f.endswith('.avi')
                or f.endswith('.mp4') or f.endswith('.mpg')
            ]
            self.vid_name = self.fname.split('/')[-1]
            #if len(seq_files) >= 2:
            self.VideoName.setText(self.fname)
            self.todo.setVisible(True)

            self.select_video.setVisible(True)
            self.add2queue_btn.setVisible(True)
            # self.ddlist_label.setVisible(True)
            # self.ddlist.setVisible(True)

            self.pose_chbox.setVisible(True)
            self.feat_chbox.setVisible(True)
            self.actions_chbox.setVisible(True)
            self.video_chbox.setVisible(True)

            self.front_chbox.setVisible(True)
            self.top_chbox.setVisible(True)
            # self.toppcf_chbox.setVisible(True)

            self.run_mars.setVisible(True)
            self.reset_btn.setVisible(True)
            self.overwrite_chbox.setVisible(True)
            #else:
            #    QMessageBox.information(self, "Not all needed files exists", "Select a folder containing .seq files!")
        else:
            QMessageBox.information(
                self, " Wrong file selected",
                "No compatible movie files found! Supported formats: .seq, .avi, .mp4, .mpg"
            )
            self.fname = dir_to_use

    def checkDoPose(self, state):
        self.doPose = (state == QtCore.Qt.Checked)

    def checkDoFeat(self, state):
        self.doFeats = (state == QtCore.Qt.Checked)

    def checkDoActions(self, state):
        self.doActions = (state == QtCore.Qt.Checked)

    def checkDoVideo(self, state):
        self.doVideo = (state == QtCore.Qt.Checked)

    def checkDoOverwrite(self, state):
        self.doOverwrite = (state == QtCore.Qt.Checked)

    def checkDoTop(self, state):
        self.doTop = (state == QtCore.Qt.Checked)
        # if self.doTop:
        #     self.ddlist.addItem("top mlp")
        #     self.ddlist.addItem("top xgb")
        #     self.ddlist.addItem("top mlp wnd")
        #     self.ddlist.addItem("top xgb wnd")
        # else:
        #     self.ddlist.clear()

    def checkDoToppcf(self, state):
        self.doToppcf = (state == QtCore.Qt.Checked)
        # if self.doToppcf:
        #     self.ddlist.addItem("top pcf mlp")
        #     self.ddlist.addItem("top pcf xgb")
        #     self.ddlist.addItem("top pcf mlp wnd")
        #     self.ddlist.addItem("top pcf xgb wnd")
        # else:
        #     self.ddlist.clear()

    def checkDoFront(self, state):
        self.doFront = (state == QtCore.Qt.Checked)
        # if self.doFront:
        #     self.ddlist.addItem("topfront mlp")
        #     self.ddlist.addItem("topfront xgb")
        #     self.ddlist.addItem("topfront mlp wnd")
        #     self.ddlist.addItem("topfront xgb wnd")
        # else:
        #     self.ddlist.clear()

    def reset(self):
        todo = [self.doPose, self.doFeats, self.doActions]
        # if not self.todo.isVisible() or  sum(todo)== 0:
        #     QMessageBox.information(self, "Reset", "Nothing to reset")
        # else:
        self.doPose = False
        self.doFeats = False
        self.doActions = False
        self.doVideo = False
        self.doOverwrite = False

        self.doFront = False
        self.doTop = False
        self.doToppcf = False

        self.pose_chbox.setCheckState(QtCore.Qt.Unchecked)
        self.feat_chbox.setCheckState(QtCore.Qt.Unchecked)
        self.actions_chbox.setCheckState(QtCore.Qt.Unchecked)
        self.video_chbox.setCheckState(QtCore.Qt.Unchecked)
        self.overwrite_chbox.setCheckState(QtCore.Qt.Unchecked)

        self.front_chbox.setCheckState(QtCore.Qt.Unchecked)
        self.top_chbox.setCheckState(QtCore.Qt.Unchecked)
        # self.toppcf_chbox.setCheckState(QtCore.Qt.Unchecked)

        self.str_proc = ''
        self.progress.setText(self.str_proc)

        self.VideoName.setText('')
        self.fname = ''

        self.statusBar().showMessage('')
        self.changeEnable_wdj(True)
        self.clearProgress()

    def changeEnable_wdj(self, b=False):
        self.run_mars.setEnabled(b)
        self.reset_btn.setEnabled(b)

        self.pose_chbox.setEnabled(b)
        self.feat_chbox.setEnabled(b)
        self.actions_chbox.setEnabled(b)
        self.video_chbox.setEnabled(b)
        self.overwrite_chbox.setEnabled(b)

        # self.add2queue_btn.setEnabled(b)
        # self.ddlist.setEnabled(b)

        self.front_chbox.setEnabled(b)
        self.top_chbox.setEnabled(b)
        # self.toppcf_chbox.setEnabled(b)

    # def stop_event(self):
    #     print('Stopped')
    #     # self.genericThread.stop()
    #     # self.genericThread.wait()
    #     self.statusBar().showMessage('Stopped processing')
    #     self.changeEnable_wdj(True)
    #     # self.stop_run.setVisible(False)

    def update_thread(self, prog):
        if prog == 1:
            print('Thread pose done')
        if prog == 2:
            print('Thread features done')
        if prog == 3:
            print('Thread actions done')
        if prog == 4:
            print('Thread video done')

    def thread_done(self):
        print('Thread ended')
        # self.changeEnable_wdj(True)
        # self.stop_run.setVisible(False)

    def queue_done(self):
        print('Queue ended')
        self.changeEnable_wdj(True)

    def updateProgess(self, barMsg, msg):
        self.statusBar().showMessage(barMsg)
        self.str_proc += msg
        self.progress.setText(self.str_proc)
        self.scrollText()

    def updateProgbar(self, value, set_max):
        if set_max != 0:
            self.progbar.setMaximum(set_max)
        self.progbar.setValue(value)

    def updateBigProgbar(self, value, set_max):
        if set_max != 0:
            self.big_progbar.setMaximum(set_max)
        self.big_progbar.setValue(value)

    def clearProgress(self):
        self.str_proc = 'Console cleared. \n'
        self.progress.setText(self.str_proc)
        self.resize(self.screen_w / 2, self.screen_h / 2)
        # self.adjustSize()
        # self.changeEnable_wdj(True)

    def scrollText(self):
        MAX_LINES = 20
        all_lines = self.str_proc.splitlines()
        if len(all_lines) > MAX_LINES:
            renewed_lines = all_lines[-MAX_LINES:]
            self.str_proc = '\n'.join(renewed_lines) + '\n'

    def run_event(self):
        todo = [self.doPose, self.doFeats, self.doActions, self.doVideo]
        if not self.todo.isVisible():
            QMessageBox.information(self, "Empty selection",
                                    "Select a folder to process.")
        elif sum(todo) == 0:
            QMessageBox.information(self, "Empty selection",
                                    "Select at least one task to do.")
        else:
            self.str_proc = ''
            self.progress.setVisible(True)
            self.genericThread = GenericThread(self.doPose, self.doFeats,
                                               self.doActions, self.doVideo,
                                               self.doOverwrite, self.doFront,
                                               self.doTop, self.doToppcf,
                                               self.queue, self.fname)
            self.genericThread.update_th.connect(self.update_thread)
            self.genericThread.done_th.connect(self.thread_done)
            self.genericThread.done_queue.connect(self.queue_done)

            self.genericThread.update_progbar_sig.connect(self.updateProgbar)
            self.genericThread.update_big_progbar_sig.connect(
                self.updateBigProgbar)
            self.genericThread.update_progress.connect(self.updateProgess)

            # self.genericThread.classifier_to_use = self.ddlist.currentText()
            self.genericThread.clear_sig.connect(self.clearProgress)

            self.genericThread.start()
            # self.stop_run.setVisible(True)
            self.changeEnable_wdj(False)
示例#5
0
class ScatterPlotMatrix(DataView):
    def __init__(self, workbench: WorkbenchModel, parent=None):
        super().__init__(workbench, parent)
        self.__frameModel: FrameModel = None

        # Create widget for the two tables
        sideLayout = QVBoxLayout()
        self.__matrixAttributes = SearchableAttributeTableWidget(
            self, True, False, False, [Types.Numeric, Types.Ordinal])
        matrixLabel = QLabel(
            'Select at least two numeric attributes and press \'Create chart\' to plot'
        )
        matrixLabel.setWordWrap(True)
        self.__createButton = QPushButton('Create chart', self)
        self.__colorByBox = QComboBox(self)
        self.__autoDownsample = QCheckBox('Auto downsample', self)
        self.__useOpenGL = QCheckBox('Use OpenGL', self)
        self.__autoDownsample.setToolTip(
            'If too many points are to be rendered, this will try\n'
            'to plot only a subsample, improving performance with\n'
            'zooming and panning, but increasing rendering time')
        self.__useOpenGL.setToolTip(
            'Enforce usage of GPU acceleration to render charts.\n'
            'It is still an experimental feature but should speed\n'
            'up rendering with huge set of points')

        # Layout for checkboxes
        optionsLayout = QHBoxLayout()
        optionsLayout.addWidget(self.__autoDownsample, 0, Qt.AlignRight)
        optionsLayout.addWidget(self.__useOpenGL, 0, Qt.AlignRight)

        sideLayout.addWidget(matrixLabel)
        sideLayout.addWidget(self.__matrixAttributes)
        sideLayout.addLayout(optionsLayout)
        sideLayout.addWidget(self.__colorByBox, 0, Qt.AlignBottom)
        sideLayout.addWidget(self.__createButton, 0, Qt.AlignBottom)
        self.__matrixLayout: pg.GraphicsLayoutWidget = pg.GraphicsLayoutWidget(
        )
        self.__layout = QHBoxLayout(self)
        self.__comboModel = AttributeProxyModel(
            [Types.String, Types.Ordinal, Types.Nominal], self)

        # Error label to signal errors
        self.errorLabel = QLabel(self)
        self.errorLabel.setWordWrap(True)
        sideLayout.addWidget(self.errorLabel)
        self.errorLabel.hide()

        self.__splitter = QSplitter(self)
        sideWidget = QWidget(self)
        sideWidget.setLayout(sideLayout)
        # chartWidget.setMinimumWidth(300)
        self.__splitter.addWidget(self.__matrixLayout)
        self.__splitter.addWidget(sideWidget)
        self.__splitter.setSizes([600, 300])
        self.__layout.addWidget(self.__splitter)
        self.__splitter.setSizePolicy(QSizePolicy.MinimumExpanding,
                                      QSizePolicy.MinimumExpanding)
        # Connect
        self.__createButton.clicked.connect(self.showScatterPlots)

        self.spinner = QtWaitingSpinner(self.__matrixLayout)

    @Slot()
    def showScatterPlots(self) -> None:
        self.__createButton.setDisabled(True)
        # Create plot with selected attributes
        attributes: Set[int] = self.__matrixAttributes.model().checked
        if len(attributes) < 2:
            self.errorLabel.setText('Select at least 2 attributes')
            self.errorLabel.setStyleSheet('color: red')
            self.errorLabel.show()
            return  # stop
        elif self.errorLabel.isVisible():
            self.errorLabel.hide()
        # Get index of groupBy Attribute
        group: int = None
        selectedIndex = self.__colorByBox.currentIndex()
        if self.__comboModel.rowCount() > 0 and selectedIndex != -1:
            index: QModelIndex = self.__comboModel.mapToSource(
                self.__comboModel.index(selectedIndex, 0, QModelIndex()))
            group = index.row() if index.isValid() else None

        # Create a new matrix layout and delete the old one
        matrix = GraphicsPlotLayout(parent=self)
        self.spinner = QtWaitingSpinner(matrix)
        oldM = self.__splitter.replaceWidget(0, matrix)
        self.__matrixLayout = matrix
        safeDelete(oldM)
        matrix.useOpenGL(self.__useOpenGL.isChecked())
        matrix.show()

        # Get attributes of interest
        toKeep: List[int] = list(attributes) if group is None else [
            group, *attributes
        ]
        filterDf = self.__frameModel.frame.getRawFrame().iloc[:, toKeep]
        # Create a worker to create scatter-plots on different thread
        worker = Worker(ProcessDataframe(), (filterDf, group, attributes))

        worker.signals.result.connect(self.__createPlots)
        # No need to deal with error/finished signals since there is nothing to do
        worker.setAutoDelete(True)
        self.spinner.start()
        QThreadPool.globalInstance().start(worker)

    def resetScatterPlotMatrix(self) -> None:
        # Create a new matrix layout
        matrix = pg.GraphicsLayoutWidget(parent=self)
        self.spinner = QtWaitingSpinner(matrix)
        oldM = self.__splitter.replaceWidget(0, matrix)
        self.__matrixLayout = matrix
        safeDelete(oldM)
        matrix.show()

    @Slot(object, object)
    def __createPlots(
            self, _, result: Tuple[pd.DataFrame, List[str], List[int],
                                   bool]) -> None:
        """ Create plots and render all graphic items """
        # Unpack results
        df, names, attributes, grouped = result

        # Populate the matrix
        for r in range(len(attributes)):
            for c in range(len(attributes)):
                if r == c:
                    name: str = names[r]
                    self.__matrixLayout.addLabel(row=r, col=c, text=name)
                else:
                    xColName: str = names[c]
                    yColName: str = names[r]
                    seriesList = self.__createScatterSeries(
                        df=df,
                        xCol=xColName,
                        yCol=yColName,
                        groupBy=grouped,
                        ds=self.__autoDownsample.isChecked())
                    plot = self.__matrixLayout.addPlot(row=r, col=c)
                    for series in seriesList:
                        plot.addItem(series)
                    # Coordinates and data for later use
                    plot.row = r
                    plot.col = c
                    plot.xName = xColName
                    plot.yName = yColName
        # When all plot are created stop spinner and re-enable button
        self.spinner.stop()
        self.__createButton.setEnabled(True)

    @staticmethod
    def __createScatterSeries(df: Union[pd.DataFrame,
                                        pd.core.groupby.DataFrameGroupBy],
                              xCol: str, yCol: str, groupBy: bool,
                              ds: bool) -> List[pg.PlotDataItem]:
        """
        Creates a list of series of points to be plotted in the scatterplot

        :param df: the input dataframe
        :param xCol: name of the feature to use as x-axis
        :param yCol: name of the feature to use as y-axis
        :param groupBy: whether the feature dataframe is grouped by some attribute
        :param ds: whether to auto downsample the set of points during rendering

        :return:

        """
        allSeries = list()
        if groupBy:
            df: pd.core.groupby.DataFrameGroupBy
            colours = randomColors(len(df))
            i = 0
            for groupName, groupedDf in df:
                # Remove any row with nan values
                gdf = groupedDf.dropna()
                qSeries1 = pg.PlotDataItem(x=gdf[xCol],
                                           y=gdf[yCol],
                                           autoDownsample=ds,
                                           name=str(groupName),
                                           symbolBrush=pg.mkBrush(colours[i]),
                                           symbol='o',
                                           pen=None)
                allSeries.append(qSeries1)
                i += 1
        else:
            df: pd.DataFrame
            # Remove any row with nan values
            df = df.dropna()
            series = pg.PlotDataItem(x=df[xCol],
                                     y=df[yCol],
                                     autoDownsample=ds,
                                     symbol='o',
                                     pen=None)
            allSeries.append(series)
        return allSeries

    @Slot(str, str)
    def onFrameSelectionChanged(self, frameName: str, *_) -> None:
        if not frameName:
            return
        self.__frameModel = self._workbench.getDataframeModelByName(frameName)
        self.__matrixAttributes.setSourceFrameModel(self.__frameModel)
        # Combo box
        attributes = AttributeTableModel(self, False, False, False)
        attributes.setFrameModel(self.__frameModel)
        oldModel = self.__comboModel.sourceModel()
        self.__comboModel.setSourceModel(attributes)
        if oldModel:
            oldModel.deleteLater()
        self.__colorByBox.setModel(self.__comboModel)
        # Reset attribute panel
        self.resetScatterPlotMatrix()