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)
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()
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)
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()