class Toggle: def __init__(self, checked_state, unchecked_state, is_default_checked): self.checked_state = checked_state self.unchecked_state = unchecked_state # Select default state self.default_state = unchecked_state if is_default_checked: self.default_state = checked_state self.widget = QPushButton(self.default_state.text) self.widget.setFixedWidth(50) self.widget.setFixedHeight(20) self.widget.setCheckable(True) self.widget.setStyleSheet("QPushButton{background-color: " + unchecked_state.color + ";} \ QPushButton{background-color: " + unchecked_state.color + ";} \ QPushButton{font-weight: bold;} \ QPushButton{border: none;} \ QPushButton:checked{background-color: " + checked_state.color + ";} \ QPushButton:focus{border:none; }") self.widget.setChecked(is_default_checked) self.widget.toggled.connect(lambda: self.onToggle(self.widget)) self.widget.isChecked() def getWidget(self): return self.widget def onToggle(self, instance): text = self.unchecked_state.text if instance.isChecked(): text = self.checked_state.text instance.setText(text)
def testBasic(self): '''QTest.mouseClick with QCheckBox''' button = QPushButton() button.setCheckable(True) button.setChecked(False) QTest.mouseClick(button, Qt.LeftButton) self.assert_(button.isChecked()) QTest.mouseClick(button, Qt.LeftButton) self.assertFalse(button.isChecked())
def testBasic(self): '''QTest.mouseClick with QCheckBox''' button = QPushButton() button.setCheckable(True) button.setChecked(False) QTest.mouseClick(button, Qt.LeftButton) self.assert_(button.isChecked()) QTest.mouseClick(button, Qt.LeftButton) self.assertFalse(button.isChecked())
def testQPushButton(self): button = QPushButton() button.setCheckable(True) button.setChecked(False) QTest.mouseClick(button, Qt.LeftButton) self.assertTrue(button.isChecked()) QTest.mouseClick(button, Qt.LeftButton) self.assertFalse(button.isChecked()) QApplication.closeAllWindows()
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.button_is_checked = True self.setWindowTitle("My Application") self.button = QPushButton("Press me!") self.button.setCheckable(True) self.button.clicked.connect(self.the_button_was_clicked) self.button.clicked.connect(self.the_button_was_toggled) self.button.released.connect(self.the_button_was_released) self.button.setChecked(self.button_is_checked) self.setCentralWidget(self.button) def the_button_was_released(self): self.button_is_checked = self.button.isChecked() print(self.button_is_checked) def the_button_was_clicked(self): print("clicked") def the_button_was_toggled(self, checked): self.button_is_checked = checked print("Checked?", self.button_is_checked)
class GeoItem(TreeItemWidget): def __init__(self, name, parent=None): super(GeoItem, self).__init__(name, parent) self.parent = parent self.build_geo_ui() self.connect_signals() def build_geo_ui(self): # self.setMaximumHeight(85) self.item_wdg.setFrameStyle(QFrame.Raised | QFrame.StyledPanel) self.item_wdg.setStyleSheet( "QFrame { background-color: rgb(55,55,55);}") icon = QIcon() icon.addPixmap(QPixmap(':/nudgeDown.png'), QIcon.Normal, QIcon.On) icon.addPixmap(QPixmap(':/nudgeRight.png'), QIcon.Normal, QIcon.Off) self.expand_btn = QPushButton() self.expand_btn.setStyleSheet( "QPushButton#expand_btn:checked {background-color: green; border: none}" ) self.expand_btn.setStyleSheet("QPushButton { color:white; }\ QPushButton:checked { background-color: rgb(55,55, 55); border: none; }\ QPushButton:pressed { background-color: rgb(55,55, 55); border: none; }" ) #\ # QPushButton:hover{ background-color: grey; border-style: outset; }") self.expand_btn.setFlat(True) self.expand_btn.setIcon(icon) self.expand_btn.setCheckable(True) self.expand_btn.setChecked(True) self.expand_btn.setFixedWidth(25) self.expand_btn.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) self.item_lay.addWidget(self.expand_btn, 0, 0, 1, 1) pixmap = QPixmap(':/pickGeometryObj.png') icon_lbl = QLabel() icon_lbl.setMaximumWidth(18) icon_lbl.setPixmap(pixmap) self.item_lay.addWidget(icon_lbl, 0, 1, 1, 1) self.target_lbl = QLabel(self.name) self.item_lay.addWidget(self.target_lbl, 0, 2, 1, 1) # self.target_edt = QLineEdit(item_wdg) # self.target_edt.setMinimumWidth(180) # self.target_edt.setVisible(False) self.item_lay.setColumnStretch(3, 1) # self.view_buttons = DisplayButtons(self) # self.item_lay.addWidget(self.view_buttons, 0, 4, 1, 1) def connect_signals(self): self.expand_btn.toggled.connect(self.toggle_children) def toggle_children(self): state = self.expand_btn.isChecked() self.child_wdg.setVisible(state)
def testWithCppSlot(self): '''QMenuBar.addAction(id, object, slot)''' menubar = QMenuBar() widget = QPushButton() widget.setCheckable(True) widget.setChecked(False) action = menubar.addAction("Accounts", widget, SLOT("toggle()")) action.activate(QAction.Trigger) self.assertTrue(widget.isChecked())
def testWithCppSlot(self): '''QMenuBar.addAction(id, object, slot)''' menubar = QMenuBar() widget = QPushButton() widget.setCheckable(True) widget.setChecked(False) action = menubar.addAction("Accounts", widget, SLOT("toggle()")) action.activate(QAction.Trigger) self.assert_(widget.isChecked())
def __init__(self, text_off: str, text_on: str, parent_instance: QPushButton): super().__init__(parent_instance.icon(), parent_instance.text(), parent_instance.parent()) self.setCheckable(self._is_toggleable) self.setSizePolicy(parent_instance.sizePolicy()) self.state: bool = parent_instance.isChecked() self.text_on: str = text_on self.text_off: str = text_off self._update_text_for_button_state() self.toggled.connect(self._toggle_button)
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.btn = QPushButton("Push") self.btn.released.connect(self.btn_released) self.btn.setCheckable(True) self.setCentralWidget(self.btn) def btn_released(self): self.btn_checked = self.btn.isChecked() print(self.btn_checked)
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.button_is_checked = True self.setWindowTitle("My App") self.button = QPushButton("Press Me!") # <1> self.button.setCheckable(True) self.button.released.connect(self.the_button_was_released) # <2> self.button.setChecked(self.button_is_checked) # Set the central widget of the Window. self.setCentralWidget(self.button) def the_button_was_released(self): self.button_is_checked = self.button.isChecked() # <3> print(self.button_is_checked)
class QW_AnimCntrl(QWidget): updated_cadmshfem = Signal() def __init__(self, fem): super(QW_AnimCntrl, self).__init__() self.fem = fem self.tmr_stepTime = QTimer(self) self.tmr_stepTime.setSingleShot(False) self.tmr_stepTime.timeout.connect(self.stepTime) self.btn_Initialize = QPushButton("initialize") self.btn_Animate = QPushButton("animate") self.btn_Animate.setCheckable(True) self.btn_Animate.toggled.connect(self.btn_Animate_toggled) self.btn_Initialize.pressed.connect(self.btn_Initialize_pressed) self.hl = QHBoxLayout() self.hl.addWidget(self.btn_Initialize) self.hl.addWidget(self.btn_Animate) self.setLayout(self.hl) def btn_Animate_toggled(self): if self.btn_Animate.isChecked(): self.tmr_stepTime.start(30) else: self.tmr_stepTime.stop() def btn_Initialize_pressed(self): self.fem.initialize() self.updated_cadmshfem.emit() def stepTime(self): self.fem.step_time() self.updated_cadmshfem.emit()
class ToolBoxWidget(QWidget): ''' Class which creates a toolbox storing all available tools and handles text input ''' numberOfButtons = 4 textButtonName = 'textButton' markerButtonName = 'markerButton' okButtonName = 'okButton' cancelButtonName = 'cancelButton' items = IndexedOrderedDict() textInputFinished = Signal(int, int, int, bool, str) currentPageNumber = -1 currentX = -1 currentY = -1 editMode = editModes.none prevEditMode = editModes.none editModeChange = Signal(str) suggestUpdate = Signal() settingsChanged = Signal() editTextBox = False buttons = IndexedOrderedDict() def __init__(self, parent): ''' Creates the toolboxwidget as child of the window widget :param parent: Parent window widget. ''' QWidget.__init__(self, parent) self.initUI() def initUI(self): ''' Sets up major UI components ''' # Create a rectengle from teh given outer dimensions textBoxRect = self.rect() # Shrink it for matiching textBox size textBoxRect.adjust(+30, +30, -12, -12) buttonRect = self.rect() buttonRect.adjust(+29, +30, +15, -20) self.row1Left = buttonRect.topLeft() self.row1Right = buttonRect.topRight() self.row2Left = QPoint(self.row1Left.x(), self.row1Left.y() + 35) self.row2Right = QPoint(self.row1Right.x(), self.row1Right.y() + 35) self.row3Left = QPoint(self.row2Left.x(), self.row2Left.y() + 35) self.row3Right = QPoint(self.row2Right.x(), self.row2Right.y() + 35) self.bottomLeft = QPoint(buttonRect.topLeft().x(), buttonRect.topLeft().y() + 140) self.bottomRight = QPoint(self.row1Right.x(), self.row1Right.y() + 140) self.bottomMiddle = QPoint(self.row1Left.x() + 65, self.row1Right.y()) # We use a textEdit for making text boxes editable for user self.pTextEdit = QTextEdit(self) # Always enable line wrapping self.pTextEdit.setLineWrapMode(QTextEdit.WidgetWidth) self.pTextEdit.setAutoFormatting(QTextEdit.AutoAll) self.pTextEdit.setAcceptRichText(True) self.pTextEdit.setFontPointSize(10) self.pTextEdit.setPlaceholderText("Text Box Content") # Forward keypressevents from the textEdit to the parent toolBoxWidget self.keyPressEvent = self.pTextEdit.keyPressEvent self.keyReleaseEvent = self.pTextEdit.keyReleaseEvent # We need a layout to add the textBox to the toolBoxWidget widgetLayout = QGridLayout(self) widgetLayout.addWidget(self.pTextEdit) self.pTextEdit.setGeometry(textBoxRect) buttonSize = QSize(60, 30) # ----------------------------- # Toolbuttons # ----------------------------- self.textButton = QPushButton(self) self.textButton.setFixedSize(buttonSize) self.textButton.move(self.row1Right) self.textButton.setIcon(QIcon(":/assets/text.png")) self.textButton.setCheckable(True) self.buttons['textButton'] = self.textButton self.markerButton = QPushButton(self) self.markerButton.setFixedSize(buttonSize) self.markerButton.move(self.row1Left) self.markerButton.setIcon(QIcon(":/assets/marker.png")) self.markerButton.setCheckable(True) self.buttons['markerButton'] = self.markerButton self.freehandButton = QPushButton(self) self.freehandButton.setFixedSize(buttonSize) self.freehandButton.move(self.row2Left) self.freehandButton.setIcon(QIcon(":/assets/freehand.png")) self.freehandButton.setCheckable(True) self.buttons['freehandButton'] = self.freehandButton self.markdownButton = QPushButton(self) self.markdownButton.setFixedSize(buttonSize) self.markdownButton.move(self.row2Right) self.markdownButton.setIcon(QIcon(":/assets/markdown.png")) self.markdownButton.setCheckable(True) self.buttons['markdownButton'] = self.markdownButton self.formsButton = QPushButton(self) self.formsButton.setFixedSize(buttonSize) self.formsButton.move(self.row3Left) self.formsButton.setIcon(QIcon(":/assets/forms.png")) self.formsButton.setCheckable(True) self.buttons['formsButton'] = self.formsButton self.eraserButton = QPushButton(self) self.eraserButton.setFixedSize(buttonSize) self.eraserButton.move(self.row3Right) self.eraserButton.setIcon(QIcon(":/assets/eraser.png")) self.eraserButton.setCheckable(True) self.buttons['eraserButton'] = self.eraserButton self.okButton = QPushButton(self) self.okButton.setFixedSize(buttonSize) self.okButton.move(self.bottomLeft) self.okButton.setIcon(QIcon(":/assets/ok.png")) self.buttons['okButton'] = self.okButton self.cancelButton = QPushButton(self) self.cancelButton.setFixedSize(buttonSize) self.cancelButton.move(self.bottomRight) self.cancelButton.setIcon(QIcon(":/assets/cancel.png")) self.buttons['cancelButton'] = self.cancelButton self.deleteButton = QPushButton(self) self.deleteButton.setFixedSize(buttonSize) self.deleteButton.move(self.bottomRight) self.deleteButton.setIcon(QIcon(":/assets/delete.png")) self.buttons['deleteButton'] = self.deleteButton self.undoButton = QPushButton(self) self.undoButton.setFixedSize(buttonSize) self.undoButton.move(self.bottomLeft) self.undoButton.setIcon(QIcon(":/assets/undo.png")) self.buttons['undoButton'] = self.undoButton self.redoButton = QPushButton(self) self.redoButton.setFixedSize(buttonSize) self.redoButton.move(self.bottomRight) self.redoButton.setIcon(QIcon(":/assets/redo.png")) self.buttons['redoButton'] = self.redoButton # ----------------------------- # Preference Buttons # ----------------------------- self.sizeButton = QPushButton(self) self.sizeButton.setFixedSize(buttonSize) self.sizeButton.setIcon(QIcon(":/assets/size.png")) self.sizeButton.setCheckable(True) self.buttons['sizeButton'] = self.sizeButton self.colorButton = QPushButton(self) self.colorButton.setFixedSize(buttonSize) self.colorButton.setIcon(QIcon(":/assets/color.png")) self.colorButton.setCheckable(True) self.buttons['colorButton'] = self.colorButton # Set Shortcuts for the buttons self.textButton.setShortcut("Ctrl+T") self.markerButton.setShortcut("Ctrl+M") self.freehandButton.setShortcut("Ctrl+D") self.eraserButton.setShortcut("Ctrl+E") self.okButton.setShortcut("Ctrl+Return") self.cancelButton.setShortcut("Esc") self.deleteButton.setShortcut("Ctrl+Del") self.undoButton.setShortcut("Ctrl+Z") self.redoButton.setShortcut("Ctrl+Y") self.sizeButton.setShortcut("Ctrl+X") self.colorButton.setShortcut("Ctrl+L") # Connect Events for the buttons self.okButton.clicked.connect(self.handleOkButton) self.markerButton.clicked.connect(self.handleMarkerButton) self.textButton.clicked.connect(self.handleTextButton) self.formsButton.clicked.connect(self.handleFormsButton) self.freehandButton.clicked.connect(self.handleFreehandButton) self.eraserButton.clicked.connect(self.handleEraserButton) self.markdownButton.clicked.connect(self.handleMarkdownButton) self.cancelButton.clicked.connect(self.handleCancelButton) self.deleteButton.clicked.connect(self.handleDeleteButton) self.undoButton.clicked.connect(self.handleUndoButton) self.redoButton.clicked.connect(self.handleRedoButton) self.sizeButton.clicked.connect(self.handleSizeButton) self.colorButton.clicked.connect(self.handleColorButton) sliderSize = QSize(15, 140) self.slider = QSlider(Qt.Vertical, self) self.slider.setMinimum(50) self.slider.setMaximum(150) self.slider.setValue(100) self.slider.move(self.bottomMiddle) self.slider.setFixedSize(sliderSize) self.slider.setEnabled(False) self.slider.valueChanged.connect(self.handleSliderValueChange) self.slider.sliderReleased.connect(self.handleSliderValueChanged) self.slider.sliderMoved.connect(self.handleSliderDrag) self.setButtonState() def restoreDefaults(self): ''' Restores defaults for certain edit components ''' black = (0, 0, 0) yellow = (1, 1, 0) # restore defaults for better ux Preferences.updateKeyValue('freehandColor', tuple(map(lambda x: str(x), black))) Preferences.updateKeyValue('markerColor', tuple(map(lambda x: str(x), yellow))) Preferences.updateKeyValue('formColor', tuple(map(lambda x: str(x), black))) self.settingsChanged.emit() def paintEvent(self, event): ''' Overrides the default paint event to either draw a textBox or a toolBox ''' if self.editTextBox: # Draw the toolBoxShape self.drawRectShape(event) else: self.drawToolBoxShape(event) # Run the parent paint Event return QWidget.paintEvent(self, event) def drawToolBoxShape(self, paintEvent): ''' Draws the circular toolBox shape ''' outerCircleRect = self.rect() outerCircleRect.adjust(+OUTEROFFSETBOTTOM, +OUTEROFFSETTOP, -OUTEROFFSETBOTTOM, -OUTEROFFSETBOTTOM) topMiddle = (outerCircleRect.topRight() - outerCircleRect.topLeft() ) / 2 + outerCircleRect.topLeft() bottomMiddle = (outerCircleRect.bottomRight() - outerCircleRect. bottomLeft()) / 2 + outerCircleRect.bottomLeft() shapePainter = QPainter(self) shapePainter.setRenderHint(shapePainter.Antialiasing) # shapePainter.setPen(QPen(QColor(14,125,145), OUTERLINEWIDTH, Qt.SolidLine)) # shapePainter.drawArc(outerCircleRect, CIRCLE/2, CIRCLE/2) # shapePainter.setPen(QPen(QColor(14,125,145), 5, Qt.SolidLine)) # shapePainter.drawLine(topMiddle, bottomMiddle) if self.editMode == editModes.freehand: if Preferences.data['comboBoxThemeSelect'] == 0 and toBool( Preferences.data['radioButtonAffectsPDF']) == True: try: color = tuple( map(lambda x: (1 - float(x)) * 255, Preferences.data['freehandColor'])) except ValueError as identifier: color = rgb.white else: try: color = tuple( map(lambda x: float(x) * 255, Preferences.data['freehandColor'])) except ValueError as identifier: color = rgb.black try: size = pdf_annots.defaultPenSize * ( int(Preferences.data['freehandSize']) / pdf_annots.freeHandScale) except ValueError as identifier: size = pdf_annots.defaultPenSize elif self.editMode == editModes.marker: if Preferences.data['comboBoxThemeSelect'] == 0 and toBool( Preferences.data['radioButtonAffectsPDF']) == True: try: color = tuple( map(lambda x: (1 - float(x)) * 255, Preferences.data['markerColor'])) except ValueError as identifier: color = rgb.white else: try: color = tuple( map(lambda x: float(x) * 255, Preferences.data['markerColor'])) except ValueError as identifier: color = rgb.black try: size = pdf_annots.defaultPenSize * (int( Preferences.data['markerSize']) / pdf_annots.freeHandScale) except ValueError as identifier: size = pdf_annots.defaultPenSize elif self.editMode == editModes.forms: if Preferences.data['comboBoxThemeSelect'] == 0 and toBool( Preferences.data['radioButtonAffectsPDF']) == True: try: color = tuple( map(lambda x: (1 - float(x)) * 255, Preferences.data['formColor'])) except ValueError as identifier: color = rgb.white else: try: color = tuple( map(lambda x: float(x) * 255, Preferences.data['formColor'])) except ValueError as identifier: color = rgb.black try: size = pdf_annots.defaultPenSize * (int( Preferences.data['formSize']) / pdf_annots.freeHandScale) except ValueError as identifier: size = pdf_annots.defaultPenSize else: color = rgb.main size = 0.1 shapePainter.setPen(QPen(QColor(*color), size * 3, Qt.SolidLine)) arcRect = QRect(bottomMiddle.x() - 5, bottomMiddle.y() - 6, 13, 13) shapePainter.drawArc(arcRect, 0, CIRCLE) self.pTextEdit.setEnabled(False) self.pTextEdit.setVisible(False) def drawRectShape(self, event): ''' Draws a rectangle for the textEdit box ''' textBoxRect = self.rect() outerCircleRect = self.rect() textBoxRect.adjust(+30, +30, -12, -12) outerCircleRect.adjust(+8, +8, -8, -15) moveRect = QRect(0, 0, 11, 11) shapePainter = QPainter(self) shapePainter.setRenderHint(shapePainter.Antialiasing) # shapePainter.setPen(QPen(QColor(14,125,145), 5, Qt.SolidLine)) # shapePainter.drawRect(textBoxRect) shapePainter.setPen(QPen(QColor(14, 125, 145), 5, Qt.SolidLine)) shapePainter.drawLine(outerCircleRect.topLeft(), outerCircleRect.bottomLeft()) # shapePainter.setPen(QPen(QColor(14,125,145), 2, Qt.SolidLine)) # arcRect = QRect(outerCircleRect.bottomLeft().x() - 6, outerCircleRect.bottomLeft().y()+1, 12, 12) # shapePainter.drawArc(arcRect, 0, CIRCLE) self.pTextEdit.setEnabled(True) self.pTextEdit.setVisible(True) self.pTextEdit.ensureCursorVisible() self.pTextEdit.setFocus() def setButtonState(self): ''' Sets the button state depending on the current edit mode ''' if self.editTextBox and self.editMode == editModes.newTextBox: self.setEnableOnAllButtonsButThose(['okButton', 'cancelButton']) self.setVisibleOnAllButtonsButThose(['okButton', 'cancelButton']) self.slider.setVisible(False) elif self.editTextBox and self.editMode == editModes.editTextBox: self.setEnableOnAllButtonsButThose(['okButton', 'deleteButton']) self.setVisibleOnAllButtonsButThose(['okButton', 'deleteButton']) self.slider.setVisible(False) elif self.editMode == editModes.newTextBox: self.setEnableOnAllButtonsButThose( ['textButton', 'sizeButton', 'colorButton']) self.setVisibleOnAllButtonsButThose( ['textButton', 'sizeButton', 'colorButton']) self.buttons['sizeButton'].move(self.row1Left) self.buttons['colorButton'].move(self.row2Left) elif self.editMode == editModes.marker: self.prevEditMode = editModes.marker self.setEnableOnAllButtonsButThose([ 'markerButton', 'sizeButton', 'colorButton', 'eraserButton', 'undoButton', 'redoButton' ]) self.setVisibleOnAllButtonsButThose([ 'markerButton', 'sizeButton', 'colorButton', 'eraserButton', 'undoButton', 'redoButton' ]) self.buttons['sizeButton'].move(self.row1Right) self.buttons['colorButton'].move(self.row2Right) elif self.editMode == editModes.freehand: self.prevEditMode = editModes.freehand self.setEnableOnAllButtonsButThose([ 'freehandButton', 'sizeButton', 'colorButton', 'eraserButton', 'undoButton', 'redoButton' ]) self.setVisibleOnAllButtonsButThose([ 'freehandButton', 'sizeButton', 'colorButton', 'eraserButton', 'undoButton', 'redoButton' ]) self.buttons['sizeButton'].move(self.row1Right) self.buttons['colorButton'].move(self.row2Right) elif self.editMode == editModes.eraser: self.setEnableOnAllButtonsButThose( ['eraserButton', 'undoButton', 'redoButton']) elif self.editMode == editModes.forms: self.prevEditMode = editModes.forms self.setEnableOnAllButtonsButThose([ 'formsButton', 'sizeButton', 'colorButton', 'eraserButton', 'undoButton', 'redoButton' ]) self.setVisibleOnAllButtonsButThose([ 'formsButton', 'sizeButton', 'colorButton', 'eraserButton', 'undoButton', 'redoButton' ]) self.buttons['sizeButton'].move(self.row1Right) self.buttons['colorButton'].move(self.row2Right) elif self.editMode == editModes.markdown: self.setEnableOnAllButtonsButThose(['markdownButton']) elif self.editMode == editModes.none: self.setVisibleOnAllButtonsButThose([ 'textButton', 'eraserButton', 'formsButton', 'freehandButton', 'markerButton', 'markdownButton', 'undoButton', 'redoButton' ]) self.setEnableOnAllButtonsButThose([ 'textButton', 'eraserButton', 'formsButton', 'freehandButton', 'markerButton', 'markdownButton', 'undoButton', 'redoButton' ]) self.setCheckedOnAllButtonsButThose([]) self.slider.setVisible(True) self.repaint() def setEnableOnAllButtonsButThose(self, names, value=False): for buttonName, buttonInst in self.buttons.items(): if not buttonName in names: buttonInst.setEnabled(value) else: buttonInst.setEnabled(not value) def setVisibleOnAllButtonsButThose(self, names, value=False): for buttonName, buttonInst in self.buttons.items(): if not buttonName in names: buttonInst.setVisible(value) else: buttonInst.setVisible(not value) def setCheckedOnAllButtonsButThose(self, names, value=False): for buttonName, buttonInst in self.buttons.items(): if not buttonName in names: buttonInst.setChecked(value) else: buttonInst.setChecked(not value) def insertCurrentContent(self, content): ''' Used to append the provided content to the textEdit box :param content: Text which should be displayed in the textEdit ''' if content != "": self.pTextEdit.setText(content) return True else: self.pTextEdit.setText("") return False def mousePressEvent(self, event): ''' Overrides the default event ''' self.__mousePressPos = None self.__mouseMovePos = None if event.button() == Qt.LeftButton: self.__mousePressPos = event.globalPos() self.__mouseMovePos = event.globalPos() QWidget.mousePressEvent(self, event) def mouseMoveEvent(self, event): ''' Overrides the default event ''' if event.buttons() == Qt.LeftButton: try: # adjust offset from clicked point to origin of widget currPos = self.mapToGlobal(self.pos()) globalPos = event.globalPos() diff = globalPos - self.__mouseMovePos newPos = self.mapFromGlobal(currPos + diff) self.move(newPos) self.__mouseMovePos = globalPos except AttributeError: pass # We are in touch screen mode here QWidget.mouseMoveEvent(self, event) # def mouseReleaseEvent(self, event): # ''' # Overrides the default event # ''' # if self.__mousePressPos is not None: # moved = event.globalPos() - self.__mousePressPos # if moved.manhattanLength() > 3: # event.ignore() # return # QWidget.mouseReleaseEvent(self, event) @Slot(int, int, int, str) def handleTextInputRequest(self, x, y, pageNumber, currentContent): ''' Slot when toolBox receives a textInput request. This is the case, when the user wants to insert a new or edit an existing textBox ''' # Switch in to text box mode and redraw Widget self.currentPageNumber = pageNumber self.currentContent = currentContent if self.insertCurrentContent(currentContent): self.editMode = editModes.editTextBox else: self.editMode = editModes.newTextBox self.editTextBox = True self.setButtonState() self.currentX = x self.currentY = y self.repaint() def handleTextButton(self): if self.textButton.isChecked(): self.editMode = editModes.newTextBox else: self.editMode = editModes.none self.editModeChange.emit(self.editMode) self.setButtonState() def handleMarkerButton(self): if self.markerButton.isChecked(): self.editMode = editModes.marker else: self.editMode = editModes.none self.editModeChange.emit(self.editMode) self.setButtonState() def handleEraserButton(self): if self.eraserButton.isChecked(): self.editMode = editModes.eraser else: self.editMode = self.prevEditMode self.prevEditMode = editModes.none self.editModeChange.emit(self.editMode) self.setButtonState() def handleFormsButton(self): if self.formsButton.isChecked(): self.editMode = editModes.forms else: self.editMode = editModes.none self.editModeChange.emit(self.editMode) self.setButtonState() def handleFreehandButton(self): if self.freehandButton.isChecked(): self.editMode = editModes.freehand else: self.editMode = editModes.none self.editModeChange.emit(self.editMode) self.setButtonState() def handleMarkdownButton(self): if self.markdownButton.isChecked(): self.editMode = editModes.markdown else: self.editMode = editModes.none self.editModeChange.emit(self.editMode) self.setButtonState() def handleOkButton(self): ''' This method handles all the stuff that needs to be done, when the user successfully finished textEditing ''' if self.editMode == editModes.newTextBox or self.editMode == editModes.editTextBox: self.textInputFinished.emit(self.currentX, self.currentY, self.currentPageNumber, True, self.pTextEdit.toPlainText()) self.editMode = editModes.none self.editTextBox = False self.setButtonState() self.repaint() self.currentPageNumber = -1 self.currentX = -1 self.currentY = -1 def handleCancelButton(self): ''' This method handles all the stuff that needs to be done, when the user canceled textEditing ''' if self.editMode == editModes.newTextBox or self.editMode == editModes.editTextBox: self.textInputFinished.emit(self.currentX, self.currentY, self.currentPageNumber, False, self.currentContent) self.editMode = editModes.none self.editTextBox = False self.setButtonState() self.repaint() self.currentPageNumber = -1 self.currentX = -1 self.currentY = -1 def handleDeleteButton(self): ''' This method handles all the stuff that needs to be done, when the user canceled textEditing ''' if self.editMode == editModes.newTextBox or self.editMode == editModes.editTextBox: self.textInputFinished.emit(self.currentX, self.currentY, self.currentPageNumber, False, "") self.editMode = editModes.none self.editTextBox = False self.setButtonState() self.repaint() self.currentPageNumber = -1 self.currentX = -1 self.currentY = -1 def handleUndoButton(self): History.undo() self.suggestUpdate.emit() def handleRedoButton(self): History.redo() self.suggestUpdate.emit() def restoreSliderValue(self): try: if self.sizeButton.isChecked(): if self.editMode == editModes.newTextBox: lastSliderValue = int(Preferences.data['textSize']) elif self.editMode == editModes.marker: lastSliderValue = int(Preferences.data['markerSize']) elif self.editMode == editModes.freehand: lastSliderValue = int(Preferences.data['freehandSize']) elif self.editMode == editModes.forms: lastSliderValue = int(Preferences.data['formSize']) elif self.colorButton.isChecked(): if self.editMode == editModes.marker: try: normRGB = tuple( map(lambda x: float(x), str(Preferences.data['markerColor']))) hsv = colorsys.rgb_to_hsv(*normRGB) except TypeError as identifier: raise ValueError lastSliderValue = int(hsv[0] * 100) elif self.editMode == editModes.freehand: try: normRGB = tuple( map(lambda x: float(x), str(Preferences.data['freehandColor']))) hsv = colorsys.rgb_to_hsv(*normRGB) except TypeError as identifier: raise ValueError lastSliderValue = int(hsv[0] * 100) elif self.editMode == editModes.forms: try: normRGB = tuple( map(lambda x: float(x), str(Preferences.data['formColor']))) hsv = colorsys.rgb_to_hsv(*normRGB) except TypeError as identifier: raise ValueError lastSliderValue = int(hsv[0] * 100) except ValueError: self.storeSliderValue() return self.slider.setValue(lastSliderValue) def storeSliderValue(self): if self.sizeButton.isChecked(): if self.editMode == editModes.newTextBox: Preferences.updateKeyValue('textSize', self.slider.value()) elif self.editMode == editModes.marker: Preferences.updateKeyValue('markerSize', self.slider.value()) elif self.editMode == editModes.freehand: Preferences.updateKeyValue('freehandSize', self.slider.value()) elif self.editMode == editModes.forms: Preferences.updateKeyValue('formSize', self.slider.value()) elif self.colorButton.isChecked(): normRGB = colorsys.hsv_to_rgb(self.slider.value() / 100, 1, 1) if self.editMode == editModes.marker: Preferences.updateKeyValue( 'markerColor', tuple(map(lambda x: str(x), normRGB))) elif self.editMode == editModes.freehand: Preferences.updateKeyValue( 'freehandColor', tuple(map(lambda x: str(x), normRGB))) elif self.editMode == editModes.forms: Preferences.updateKeyValue( 'formColor', tuple(map(lambda x: str(x), normRGB))) self.settingsChanged.emit() def handleSizeButton(self): ''' This method will set the slider value to match the current size ''' if self.sizeButton.isChecked(): self.slider.setEnabled(True) self.restoreSliderValue() else: self.storeSliderValue() self.slider.setEnabled(False) self.slider.setValue(100) self.repaint() def handleColorButton(self): ''' Handles color button presses ''' if self.colorButton.isChecked(): self.slider.setEnabled(True) self.restoreSliderValue() else: self.restoreDefaults() self.slider.setEnabled(False) self.slider.setValue(100) self.repaint() def handleSliderDrag(self, value): ''' Called when the user moves the slider ''' self.slider.setValue(10 * round(value / 10)) self.storeSliderValue() self.repaint() def handleSliderValueChange(self, value): ''' Triggered when user changes the slider value ''' self.slider.setValue(10 * round(value / 10)) def handleSliderValueChanged(self): ''' Triggered when user has changed the slider value ''' self.storeSliderValue()
class StreamFieldsWidget(QDialog): """ A stream widget containing schema-specific properties. """ def __init__(self, parent, show_only_f142_stream: bool = False): super().__init__() self.setParent(parent) self.setLayout(QGridLayout()) self.setWindowModality(Qt.WindowModal) self.setModal(True) self._show_only_f142_stream = show_only_f142_stream self.minimum_spinbox_value = 0 self.maximum_spinbox_value = 100_000_000 self.advanced_options_enabled = False self.hs00_unimplemented_label = QLabel( "hs00 (Event histograms) has not yet been fully implemented.") self.schema_label = QLabel("Schema: ") self.schema_combo = DropDownList() self.schema_validator = SchemaSelectionValidator() self.schema_combo.setValidator(self.schema_validator) self.schema_validator.is_valid.connect( partial(validate_general_widget, self.schema_combo)) self.topic_label = QLabel("Topic: ") self.topic_line_edit = QLineEdit() self.topic_validator = NoEmptyStringValidator() self.topic_line_edit.setValidator(self.topic_validator) self.topic_validator.is_valid.connect( partial( validate_line_edit, self.topic_line_edit, tooltip_on_reject="Topic name can not be empty.", )) validate_line_edit(self.topic_line_edit, False) self.source_label = QLabel("Source: ") self.source_line_edit = QLineEdit() self.source_validator = NoEmptyStringValidator() self.source_line_edit.setValidator(self.source_validator) self.source_validator.is_valid.connect( partial( validate_line_edit, self.source_line_edit, tooltip_on_reject="Source name can not be empty.", )) validate_line_edit(self.source_line_edit, False) self.array_size_label = QLabel("Array size: ") self.array_size_spinbox = QSpinBox() self.array_size_spinbox.setMaximum(np.iinfo(np.int32).max) self.array_size_table = QTableWidget(1, 3) self.array_size_table.setHorizontalHeaderLabels(["x", "y", "z"]) self.array_size_table.setVerticalHeaderLabels([""]) table_height = self.array_size_table.sizeHintForRow( 0) + self.array_size_table.sizeHintForRow(1) self.array_size_table.setMaximumHeight(table_height) self.array_size_table.setFrameStyle(QFrame.NoFrame) self.array_size_table.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.array_size_table.resizeColumnsToContents() self.array_size_table.resizeRowsToContents() self.array_size_table.setItemDelegate( ValueDelegate(int, self.array_size_table)) self.type_label = QLabel("Type: ") self.type_combo = QComboBox() self.type_combo.addItems(F142_TYPES) self.type_combo.setCurrentText("double") self.value_units_edit = QLineEdit() self.value_units_label = QLabel("Value Units:") self.show_advanced_options_button = QPushButton( text="Show/hide advanced options") self.show_advanced_options_button.setCheckable(True) self.show_advanced_options_button.clicked.connect( self.advanced_options_button_clicked) self._set_up_f142_group_box() self._set_up_ev42_group_box() self.scalar_radio = QRadioButton(text=SCALAR) self.scalar_radio.clicked.connect(partial(self._show_array_size, False)) self.scalar_radio.setChecked(True) self.scalar_radio.clicked.emit() self.array_radio = QRadioButton(text=ARRAY) self.array_radio.clicked.connect(partial(self._show_array_size, True)) self.schema_combo.currentTextChanged.connect(self._schema_type_changed) if self._show_only_f142_stream: self.schema_combo.addItems([StreamModules.F142.value]) else: self.schema_combo.addItems([e.value for e in StreamModules]) self.ok_button = QPushButton("OK") self.ok_button.clicked.connect(self.parent().close) self.layout().addWidget(self.schema_label, 0, 0) self.layout().addWidget(self.schema_combo, 0, 1) self.layout().addWidget(self.topic_label, 1, 0) self.layout().addWidget(self.topic_line_edit, 1, 1) self.layout().addWidget(self.source_label, 2, 0) self.layout().addWidget(self.source_line_edit, 2, 1) self.layout().addWidget(self.value_units_label, 3, 0) self.layout().addWidget(self.value_units_edit, 3, 1) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) self.layout().addWidget(self.type_label, 4, 0) self.layout().addWidget(self.type_combo, 4, 1) self.layout().addWidget(self.scalar_radio, 5, 0) self.layout().addWidget(self.array_radio, 5, 1) self.layout().addWidget(self.array_size_label, 6, 0) self.layout().addWidget(self.array_size_spinbox, 6, 1) self.layout().addWidget(self.array_size_table, 6, 1) self.layout().addWidget(self.hs00_unimplemented_label, 7, 0, 1, 2) # Spans both rows self.layout().addWidget(self.show_advanced_options_button, 8, 0, 1, 2) self.layout().addWidget(self.f142_advanced_group_box, 9, 0, 1, 2) self.layout().addWidget(self.ev42_advanced_group_box, 10, 0, 1, 2) self.layout().addWidget(self.ok_button, 11, 0, 1, 2) self._schema_type_changed(self.schema_combo.currentText()) self.parent().parent().field_name_edit.setVisible(False) def advanced_options_button_clicked(self): self._show_advanced_options( show=self.show_advanced_options_button.isChecked()) def _set_up_ev42_group_box(self): """ Sets up the UI for ev42 advanced options. """ self.ev42_advanced_group_box = QGroupBox( parent=self.show_advanced_options_button) self.ev42_advanced_group_box.setLayout(QFormLayout()) self.ev42_adc_pulse_debug_label = QLabel(ADC_PULSE_DEBUG) self.ev42_adc_pulse_debug_checkbox = QCheckBox() self.ev42_advanced_group_box.layout().addRow( self.ev42_adc_pulse_debug_label, self.ev42_adc_pulse_debug_checkbox) self.ev42_chunk_size_spinner = ( self.create_label_and_spinbox_for_advanced_option( CHUNK_SIZE, self.ev42_advanced_group_box)) self.ev42_cue_interval_spinner = ( self.create_label_and_spinbox_for_advanced_option( CUE_INTERVAL, self.ev42_advanced_group_box)) def create_label_and_spinbox_for_advanced_option(self, nexus_string: str, group_box: QGroupBox): """ Creates a SpinBox with a label and adds them to GroupBox then returns the SpinBox. :param nexus_string: The nexus string label for the SpinBox. :param group_box: The GroupBox that the label and SpinBox should be added to. :return: The newly created SpinBox. """ label = QLabel(nexus_string) spinner = QSpinBox() spinner.setRange(self.minimum_spinbox_value, self.maximum_spinbox_value) group_box.layout().addRow(label, spinner) return spinner def _set_up_f142_group_box(self): """ Sets up the UI for the f142 advanced options. """ self.f142_advanced_group_box = QGroupBox( parent=self.show_advanced_options_button) self.f142_advanced_group_box.setLayout(QFormLayout()) self.f142_chunk_size_spinner = ( self.create_label_and_spinbox_for_advanced_option( CHUNK_SIZE, self.f142_advanced_group_box)) self.f142_cue_interval_spinner = ( self.create_label_and_spinbox_for_advanced_option( CUE_INTERVAL, self.f142_advanced_group_box)) def _show_advanced_options(self, show): schema = self.schema_combo.currentText() if schema == WriterModules.F142.value: self.f142_advanced_group_box.setVisible(show) elif schema == WriterModules.EV42.value: self.ev42_advanced_group_box.setVisible(show) self.advanced_options_enabled = show def _show_array_size(self, show: bool): self.array_size_spinbox.setVisible(show) self.array_size_label.setVisible(show) def _schema_type_changed(self, schema: str): self.parent().setWindowTitle(f"Editing {schema} stream field") self.hs00_unimplemented_label.setVisible(False) self.f142_advanced_group_box.setVisible(False) self.ev42_advanced_group_box.setVisible(False) self.show_advanced_options_button.setVisible(False) self.show_advanced_options_button.setChecked(False) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) self.array_size_table.setVisible(False) if schema == WriterModules.F142.value: self.value_units_label.setVisible(True) self.value_units_edit.setVisible(True) self._set_edits_visible(True, True) self.show_advanced_options_button.setVisible(True) self.f142_advanced_group_box.setVisible(False) elif schema == WriterModules.EV42.value: self._set_edits_visible(True, False) self.show_advanced_options_button.setVisible(True) self.ev42_advanced_group_box.setVisible(False) elif schema == WriterModules.ADAR.value: self._set_edits_visible(True, False) self._show_array_size_table(True) elif schema == WriterModules.HS00.value: self._set_edits_visible(True, False) self.hs00_unimplemented_label.setVisible(True) elif schema == WriterModules.NS10.value: self._set_edits_visible(True, False, "nicos/<device>/<parameter>") elif (schema == WriterModules.TDCTIME.value or schema == WriterModules.SENV.value): self._set_edits_visible(True, False) def _show_array_size_table(self, show: bool): self.array_size_label.setVisible(show) self.array_size_table.setVisible(show) def _set_edits_visible(self, source: bool, type: bool, source_hint=None): self.source_label.setVisible(source) self.source_line_edit.setVisible(source) self.type_label.setVisible(type) self.type_combo.setVisible(type) self.array_radio.setVisible(type) self.scalar_radio.setVisible(type) if source_hint: self.source_line_edit.setPlaceholderText(source_hint) else: self.source_line_edit.setPlaceholderText("") def get_stream_module(self, parent) -> StreamModule: """ Create the stream module :return: The created stream module """ source = self.source_line_edit.text() topic = self.topic_line_edit.text() stream: StreamModule = None type = self.type_combo.currentText() current_schema = self.schema_combo.currentText() if current_schema == WriterModules.F142.value: value_units = self.value_units_edit.text() array_size = self.array_size_spinbox.value() stream = F142Stream( parent_node=parent, source=source, topic=topic, type=type, value_units=value_units, array_size=array_size, ) if array_size: stream.array_size = array_size if self.advanced_options_enabled: self.record_advanced_f142_values(stream) elif current_schema == WriterModules.ADAR.value: array_size = [] for i in range(self.array_size_table.columnCount()): table_value = self.array_size_table.item(0, i) if table_value: array_size.append(int(table_value.text())) stream = ADARStream(parent_node=parent, source=source, topic=topic) stream.array_size = array_size elif current_schema == WriterModules.EV42.value: stream = EV42Stream(parent_node=parent, source=source, topic=topic) if self.advanced_options_enabled: self.record_advanced_ev42_values(stream) elif current_schema == WriterModules.NS10.value: stream = NS10Stream(parent_node=parent, source=source, topic=topic) elif current_schema == WriterModules.SENV.value: stream = SENVStream(parent_node=parent, source=source, topic=topic) elif current_schema == WriterModules.HS00.value: stream = HS00Stream( # type: ignore parent=parent, source=source, topic=topic, data_type=NotImplemented, edge_type=NotImplemented, error_type=NotImplemented, shape=[], ) elif current_schema == WriterModules.TDCTIME.value: stream = TDCTStream(parent_node=parent, source=source, topic=topic) return stream def record_advanced_f142_values(self, stream: F142Stream): """ Save the advanced f142 properties to the stream data object. :param stream: The stream data object to be modified. """ stream.chunk_size = self.f142_chunk_size_spinner.value() stream.cue_interval = self.f142_cue_interval_spinner.value() def record_advanced_ev42_values(self, stream: EV42Stream): """ Save the advanced ev42 properties to the stream data object. :param stream: The stream data object to be modified. """ stream.adc_pulse_debug = self.ev42_adc_pulse_debug_checkbox.isChecked() stream.chunk_size = self.ev42_chunk_size_spinner.value() stream.cue_interval = self.ev42_cue_interval_spinner.value() def fill_in_existing_ev42_fields(self, field: EV42Stream): """ Fill in specific existing ev42 fields into the new UI field. :param field: The stream group """ if check_if_advanced_options_should_be_enabled( [field.adc_pulse_debug, field.chunk_size, field.cue_interval]): self._show_advanced_options(True) self._fill_existing_advanced_ev42_fields(field) def _fill_existing_advanced_ev42_fields(self, field: EV42Stream): """ Fill the fields in the interface with the existing ev42 stream data. :param field: The ev42 stream data object. """ self.ev42_adc_pulse_debug_checkbox.setChecked(field.adc_pulse_debug) self.ev42_chunk_size_spinner.setValue(field.chunk_size) self.ev42_cue_interval_spinner.setValue(field.cue_interval) def fill_in_existing_f142_fields(self, field: F142Stream): """ Fill in specific existing f142 fields into the new UI field. :param field: The stream group """ self.type_combo.setCurrentText(field.type) if field.array_size is not None: self.array_radio.setChecked(True) self.scalar_radio.setChecked(False) self.array_size_spinbox.setValue(field.array_size) else: self.array_radio.setChecked(False) self.scalar_radio.setChecked(True) if field.value_units is not None: self.value_units_edit.setText(field.value_units) if check_if_advanced_options_should_be_enabled( [field.chunk_size, field.cue_interval]): self._show_advanced_options(True) self._fill_existing_advanced_f142_fields(field) def _fill_existing_advanced_f142_fields(self, field: F142Stream): """ Fill the advanced fields in the interface with the existing f142 stream data. :param field: The f412 stream data object. """ self.f142_chunk_size_spinner.setValue(field.chunk_size) self.f142_cue_interval_spinner.setValue(field.cue_interval) def update_existing_stream_info(self, field): """ Fill in stream fields and properties into the new UI field. :param field: The stream group """ if isinstance(field, Group): field = field.children[0] if hasattr(field, "parent_node") and isinstance( field.parent_node, Group): self.schema_validator.set_group(field.parent_node) else: self.schema_validator.set_group(None) schema = field.writer_module self.schema_combo.setCurrentText(schema) self.schema_validator.validate(schema, 0) self.topic_line_edit.setText(field.topic) self.topic_validator.validate(field.topic, 0) self.source_line_edit.setText(field.source) self.source_validator.validate(field.source, 0) if schema == WriterModules.F142.value: self.fill_in_existing_f142_fields(field) elif schema == WriterModules.EV42.value: self.fill_in_existing_ev42_fields(field) elif schema == WriterModules.ADAR.value: for i, val in enumerate(field.array_size): self.array_size_table.setItem(0, i, QTableWidgetItem(str(val)))
class YoutubeDnld(QDialog): def __init__(self): super().__init__() self.downloadName = '' self.downloadPercent = '' self.downloadSpeed = '' self.setWindowTitle('Youtube下载器 (此窗口可关闭至后台下载 支持断点下载 需要自备梯子)') self.resize(1000, 600) self.layout = QGridLayout() self.setLayout(self.layout) self.tipLabel = QLabel('Youtube链接:') self.layout.addWidget(self.tipLabel, 0, 0, 1, 2) self.urlInput = QLineEdit('请输入Youtube视频链接') self.layout.addWidget(self.urlInput, 0, 2, 1, 5) self.searchButton = QPushButton('查询') self.searchButton.clicked.connect(self.checkURL) self.layout.addWidget(self.searchButton, 0, 7, 1, 1) self.searchToken = False self.videoInfo = QTableWidget() self.videoInfo.verticalHeader().setHidden(True) self.videoInfo.setRowCount(10) self.videoInfo.setColumnCount(6) self.videoInfo.setColumnWidth(0, 100) self.videoInfo.setColumnWidth(1, 100) self.videoInfo.setColumnWidth(2, 100) self.videoInfo.setColumnWidth(3, 100) self.videoInfo.setColumnWidth(4, 100) self.videoInfo.setColumnWidth(5, 450) self.videoInfo.setHorizontalHeaderLabels( ['序号', '后缀名', '分辨率', '码率', '类型', '备注']) self.layout.addWidget(self.videoInfo, 1, 0, 4, 8) self.dnldInput = QLineEdit() self.layout.addWidget(self.dnldInput, 5, 0, 1, 2) self.dnldLabel = QLabel('输入要下载的视频/音频序号,多个序号用空格隔开 ') self.layout.addWidget(self.dnldLabel, 5, 2, 1, 2) self.jaCheck = QPushButton('下载日语字幕(自动识别)') self.zhCheck = QPushButton('下载中文字幕(油管机翻)') self.thumbnailCheck = QPushButton('下载封面') self.jaCheck.setStyleSheet('background-color:#3daee9') self.zhCheck.setStyleSheet('background-color:#3daee9') self.thumbnailCheck.setStyleSheet('background-color:#3daee9') self.jaCheckStatus = True self.zhCheckStatus = True self.thumbnailCheckStatus = True self.jaCheck.clicked.connect(self.jaCheckClick) self.zhCheck.clicked.connect(self.zhCheckClick) self.thumbnailCheck.clicked.connect(self.thumbnailCheckClick) self.layout.addWidget(self.jaCheck, 5, 4, 1, 1) self.layout.addWidget(self.zhCheck, 5, 5, 1, 1) self.layout.addWidget(self.thumbnailCheck, 5, 6, 1, 1) self.savePath = QLineEdit() self.layout.addWidget(self.savePath, 6, 0, 1, 4) self.saveButton = QPushButton('保存路径') self.saveButton.setFixedWidth(115) self.saveButton.clicked.connect(self.setSavePath) self.layout.addWidget(self.saveButton, 6, 4, 1, 1) self.processInfo = QLabel() self.layout.addWidget(self.processInfo, 6, 5, 1, 2) self.progress = QProgressBar() self.layout.addWidget(self.progress, 7, 0, 1, 7) self.startButton = QPushButton('开始下载') self.startButton.setFixedWidth(140) self.startButton.setFixedHeight(120) self.startButton.setEnabled(False) self.startButton.clicked.connect(self.dnldStart) self.layout.addWidget(self.startButton, 5, 7, 3, 1) self.timer = QTimer() self.timer.setInterval(500) self.timer.start() self.timer.timeout.connect(self.dnldProgress) def jaCheckClick(self): self.jaCheckStatus = not self.jaCheckStatus if self.jaCheckStatus: self.jaCheck.setStyleSheet('background-color:#3daee9') else: self.jaCheck.setStyleSheet('background-color:#31363b') def zhCheckClick(self): self.zhCheckStatus = not self.zhCheckStatus if self.zhCheckStatus: self.zhCheck.setStyleSheet('background-color:#3daee9') else: self.zhCheck.setStyleSheet('background-color:#31363b') def thumbnailCheckClick(self): self.thumbnailCheckStatus = not self.thumbnailCheckStatus if self.thumbnailCheckStatus: self.thumbnailCheck.setStyleSheet('background-color:#3daee9') else: self.thumbnailCheck.setStyleSheet('background-color:#31363b') def checkURL(self): self.url = self.urlInput.text() if self.url: if '&' in self.url: self.url = self.url.split('&')[0] self.videoInfo.clearContents() self.dnldCheck = dnldCheck(self.url) self.dnldCheck.searchCnt.connect(self.refreshSearchButton) self.dnldCheck.checkStatus.connect(self.setCheckStatus) self.dnldCheck.videoTitle.connect(self.setTitle) self.dnldCheck.videoResults.connect(self.setVideoInfo) self.dnldCheck.start() def refreshSearchButton(self, cnt): if cnt: self.searchButton.setText('搜索中' + '.' * cnt) else: self.searchButton.setText('查询') def setCheckStatus(self, checkStatus): if not checkStatus: self.searchToken = False self.videoInfo.setItem(0, 5, QTableWidgetItem('无效的视频链接 请重新输入')) else: self.searchToken = True def setTitle(self, title): self.title = title self.urlInput.setText(title) def setVideoInfo(self, results): self.videoInfo.setRowCount(len(results) - 4) for y, l in enumerate(results[1:-3]): l = l.split(' ') while '' in l: l.remove('') if ',' in l: l.remove(',') if 'tiny' in l: l.remove('tiny') lineData = l[:2] if l[2] == 'audio': lineData.append('无') else: lineData.append('%s %s' % tuple(l[2:4])) lineData.append(l[4]) tip = '' for i in l[4:]: tip += i + ' ' if l[2] == 'audio': lineData.append('audio only') elif 'video only' in tip: lineData.append('video only') else: lineData.append('video + audio') lineData.append(tip[:-1]) for x, data in enumerate(lineData): self.videoInfo.setItem(y, x, QTableWidgetItem(data)) def setSavePath(self): savePath = QFileDialog.getExistingDirectory(self, '选择视频保存文件夹') if savePath: self.savePath.setText(savePath) def dnldProgress(self): if self.searchToken and self.dnldInput.text() and self.savePath.text(): self.startButton.setEnabled(True) else: self.startButton.setEnabled(False) def dnldStart(self): self.processInfo.setText('下载速度:') dnldNum = self.dnldInput.text().split(' ') videoType = [] resolution = [] for num in dnldNum: for y in range(self.videoInfo.rowCount()): if self.videoInfo.item(y, 0).text() == num: videoType.append(self.videoInfo.item(y, 1).text()) resolution.append(self.videoInfo.item(y, 2).text()) break savePath = self.savePath.text() ja = self.jaCheck.isChecked() zh = self.zhCheck.isChecked() if ja and zh: args = ['--write-auto-sub', '--sub-lang', 'ja,zh-Hans'] elif ja and not zh: args = ['--write-auto-sub', '--sub-lang', 'ja'] elif zh and not ja: args = ['--write-auto-sub', '--sub-lang', 'zh-Hans'] else: args = [] if self.thumbnailCheck.isChecked(): args.append('--write-thumbnail') self.dnldThread = dnldThread(dnldNum, videoType, resolution, savePath, self.title, args, self.url) self.dnldThread.downloading.connect(self.dnldName) self.dnldThread.percent.connect(self.dnldPercent) self.dnldThread.done.connect(self.dnldFinish) self.dnldThread.start() def dnldName(self, name): self.savePath.setText(name) def dnldPercent(self, percent): if r'%' in percent: self.downloadPercent = percent.split(r'%')[0].split(' ')[-1] if 'B/s' in percent: self.downloadSpeed = percent.split('B/s')[0].split(' ')[-1] + 'B/s' self.processInfo.setText('下载速度:%s' % self.downloadSpeed) if self.downloadPercent: self.progress.setValue(float(self.downloadPercent)) def dnldFinish(self, done): self.processInfo.setText(done) self.progress.setValue(0)
class SignUpForm(QDialog): def __init__(self, parent=None): super(SignUpForm, self).__init__(parent) self.checkedPass = 0 self.setWindowTitle("Backend Discord-GUI") self.changeStyle('fusion') palette = QPalette() palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, Qt.white) palette.setColor(QPalette.Text, Qt.white) palette.setColor(QPalette.Button, QColor(60, 60, 60)) palette.setColor(QPalette.ButtonText, Qt.white) palette.setColor(QPalette.Base, QColor(40, 40, 40)) palette.setColor(QPalette.ToolTipBase, QColor(60, 60, 60)) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.PlaceholderText, QColor(100, 60, 60)) palette.setColor(QPalette.BrightText, Qt.white) palette.setColor(QPalette.Highlight, QColor(106, 13, 173)) palette.setColor(QPalette.HighlightedText, Qt.white) mainLayout = QVBoxLayout() hMainLayout = QHBoxLayout() passwordLayout = QHBoxLayout() entryBG = QPalette() gradient = QGradient() gradient.setColorAt(0.0, QColor(30, 30, 30)) gradient.setColorAt(0.4, QColor(30, 30, 30)) gradient.setColorAt(1.0, QColor(70, 70, 70)) gradient.setSpread(QGradient.RepeatSpread) entryBG.setBrush(QPalette.Button, QBrush(gradient)) self.name = QLineEdit(self) self.name.setFixedHeight(24) self.name.setToolTip("Max 64 Characters") self.name.setStyleSheet( "QToolTip { border: 0px; border-radius: 3px; }") self.name.setPalette(entryBG) self.QNameLabel = QLabel("Full Name") self.QNameLabel.setFont(QFont("Copperplate", 12)) self.name.setMaxLength(64) self.email = QLineEdit(self) self.email.setFixedHeight(24) self.email.setToolTip( "Max 128 Characters, Example - [email protected]") self.email.setStyleSheet( "QToolTip { border: 0px; border-radius: 3px }") self.email.setPalette(entryBG) self.QEmailLabel = QLabel("Email") self.QEmailLabel.setFont(QFont("Copperplate", 12)) self.email.setMaxLength(128) self.username = QLineEdit(self) self.username.setFixedHeight(24) self.username.setToolTip("Max 16 Characters") self.username.setStyleSheet( "QToolTip { border: 0px; border-radius: 3px }") self.username.setPalette(entryBG) self.QUserLabel = QLabel("Username") self.QUserLabel.setFont(QFont("Copperplate", 12)) self.username.setMaxLength(16) self.password = QLineEdit(self) self.password.setFixedHeight(24) self.password.setToolTip( "Max 32 Characters, Must Include = Uppercase Letter,\nNumber and Special Character" ) self.password.setStyleSheet( "QToolTip { border: 0px; border-radius: 3px }") self.password.setPalette(entryBG) self.QPasswordLabel = QLabel("Password ") self.password.setMaxLength(32) self.QPasswordLabel.setFont(QFont("Copperplate", 12)) self.showhideButton = QPushButton("Show") self.showhideButton.setCheckable(True) self.showhideButton.setChecked(False) self.showhideButton.clicked.connect(lambda: self.show_hide()) self.password.setEchoMode(QLineEdit.Password) passwordLayout.addWidget(self.QPasswordLabel) passwordLayout.addWidget(self.password) passwordLayout.addWidget(self.showhideButton) self.btn_SignUp = QPushButton("Sign Up") self.btn_SignUp.clicked.connect(lambda: self.signUpWindow()) shortcut = QShortcut(QKeySequence("Return"), self.btn_SignUp) shortcut.activated.connect(lambda: self.signUpWindow()) shortcut.setEnabled(True) self.btn_cancel = QPushButton("Cancel") self.btn_cancel.clicked.connect(lambda: self.cancel()) layout = QFormLayout() layout.addRow(self.QNameLabel, self.name) layout.addRow(self.QEmailLabel, self.email) layout.addRow(self.QUserLabel, self.username) layout.addRow(passwordLayout) layout.addRow(self.btn_SignUp) layout.addRow(self.btn_cancel) Label = QLabel("Sign Up To The\nBackend Discord-GUI Development") Label.setFont(QFont("Copperplate", 15, QFont.Bold)) Label.setAlignment(Qt.AlignCenter) mainLayout.addSpacing(40) mainLayout.addWidget(Label) mainLayout.addLayout(layout) mainLayout.addSpacing(60) hMainLayout.addSpacing(115) hMainLayout.addLayout(mainLayout) hMainLayout.addSpacing(115) self.setLayout(hMainLayout) QApplication.setPalette(palette) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: pass def check_passwordCheck(self): if self.checkedPass <= 0: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Check Password?") msg.setInformativeText( "Are you sure you want to Sign Up, you haven't checked your password. Do you want to proceed?" ) msg.setWindowTitle("Check Password?") msg.setDetailedText( "We monitor basic actions you make, this is part of our policy. This MessageBox " + "was generated because we detected you did not check your password before clicking " + "the sign up button. We recommend this just incase you forget your password.\n\n" + "We believe in the best for our customers, so we try to minimise simple errors, " + "like this, to serve customers quicker when there is a higher priority support request." ) msg.setStandardButtons(QMessageBox.No | QMessageBox.Yes) msg.buttonClicked.connect(self.signUp) retval = msg.exec_() else: self.signUp(proceed=True) def signUpWindow(self): namePassed, emailPassed, usernamePassed, passwordPassed = False, False, False, False errors = [] if len(self.name.text()) <= 1: self.name.setStyleSheet( "QLineEdit { border: 1px solid red; border-radius: 3px; } QToolTip { border: 0px }" ) errors.append("Name: Too Short") else: self.name.setStyleSheet( "QLineEdit { border: 0px; border-radius: 3px; } QToolTip { border: 0px }" ) namePassed = True if re.match(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", self.email.text()): self.email.setStyleSheet( "QLineEdit { border: 0px; border-radius: 3px; } QToolTip { border: 0px }" ) emailPassed = True else: self.email.setStyleSheet( "QLineEdit { border: 1px solid red; border-radius: 3px; } QToolTip { border: 0px }" ) errors.append("Email: This is not a valid Email") if len(self.username.text()) <= 2: self.username.setStyleSheet( "QLineEdit { border: 1px solid red; border-radius: 3px; } QToolTip { border: 0px }" ) errors.append("Username: Too Short") else: if re.match(r"([a-zA-Z0-9_]+$)", self.username.text()): self.username.setStyleSheet( "QLineEdit { border: 0px; border-radius: 3px; } QToolTip { border: 0px }" ) usernamePassed = True else: self.username.setStyleSheet( "QLineEdit { border: 1px solid red; border-radius: 3px; } QToolTip { border: 0px }" ) errors.append( "Username: Can only have, a-z (A-Z), 0-9 and '_'") if len(self.password.text()) <= 7: self.password.setStyleSheet( "QLineEdit { border: 1px solid red; border-radius: 3px; } QToolTip { border: 0px }" ) errors.append("Password: Too Short") else: if re.match( r'^.*(?=.{8,10})(?=.*[a-zA-Z])(?=.*?[A-Z])(?=.*\d)[a-zA-Z0-9!@£$%^&*()_+={}?:~\[\]]+$', self.password.text()): self.password.setStyleSheet( "QLineEdit { border: 0px; border-radius: 3px; } QToolTip { border: 0px }" ) passwordPassed = True else: self.password.setStyleSheet( "QLineEdit { border: 1px solid red; border-radius: 3px; } QToolTip { border: 0px }" ) errors.append( "Password: Needs to have, Capital Letter, Number, Special Character" ) if namePassed and emailPassed and usernamePassed and passwordPassed: self.check_passwordCheck() else: if len(errors) > 2: string = "; ".join(errors[:2]) overall_string = str("Errors: " + string + " +{} more".format(len(errors) - 2)) else: string = "; ".join(errors) overall_string = str("Errors: " + string) window.setStatusBar(overall_string, True) def signUp(self, i=None, proceed=False): if i != None: if i.text() == "&Yes": signUp = True QApplication.quit() else: pass signUp = proceed if signUp == True: print("Signed Up") QApplication.quit() def show_hide(self): if self.showhideButton.isChecked(): self.checkedPass += 1 self.password.setEchoMode(QLineEdit.Normal) self.showhideButton.setText("Hide") else: self.password.setEchoMode(QLineEdit.Password) self.showhideButton.setText("Show") def changeStyle(self, styleName): QApplication.setStyle(QStyleFactory.create(styleName)) def cancel(self): window.openLogIn()
class PlayOverlay(QWidget): def __init__(self, parent, status): super(PlayOverlay, self).__init__(parent) self.status = status self.main_widget = parent self.main_window = parent.parent() # AspectRatioWidget >> MainWindow self.resize(self.main_window.size().width(), self.main_window.size().height()) self.resize(100, 100) self.gridLayout = QGridLayout() self.label = QLabel(self) self.btn_play = PlayButton(self) self.btn_force_jump = QPushButton(self) self.btn_pc_first = QPushButton(self) self.btn_lvl1 = QPushButton(self) self.btn_lvl2 = QPushButton(self) self.btn_lvl3 = QPushButton(self) self.btn_undo = QPushButton(self) self.init_layout() self.set_remembered() def resizeEvent(self, event): super(PlayOverlay, self).resizeEvent(event) w = event.size().width() h = event.size().height() self.update_sizes(w, h) def update_sizes(self, width, height): self.resize(width, height) y = height / 2 - 370 self.label.resize(width, 500) self.label.move(0, y) y = height / 2 x = width / 2 self.btn_play.move(x - 150, y - 20) self.btn_force_jump.move(x - 150, y + 60) self.btn_pc_first.move(x, y + 60) self.btn_undo.move(x - 100, y - 70) self.btn_lvl1.move(x - 150, y + 120) self.btn_lvl2.move(x - 50, y + 120) self.btn_lvl3.move(x + 50, y + 120) if width < 600: pt_size = 38 else: pt_size = 72 font = self.label.font() font.setPointSize(pt_size) font.setBold(True) self.label.setFont(font) def init_layout(self): self.label.setObjectName("status") self.label.setText(self.get_status_string()) self.label.setAlignment(Qt.AlignCenter) self.label.setStyleSheet("background: transparent; color:#ddd") font = self.label.font() font.setPointSize(72) font.setBold(True) self.label.setFont(font) self.btn_play.resize(300, 70) self.btn_force_jump.setText("Force Jump") self.btn_force_jump.setCheckable(True) self.btn_force_jump.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_force_jump.resize(150, 50) self.btn_pc_first.setText("PC First") self.btn_pc_first.setCheckable(True) self.btn_pc_first.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_pc_first.resize(150, 50) # self.btn_play.move(100,200) self.btn_lvl1.resize(100, 50) self.btn_lvl2.resize(100, 50) self.btn_lvl3.resize(100, 50) self.btn_lvl1.setCheckable(True) self.btn_lvl2.setCheckable(True) self.btn_lvl3.setCheckable(True) self.btn_lvl1.setText("EASY") self.btn_lvl2.setText("MEDIUM") self.btn_lvl3.setText("HARD") self.btn_lvl1.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_lvl2.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_lvl3.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_lvl1.clicked.connect(lambda: self.difficulty_radio(1)) self.btn_lvl2.clicked.connect(lambda: self.difficulty_radio(2)) self.btn_lvl3.clicked.connect(lambda: self.difficulty_radio(3)) self.difficulty_radio(2) self.btn_undo.setText("UNDO") self.btn_undo.setCursor(Qt.CursorShape.PointingHandCursor) self.btn_undo.resize(200, 40) self.btn_undo.clicked.connect(self.undo_move) if self.status == -1: self.btn_play.set_text("PLAY") self.btn_undo.setVisible(False) else: self.btn_play.set_text("PLAY AGAIN") if self.main_window.history_table: self.btn_undo.setVisible(True) else: self.btn_undo.setVisible(False) self.btn_play.show() def get_status_string(self): if self.status == 0: return "Draw" elif self.status == 1: return "You win" elif self.status == 2: return "You lose" elif self.status == 3: return "Draw (win)" elif self.status == 4: return "Draw (lose)" elif self.status == -1: return "Checkers" elif self.status == -2: return "Checkers" def difficulty_radio(self, btn_id): self.btn_lvl1.setChecked(False) self.btn_lvl3.setChecked(False) self.btn_lvl2.setChecked(False) if btn_id == 1: self.btn_lvl1.setChecked(True) elif btn_id == 2: self.btn_lvl2.setChecked(True) elif btn_id == 3: self.btn_lvl3.setChecked(True) def is_force_move(self): return self.btn_force_jump.isChecked() def is_pc_move(self): return self.btn_pc_first.isChecked() def get_radio_selected(self): if self.btn_lvl3.isChecked(): return 3 elif self.btn_lvl2.isChecked(): return 2 elif self.btn_lvl1.isChecked(): return 1 else: return 2 def get_difficulty(self): if self.btn_lvl3.isChecked(): return 5 elif self.btn_lvl2.isChecked(): return 4 elif self.btn_lvl1.isChecked(): return 3 else: return 4 def undo_move(self): remembered = self.main_window.remember_choice_config undo = self.main_window.history_table.pop() matrix = undo[0] self.main_window.start_game(remembered[0], False, remembered[2], matrix) # heuristic bar is updated 50ms so it will happend after, because this undo create new game with 'undo' # starting matrix QTimer.singleShot( 50, lambda: self.main_window.update_heuristic_bar(undo[1])) def set_remembered(self): remembered = self.main_window.remember_choice_config self.btn_force_jump.setChecked(remembered[0]) self.btn_pc_first.setChecked(remembered[1]) self.difficulty_radio(remembered[2]) def save_remembered(self): self.main_window.remember_choice_config[ 0] = self.btn_force_jump.isChecked() self.main_window.remember_choice_config[ 1] = self.btn_pc_first.isChecked() self.main_window.remember_choice_config[2] = self.get_radio_selected()
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setMinimumSize(QSize(400, 250)) self.setWindowTitle("Automate outlook mailing") self.extractAction = QtWidgets.QAction("&Info", self) self.extractAction.setShortcut("Ctrl+I") self.extractAction.setStatusTip('Get Info') self.extractAction.triggered.connect(self.get_info) self.statusBar() self.mainMenu = self.menuBar() self.aboutMenu = self.mainMenu.addMenu('&About') self.aboutMenu.addAction(self.extractAction) self.LabelExcelFile = QLabel(self) self.LabelExcelFile.setText('Excel :') self.LabelExcelFile.move(20, 20) self.line = QLineEdit(self) self.line.move(80, 20) self.line.resize(200, 25) self.searchFileButton = QPushButton("Load", self) self.searchFileButton.clicked.connect(self.searchAndLoadFile) self.searchFileButton.move(300, 20) self.searchFileButton.resize(75, 25) # self.layout.addWidget(self.searchFileButton,2, 1, 1, 1) self.nameLabel = QLabel(self) self.nameLabel.setText('Subject :') self.nameLabel.move(20, 60) self.LineSubject = QLineEdit(self) self.LineSubject.move(80, 60) self.LineSubject.resize(200, 25) self.LabelArea = QLabel(self) self.LabelArea.setText('Body :') self.LabelArea.move(20, 100) self.text_area = QTextEdit(self) self.text_area.resize(200, 80) self.text_area.move(80, 100) self.pybutton = QPushButton('Save', self) self.pybutton.clicked.connect(self.clickMethod) self.pybutton.resize(200,32) self.pybutton.move(80, 200) self.createExample = QPushButton('Example File', self) self.createExample.clicked.connect(myExcel.CreateExample) self.createExample.resize(75,32) self.createExample.move(300, 100) self.autorun = QPushButton('Auto Run Off', self) self.autorun.clicked.connect(self.set_auto_run) self.autorun.resize(75,32) self.autorun.move(300, 150) self.autorun.setCheckable(True) self.start = QPushButton('Run', self) self.start.clicked.connect(self.run_business) self.start.resize(75,32) self.start.move(300, 200) def run_business(self): print("The business program starts") myBusiness.the_aim_of_the_program() pass def set_auto_run(self): """ print("Select Example") #self.button2.click() self.button2.setChecked(True) if self.button4.isChecked(): print("button4 is checked") self.button4.setChecked(False) pass else: print("button4 isnt checked") pass """ if self.autorun.isChecked(): print("autorun button is checked") self.autorun.setChecked(True) self.autorun.setText('Auto Run On') self.save_something('Automate outlook mailing','auto_run', 'True') pass else: self.autorun.setChecked(False) print("autorun button isnt checked") self.autorun.setText('Auto Run Off') self.save_something('Automate outlook mailing','auto_run', 'False') pass print("The business program starts") # myBusiness.the_aim_of_the_program() pass def save_something(self,section,somekey,something): if myConfig.configuration_file_has_been_persisted(): print("The program starts") #print(myConfig.get_saved_data("EXCEL","subject")) else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass myConfig.configuration_file_set_something_to_save(section,somekey,something) pass def clickMethod(self): print('Your name: ' + self.line.text()) if myConfig.configuration_file_has_been_persisted(): print("The program starts") print(myConfig.get_saved_data("EXCEL","subject")) else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass if self.line.text() != "": myConfig.configuration_file_set_something_to_save("EXCEL","file",self.line.text()) pass if self.LineSubject.text() != "": myConfig.configuration_file_set_something_to_save("EMAIL","subject",self.LineSubject.text()) pass if self.text_area.toPlainText() != "": myConfig.configuration_file_set_something_to_save("EMAIL","body",self.text_area.toPlainText()) pass # print(self.text_area.toPlainText()) #print(myConfig.get_mail_data()['subject']) # myConfig.configuration_file_create_persist() pass """ excel_file = "~tempfile.1.xlsx" #myExcel.getDataFromExcel(excel_file) if myConfig.configuration_file_has_been_persisted(): print("The program starts") print(myConfig.check_data("EMAIL",'subject')) # for key in (myConfig.get_mail_data()): print(key) if myConfig.check_data("EMAIL",'subject'): print(myConfig.get_mail_data()['subject']) myConfig.get_mail_data()['subject'] pass else: myConfig.configuration_file_create_persist() pass #myExcel.getDataFromExcel(excel_file,) pass else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass # myConfig.configuration_file_create_persist() pass """ def setFromConfigurationFile(self): #excel_file = "~tempfile.1.xlsx" #myExcel.getDataFromExcel(excel_file) if myConfig.configuration_file_has_been_persisted(): print("The program starts") #print(myConfig.check_data("EMAIL",'subject')) # for key in (myConfig.get_mail_data()): print(key) if myConfig.check_data("EMAIL",'subject'): #print(myConfig.get_mail_data()['subject']) #myConfig.get_mail_data()['subject'] print() print() print() self.line.setText(myConfig.get_saved_data("EXCEL",'file')) # self.line.setText("Hola perro") self.LineSubject.setText(myConfig.get_saved_data("EMAIL",'subject')) self.text_area.setText(myConfig.get_saved_data("EMAIL",'body')) if myConfig.check_data('Automate outlook mailing','auto_run'): if myConfig.get_saved_data('Automate outlook mailing','auto_run') == "True": self.autorun.setChecked(True) self.autorun.setText('Auto Run On') print('Auto Run On') pass else: self.autorun.setChecked(False) self.autorun.setText('Auto Run Off') print('Auto Run Off') pass pass else: print('auto_run not exist') myConfig.configuration_file_create_persist() pass pass else: myConfig.configuration_file_create_persist() pass #myExcel.getDataFromExcel(excel_file,) pass else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass pass def searchAndLoadFile(self): #path_to_file, _ = QFileDialog.getOpenFileName(self, self.tr("Load Image"), self.tr("~/Desktop/"), self.tr("Images (*.jpg)")) current_location = myConfig.getPathExternal("") path_to_file, _ = QFileDialog.getOpenFileName(self, self.tr("Load Excel"), self.tr("~/Desktop/"), self.tr(current_location+" (*.xlsx)")) #self.test(path_to_file) print(path_to_file) #self.testFuncion(path_to_file) # self.filenameLoaded = path_to_file self.line.setText(path_to_file) def close_application(self): choice = QtWidgets.QMessageBox.question(self, 'Extract!', "Get into the chopper?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if choice == QtWidgets.QMessageBox.Yes: print("Extracting Naaaaaaoooww!!!!") sys.exit() else: pass def close_application_timeout(self): print("Shooting down") """ import time time.sleep(myBusiness.get_after_delay()) sys.exit() """ QtCore.QTimer.singleShot(30000, self.close) pass def get_info(self): # https://stackoverflow.com/questions/15682665/how-to-add-custom-button-to-a-qmessagebox-in-pyqt4 # https://pythonprogramming.net/pop-up-messages-pyqt-tutorial/ """ self.msgBox = QtWidgets.QMessageBox() self.msgBox.setText('What to do?') self.msgBox.addButton(QtWidgets.QPushButton('Accept'), QtWidgets.QMessageBox.YesRole) self.msgBox.addButton(QtWidgets.QPushButton('Reject'), QtWidgets.QMessageBox.NoRole) self.msgBox.addButton(QtWidgets.QPushButton('Cancel'), QtWidgets.QMessageBox.RejectRole) ret = self.msgBox.exec_() self.msgBox.question(self, 'About Developer', "my name is luca if you want to contact me\nmy email is [email protected]", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) #ret = self.msgBox.exec_() """ choice = QtWidgets.QMessageBox.question(self, 'About Developer', "my name is luca, if you want to contact me\nyou can send me an email to\[email protected]\n\nSend email?(yes/no)", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if choice == QtWidgets.QMessageBox.Yes: print("Redirect to send email") import webbrowser webbrowser.open('mailto:[email protected]?subject=Hi Luca&body=How are you?🧙♂️') # Go to example.com # sys.exit() else: pass
class SidePanel(QDockWidget): saved = Signal(dict) def __init__(self): super(SidePanel, self).__init__() # Internal variables self._coverdir = path.join("data", "images", "covers") self._id = 0 self._imagedata = "" size = [220, 16] # Width, Height (for QLineEdits/QTextEdits) # QDockWidget settings self.setAllowedAreas(Qt.RightDockWidgetArea) self.setFeatures(QDockWidget.DockWidgetClosable) self.setFixedWidth(350) self.setVisible(False) # Fonts bold = QFont() bold.setBold(True) boldUnderline = QFont() boldUnderline.setBold(True) boldUnderline.setUnderline(True) # Horizontal line hline = QFrame() hline.setFrameShape(QFrame.HLine) hline.setFrameShadow(QFrame.Sunken) """Widgets""" # Cover self.cover = QLabel() self.cover.setAlignment(Qt.AlignCenter) self.cover.setMinimumHeight(200) self.cover.setMaximumSize(self.width(), 250) # Buttons self.fetchInfoButton = QPushButton("Fetch missing info") self.fetchInfoButton.setToolTip("Try to fetch info from MobyGames") self.fetchInfoButton.clicked.connect(self._fetchInfo) self.editDetailsButton = QPushButton("Edit") self.editDetailsButton.setCheckable(True) self.editDetailsButton.clicked.connect(self._editDetails) self.saveDetailsButton = QPushButton("Save") self.saveDetailsButton.clicked.connect(self._saveInfo) self.fetchPriceButton = QPushButton("Update price data") self.fetchPriceButton.setToolTip("Try to update price data from Pricecharting") self.fetchPriceButton.clicked.connect(self._fetchPriceData) self.savePriceButton = QPushButton("Save") self.savePriceButton.clicked.connect(self._saveInfo) # Info layout widgets self.nameInfoLabel = QLabel("Name:") self.nameInfoLabel.setFont(bold) self.nameDataLabel = QLabel() self.nameDataLabel.setWordWrap(True) self.platformInfoLabel = QLabel("Platform:") self.platformInfoLabel.setFont(bold) self.platformDataLabel = QLabel() self.publisherInfoLabel = QLabel("Publisher:") self.publisherInfoLabel.setFont(bold) self.publisherDataLabel = QLabel() self.developerInfoLabel = QLabel("Developer:") self.developerInfoLabel.setFont(bold) self.developerDataLabel = QLabel() self.regionInfoLabel = QLabel("Region:") self.regionInfoLabel.setFont(bold) self.regionDataLabel = QLabel() self.codeInfoLabel = QLabel("Code:") self.codeInfoLabel.setFont(bold) self.codeDataLabel = QLabel() self.codeDataLabel.setWordWrap(True) self.itemInfoLabel = QLabel("Game:") self.itemInfoLabel.setFont(bold) self.itemDataLabel = QLabel() self.boxInfoLabel = QLabel("Box:") self.boxInfoLabel.setFont(bold) self.boxDataLabel = QLabel() self.manualInfoLabel = QLabel("Manual:") self.manualInfoLabel.setFont(bold) self.manualDataLabel = QLabel() self.genreInfoLabel = QLabel("Genre:") self.genreInfoLabel.setFont(bold) self.genreDataLabel = QLabel() self.yearInfoLabel = QLabel("Year:") self.yearInfoLabel.setFont(bold) self.yearDataLabel = QLabel() self.commentInfoLabel = QLabel("Comment:") self.commentInfoLabel.setFont(bold) self.commentDataLabel = QLabel() self.commentDataLabel.setWordWrap(True) self.platformsInfoLabel = QLabel("Available for:") self.platformsInfoLabel.setFont(bold) self.platformsDataLabel = QLabel() self.platformsDataLabel.setWordWrap(True) self.platformsDataLabel.setMaximumHeight(50) # Can get quite large otherwise # Edit layout widgets self.nameEditLabel = QLabel("Name:") self.nameEditLabel.setFont(bold) self.nameDataTE = QTextEdit() self.nameDataTE.setMaximumSize(size[0], size[1] * 2) self.platformEditLabel = QLabel("Platform:") self.platformEditLabel.setFont(bold) self.platformDataLE = QLineEdit() self.platformDataLE.setMaximumSize(size[0], size[1]) self.publisherEditLabel = QLabel("Publisher:") self.publisherEditLabel.setFont(bold) self.publisherDataLE = QLineEdit() self.publisherDataLE.setMaximumSize(size[0], size[1]) self.developerEditLabel = QLabel("Developer:") self.developerEditLabel.setFont(bold) self.developerDataLE = QLineEdit() self.developerDataLE.setMaximumSize(size[0], size[1]) self.regionEditLabel = QLabel("Region:") self.regionEditLabel.setFont(bold) self.regionDataCoB = QComboBox() self.regionDataCoB.addItems(("NTSC (JP)", "NTSC (NA)", "PAL")) self.regionDataCoB.setMinimumWidth(size[0]) # If not set it will be too small self.regionDataCoB.setMaximumSize(size[0], size[1]) self.codeEditLabel = QLabel("Code:") self.codeEditLabel.setFont(bold) self.codeDataLE = QLineEdit() self.codeDataLE.setMaximumSize(size[0], size[1]) self.itemEditLabel = QLabel("Game:") self.itemEditLabel.setFont(bold) self.itemDataCB = QCheckBox() self.itemDataCB.setChecked(False) self.boxEditLabel = QLabel("Box:") self.boxEditLabel.setFont(bold) self.boxDataCB = QCheckBox() self.boxDataCB.setChecked(False) self.manualEditLabel = QLabel("Manual:") self.manualEditLabel.setFont(bold) self.manualDataCB = QCheckBox() self.manualDataCB.setChecked(False) self.genreEditLabel = QLabel("Genre:") self.genreEditLabel.setFont(bold) self.genreDataLE = QLineEdit() self.genreDataLE.setMaximumSize(size[0], size[1]) self.yearEditLabel = QLabel("Year:") self.yearEditLabel.setFont(bold) self.yearDataLE = QLineEdit() self.yearDataLE.setMaximumSize(size[0], size[1]) self.commentEditLabel = QLabel("Comment:") self.commentEditLabel.setFont(bold) self.commentDataTE = QTextEdit() self.commentDataTE.setMaximumSize(size[0], size[1] * 2) self.platformsEditLabel = QLabel("Available for:") self.platformsEditLabel.setFont(bold) self.platformsDataTE = QTextEdit() self.platformsDataTE.setMaximumSize(size[0], size[1] * 2) # Price widgets self.paidPriceLabel = QLabel("Paid:") self.paidPriceLabel.setFont(bold) self.paidPriceDataLE = QLineEdit() self.paidPriceDataLE.setMaximumSize(60, size[1]) self.paidPriceDataLE.setAlignment(Qt.AlignRight) self.loosePriceLabel = QLabel("Loose:") self.loosePriceLabel.setFont(bold) self.loosePriceDataLabel = QLabel() self.loosePriceDataLabel.setAlignment(Qt.AlignRight) self.cibPriceLabel = QLabel("CIB:") self.cibPriceLabel.setFont(bold) self.cibPriceDataLabel = QLabel() self.cibPriceDataLabel.setAlignment(Qt.AlignRight) self.newPriceLabel = QLabel("New:") self.newPriceLabel.setFont(bold) self.newPriceDataLabel = QLabel() self.newPriceDataLabel.setAlignment(Qt.AlignRight) """Layouts""" # Cover self.coverVbox = QVBoxLayout() self.coverVbox.addWidget(self.cover, 1) self.coverVbox.addWidget(hline, 0) # Buttons self.detailsButtonHbox = QHBoxLayout() self.detailsButtonHbox.addWidget(self.fetchInfoButton, 0) self.detailsButtonHbox.addWidget(self.editDetailsButton, 0) self.detailsButtonHbox.addWidget(self.saveDetailsButton, 0) self.priceButtonHbox = QHBoxLayout() self.priceButtonHbox.addWidget(self.fetchPriceButton, 0) self.priceButtonHbox.addWidget(self.savePriceButton, 0) # Info layouts self.nameInfoHbox = QHBoxLayout() self.nameInfoHbox.addWidget(self.nameInfoLabel, 0) self.nameInfoHbox.addWidget(self.nameDataLabel, 0) self.platformInfoHbox = QHBoxLayout() self.platformInfoHbox.addWidget(self.platformInfoLabel, 0) self.platformInfoHbox.addWidget(self.platformDataLabel, 0) self.publisherInfoHbox = QHBoxLayout() self.publisherInfoHbox.addWidget(self.publisherInfoLabel, 0) self.publisherInfoHbox.addWidget(self.publisherDataLabel, 0) self.developerInfoHbox = QHBoxLayout() self.developerInfoHbox.addWidget(self.developerInfoLabel, 0) self.developerInfoHbox.addWidget(self.developerDataLabel, 0) self.regionInfoHbox = QHBoxLayout() self.regionInfoHbox.addWidget(self.regionInfoLabel, 0) self.regionInfoHbox.addWidget(self.regionDataLabel, 0) self.codeInfoHbox = QHBoxLayout() self.codeInfoHbox.addWidget(self.codeInfoLabel, 0) self.codeInfoHbox.addWidget(self.codeDataLabel, 0) self.itemInfoHbox = QHBoxLayout() self.itemInfoHbox.addWidget(self.itemInfoLabel, 0) self.itemInfoHbox.addWidget(self.itemDataLabel, 0) self.boxInfoHbox = QHBoxLayout() self.boxInfoHbox.addWidget(self.boxInfoLabel, 0) self.boxInfoHbox.addWidget(self.boxDataLabel, 0) self.manualInfoHbox = QHBoxLayout() self.manualInfoHbox.addWidget(self.manualInfoLabel, 0) self.manualInfoHbox.addWidget(self.manualDataLabel, 0) self.genreInfoHbox = QHBoxLayout() self.genreInfoHbox.addWidget(self.genreInfoLabel, 0) self.genreInfoHbox.addWidget(self.genreDataLabel, 0) self.yearInfoHbox = QHBoxLayout() self.yearInfoHbox.addWidget(self.yearInfoLabel, 0) self.yearInfoHbox.addWidget(self.yearDataLabel, 0) self.commentInfoHbox = QHBoxLayout() self.commentInfoHbox.addWidget(self.commentInfoLabel, 0) self.commentInfoHbox.addWidget(self.commentDataLabel, 0) self.platformsInfoHbox = QHBoxLayout() self.platformsInfoHbox.addWidget(self.platformsInfoLabel, 0) self.platformsInfoHbox.addWidget(self.platformsDataLabel, 0) # Edit layouts self.nameEditHbox = QHBoxLayout() self.nameEditHbox.addWidget(self.nameEditLabel, 0) self.nameEditHbox.addWidget(self.nameDataTE, 0) self.platformEditHbox = QHBoxLayout() self.platformEditHbox.addWidget(self.platformEditLabel, 0) self.platformEditHbox.addWidget(self.platformDataLE, 0) self.publisherEditHbox = QHBoxLayout() self.publisherEditHbox.addWidget(self.publisherEditLabel, 0) self.publisherEditHbox.addWidget(self.publisherDataLE, 0) self.developerEditHbox = QHBoxLayout() self.developerEditHbox.addWidget(self.developerEditLabel, 0) self.developerEditHbox.addWidget(self.developerDataLE, 0) self.regionEditHbox = QHBoxLayout() self.regionEditHbox.addWidget(self.regionEditLabel, 0) self.regionEditHbox.addWidget(self.regionDataCoB, 0) self.codeEditHbox = QHBoxLayout() self.codeEditHbox.addWidget(self.codeEditLabel, 0) self.codeEditHbox.addWidget(self.codeDataLE, 0) self.itemEditHbox = QHBoxLayout() self.itemEditHbox.addWidget(self.itemEditLabel, 0) self.itemEditHbox.addWidget(self.itemDataCB, 0) self.itemEditHbox.addSpacing(135) self.boxEditHbox = QHBoxLayout() self.boxEditHbox.addWidget(self.boxEditLabel, 0) self.boxEditHbox.addWidget(self.boxDataCB, 0) self.boxEditHbox.addSpacing(135) self.manualEditHbox = QHBoxLayout() self.manualEditHbox.addWidget(self.manualEditLabel, 0) self.manualEditHbox.addWidget(self.manualDataCB, 0) self.manualEditHbox.addSpacing(135) self.genreEditHbox = QHBoxLayout() self.genreEditHbox.addWidget(self.genreEditLabel, 0) self.genreEditHbox.addWidget(self.genreDataLE, 0) self.yearEditHbox = QHBoxLayout() self.yearEditHbox.addWidget(self.yearEditLabel, 0) self.yearEditHbox.addWidget(self.yearDataLE, 0) self.commentEditHbox = QHBoxLayout() self.commentEditHbox.addWidget(self.commentEditLabel, 0) self.commentEditHbox.addWidget(self.commentDataTE, 0) self.platformsEditHbox = QHBoxLayout() self.platformsEditHbox.addWidget(self.platformsEditLabel, 0) self.platformsEditHbox.addWidget(self.platformsDataTE, 0) # Price layouts self.paidPriceHbox = QHBoxLayout() self.paidPriceHbox.addWidget(self.paidPriceLabel, 0) self.paidPriceHbox.addWidget(self.paidPriceDataLE, 0) self.loosePriceHbox = QHBoxLayout() self.loosePriceHbox.addWidget(self.loosePriceLabel, 0) self.loosePriceHbox.addWidget(self.loosePriceDataLabel, 0) self.cibPriceHbox = QHBoxLayout() self.cibPriceHbox.addWidget(self.cibPriceLabel, 0) self.cibPriceHbox.addWidget(self.cibPriceDataLabel, 0) self.newPriceHbox = QHBoxLayout() self.newPriceHbox.addWidget(self.newPriceLabel, 0) self.newPriceHbox.addWidget(self.newPriceDataLabel, 0) # Info layout self.infoLayout = QVBoxLayout() self.infoLayout.addLayout(self.nameInfoHbox, 0) self.infoLayout.addLayout(self.platformInfoHbox, 0) self.infoLayout.addLayout(self.publisherInfoHbox, 0) self.infoLayout.addLayout(self.developerInfoHbox, 0) self.infoLayout.addLayout(self.genreInfoHbox, 0) self.infoLayout.addLayout(self.regionInfoHbox, 0) self.infoLayout.addLayout(self.yearInfoHbox, 0) self.infoLayout.addLayout(self.codeInfoHbox, 0) self.infoLayout.addLayout(self.itemInfoHbox, 0) self.infoLayout.addLayout(self.boxInfoHbox, 0) self.infoLayout.addLayout(self.manualInfoHbox, 0) self.infoLayout.addLayout(self.commentInfoHbox, 0) self.infoLayout.addLayout(self.platformsInfoHbox, 0) # Edit layout self.editLayout = QVBoxLayout() self.editLayout.addLayout(self.nameEditHbox, 0) self.editLayout.addLayout(self.platformEditHbox, 0) self.editLayout.addLayout(self.publisherEditHbox, 0) self.editLayout.addLayout(self.developerEditHbox, 0) self.editLayout.addLayout(self.genreEditHbox, 0) self.editLayout.addLayout(self.regionEditHbox, 0) self.editLayout.addLayout(self.yearEditHbox, 0) self.editLayout.addLayout(self.codeEditHbox, 0) self.editLayout.addLayout(self.itemEditHbox, 0) self.editLayout.addLayout(self.boxEditHbox, 0) self.editLayout.addLayout(self.manualEditHbox, 0) self.editLayout.addLayout(self.commentEditHbox, 0) self.editLayout.addLayout(self.platformsEditHbox, 0) # Price layout self.priceLayout = QVBoxLayout() self.priceLayout.addLayout(self.paidPriceHbox, 0) self.priceLayout.addLayout(self.loosePriceHbox, 0) self.priceLayout.addLayout(self.cibPriceHbox, 0) self.priceLayout.addLayout(self.newPriceHbox, 0) self.priceLayout.addStretch(1) self.priceLayout.addLayout(self.priceButtonHbox, 0) """Main layout""" self.infoWidget = QWidget() self.infoWidget.setLayout(self.infoLayout) self.editWidget = QWidget() self.editWidget.setLayout(self.editLayout) # Add info and edit widgets to a stacked layout so we can switch layouts when editing self.stackedLayout = QStackedLayout() self.stackedLayout.addWidget(self.infoWidget) self.stackedLayout.addWidget(self.editWidget) self.stackedLayout.setCurrentIndex(0) # Default to info layout self.detailsLayout = QVBoxLayout() self.detailsLayout.addLayout(self.coverVbox, 1) self.detailsLayout.addLayout(self.stackedLayout, 0) self.detailsLayout.addLayout(self.detailsButtonHbox, 0) self.detailsWidget = QWidget() self.detailsWidget.setLayout(self.detailsLayout) self.priceWidget = QWidget() self.priceWidget.setLayout(self.priceLayout) self.tab = QTabWidget() self.tab.addTab(self.detailsWidget, "Details") self.tab.addTab(self.priceWidget, "Price info") self.setWidget(self.tab) def _editDetails(self): if self.editDetailsButton.isChecked(): self._updateWidgetData(1) self.stackedLayout.setCurrentIndex(1) else: self._updateWidgetData(0) self.stackedLayout.setCurrentIndex(0) def _fetchInfo(self): name = self.nameDataLabel.text() platform = self.platformDataLabel.text() region = self.regionDataLabel.text() info = getMobyRelease(name, platform, region) if "image" in info.keys() and info["image"] != "": self._imagedata = requests.get(info["image"]).content pixmap = QPixmap() pixmap.loadFromData(self._imagedata) w = self.cover.width() h = self.cover.height() self.cover.setPixmap(pixmap.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) if self.publisherDataLabel.text() == "": self.publisherDataLabel.setText(info["publisher"]) if self.developerDataLabel.text() == "": self.developerDataLabel.setText(info["developer"]) if self.genreDataLabel.text() == "": self.genreDataLabel.setText(info["genre"]) if self.yearDataLabel.text() == "": self.yearDataLabel.setText(info["year"]) if self.codeDataLabel.text() == "": self.codeDataLabel.setText(info["code"]) if self.platformsDataLabel.text() == "": self.platformsDataLabel.setText(info["platforms"]) # Update edit widgets if we're editing: if self.editDetailsButton.isChecked(): self._updateWidgetData(1) def _fetchPriceData(self): name = self.nameDataLabel.text() platform = self.platformDataLabel.text() region = self.regionDataLabel.text() prices = getPriceData(name, platform, region) self.loosePriceDataLabel.setText(prices["loose"]) self.cibPriceDataLabel.setText(prices["cib"]) self.newPriceDataLabel.setText(prices["new"]) def _saveInfo(self): if self.editDetailsButton.isChecked(): self._updateWidgetData(0) paidPrice = str(self.paidPriceDataLE.text()).replace(",", ".") # Better use '.' as decimal denominator info = {"id": self._id, "name": self.nameDataLabel.text(), "platform": self.platformDataLabel.text(), "publisher": self.publisherDataLabel.text(), "developer": self.developerDataLabel.text(), "genre": self.genreDataLabel.text(), "region": self.regionDataLabel.text(), "year": self.yearDataLabel.text(), "code": self.codeDataLabel.text(), "item": self.itemDataLabel.text(), "box": self.boxDataLabel.text(), "manual": self.manualDataLabel.text(), "comment": self.commentDataLabel.text(), "platforms": self.platformsDataLabel.text(), "price": ",".join((paidPrice, self.loosePriceDataLabel.text(), self.cibPriceDataLabel.text(), self.newPriceDataLabel.text()))} # Save imagedata to file if self._imagedata != "" and not path.exists(path.join(self._coverdir, str(self._id) + ".jpg")): with open(path.join(self._coverdir, str(self._id) + ".jpg"), "wb") as f: f.write(self._imagedata) self.saved.emit(info) def _updateWidgetData(self, layoutIndex: int): if layoutIndex == 0: self.nameDataLabel.setText(self.nameDataTE.toPlainText()) self.platformDataLabel.setText(self.platformDataLE.text()) self.publisherDataLabel.setText(self.publisherDataLE.text()) self.developerDataLabel.setText(self.developerDataLE.text()) self.genreDataLabel.setText(self.genreDataLE.text()) self.regionDataLabel.setText(self.regionDataCoB.currentText()) self.yearDataLabel.setText(self.yearDataLE.text()) self.codeDataLabel.setText(self.codeDataLE.text()) self.itemDataLabel.setText("Yes") if self.itemDataCB.isChecked() else self.itemDataLabel.setText("No") self.boxDataLabel.setText("Yes") if self.boxDataCB.isChecked() else self.boxDataLabel.setText("No") self.manualDataLabel.setText("Yes") if self.manualDataCB.isChecked() else self.manualDataLabel.setText("No") self.commentDataLabel.setText(self.commentDataTE.toPlainText()) self.platformsDataLabel.setText(self.platformsDataTE.toPlainText()) else: self.nameDataTE.setText(self.nameDataLabel.text()) self.platformDataLE.setText(self.platformDataLabel.text()) self.publisherDataLE.setText(self.publisherDataLabel.text()) self.developerDataLE.setText(self.developerDataLabel.text()) self.genreDataLE.setText(self.genreDataLabel.text()) self.regionDataCoB.setCurrentIndex(0) if self.regionDataLabel.text == "NTSC (JP)"\ else self.regionDataCoB.setCurrentIndex(1) if self.regionDataLabel.text == "NTSC (NA)"\ else self.regionDataCoB.setCurrentIndex(2) self.yearDataLE.setText(self.yearDataLabel.text()) self.codeDataLE.setText(self.codeDataLabel.text()) self.itemDataCB.setChecked(True) if self.itemDataLabel.text() == "Yes" \ else self.itemDataCB.setChecked("False") self.boxDataCB.setChecked(True) if self.boxDataLabel.text() == "Yes" \ else self.boxDataCB.setChecked(False) self.manualDataCB.setChecked(True) if self.manualDataLabel.text() == "Yes" \ else self.manualDataCB.setChecked(False) self.commentDataTE.setText(self.commentDataLabel.text()) self.platformsDataTE.setText(self.platformsDataLabel.text()) def showDetails(self, info: dict): if not self.isVisible(): self.setVisible(True) self.tab.setCurrentIndex(0) # Show details tab initially if self.editDetailsButton.isChecked(): self.editDetailsButton.setChecked(False) self.stackedLayout.setCurrentIndex(0) # Show info layout initially self._id = info["id"] self._imagedata = "" pixmap = path.join(self._coverdir, "none.png") if path.exists(path.join(self._coverdir, str(self._id) + ".jpg")) and info["table"] == "games": pixmap = path.join(self._coverdir, str(self._id) + ".jpg") p = QPixmap(pixmap) w = self.cover.width() h = self.cover.height() self.cover.setPixmap(p.scaled(w, h, Qt.KeepAspectRatio, Qt.SmoothTransformation)) # Price data is stored in form $x,$x,$x,$x [paid, loose, cib, new] paidPrice, loosePrice, cibPrice, newPrice = info["price"].split(",") self.nameDataLabel.setText(info["name"]) self.platformDataLabel.setText(info["platform"]) self.regionDataLabel.setText(info["region"]) self.boxDataLabel.setText(info["box"]) self.manualDataLabel.setText(info["manual"]) self.yearDataLabel.setText(str(info["year"])) self.commentDataLabel.setText(info["comment"]) self.paidPriceDataLE.setText(paidPrice) self.loosePriceDataLabel.setText(loosePrice) self.cibPriceDataLabel.setText(cibPrice) self.newPriceDataLabel.setText(newPrice) if info["table"] == "games": self.publisherDataLabel.setText(info["publisher"]) self.developerDataLabel.setText(info["developer"]) self.genreInfoLabel.setText("Genre:") self.genreEditLabel.setText("Genre:") self.genreDataLabel.setText(info["genre"]) self.codeInfoLabel.setText("Code:") self.codeInfoLabel.setVisible(True) self.codeEditLabel.setText("Code") self.codeEditLabel.setVisible(True) self.codeDataLabel.setText(info["code"]) self.codeDataLabel.setVisible(True) self.codeDataLE.setVisible(True) self.itemInfoLabel.setText("Game:") self.itemEditLabel.setText("Game:") self.itemDataLabel.setText(info["game"]) self.platformsDataLabel.setText(info["platforms"]) self.platformsDataLabel.setVisible(True) self.platformsInfoLabel.setVisible(True) self.fetchInfoButton.setEnabled(True) self.fetchInfoButton.setVisible(True) self.fetchInfoButton.setToolTip("Try to fetch info from MobyGames") self.saveDetailsButton.setEnabled(True) self.saveDetailsButton.setVisible(True) elif info["table"] == "consoles": self.genreInfoLabel.setText("Country:") self.genreEditLabel.setText("Country:") self.genreDataLabel.setText(info["country"]) self.codeInfoLabel.setText("Serial Number:") self.codeInfoLabel.setVisible(True) self.codeEditLabel.setText("Serial Number:") self.codeEditLabel.setVisible(True) self.codeDataLabel.setText(info["serial number"]) self.codeDataLabel.setVisible(True) self.codeDataLE.setVisible(True) self.itemInfoLabel.setText("Console:") self.itemEditLabel.setText("Console:") self.itemDataLabel.setText(info["console"]) self.platformsInfoLabel.setVisible(False) self.platformsDataLabel.setVisible(False) self.fetchInfoButton.setEnabled(False) self.fetchInfoButton.setToolTip("Not available for Consoles tab") elif info["table"] == "accessories": self.genreInfoLabel.setText("Country:") self.genreEditLabel.setText("Country:") self.genreDataLabel.setText(info["country"]) self.itemInfoLabel.setText("Accessory:") self.itemEditLabel.setText("Accessory:") self.itemDataLabel.setText(info["accessory"]) self.codeInfoLabel.setVisible(False) self.codeEditLabel.setVisible(False) self.codeDataLabel.setVisible(False) self.codeDataLE.setVisible(False) self.platformsInfoLabel.setVisible(False) self.platformsDataLabel.setVisible(False) self.fetchInfoButton.setEnabled(False) self.fetchInfoButton.setToolTip("Not avaiable for Accessories tab") def hideDetails(self): self.setVisible(False)
class StreamFieldsWidget(QDialog): """ A stream widget containing schema-specific properties. """ def __init__(self, parent): super().__init__() self.setParent(parent) self.setLayout(QGridLayout()) self.setWindowModality(Qt.WindowModal) self.setModal(True) self.minimum_spinbox_value = 0 self.maximum_spinbox_value = 100_000_000 self.advanced_options_enabled = False self.hs00_unimplemented_label = QLabel( "hs00 (Event histograms) has not yet been fully implemented.") self.schema_label = QLabel("Schema: ") self.schema_combo = QComboBox() self.topic_label = QLabel("Topic: ") self.topic_line_edit = QLineEdit() self.topic_line_edit.setPlaceholderText( "[broker][:port, default=9092]/topic") self.source_label = QLabel("Source: ") self.source_line_edit = QLineEdit() self.array_size_label = QLabel("Array size") self.array_size_spinbox = QSpinBox() self.array_size_spinbox.setMaximum(np.iinfo(np.int32).max) self.type_label = QLabel("Type: ") self.type_combo = QComboBox() self.type_combo.addItems(F142_TYPES) self.type_combo.setCurrentText("double") self.value_units_edit = QLineEdit() self.value_units_label = QLabel("Value Units:") self.show_advanced_options_button = QPushButton( text="Show/hide advanced options") self.show_advanced_options_button.setCheckable(True) self.show_advanced_options_button.clicked.connect( self.advanced_options_button_clicked) self._set_up_f142_group_box() self._set_up_ev42_group_box() self.scalar_radio = QRadioButton(text="Scalar") self.scalar_radio.clicked.connect(partial(self._show_array_size, False)) self.scalar_radio.setChecked(True) self.scalar_radio.clicked.emit() self.array_radio = QRadioButton(text="Array") self.array_radio.clicked.connect(partial(self._show_array_size, True)) self.schema_combo.currentTextChanged.connect(self._schema_type_changed) self.schema_combo.addItems([e.value for e in WriterModules]) self.ok_button = QPushButton("OK") self.ok_button.clicked.connect(self.parent().close) self.layout().addWidget(self.schema_label, 0, 0) self.layout().addWidget(self.schema_combo, 0, 1) self.layout().addWidget(self.topic_label, 1, 0) self.layout().addWidget(self.topic_line_edit, 1, 1) self.layout().addWidget(self.source_label, 2, 0) self.layout().addWidget(self.source_line_edit, 2, 1) self.layout().addWidget(self.value_units_label, 3, 0) self.layout().addWidget(self.value_units_edit, 3, 1) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) self.layout().addWidget(self.type_label, 4, 0) self.layout().addWidget(self.type_combo, 4, 1) self.layout().addWidget(self.scalar_radio, 5, 0) self.layout().addWidget(self.array_radio, 5, 1) self.layout().addWidget(self.array_size_label, 6, 0) self.layout().addWidget(self.array_size_spinbox, 6, 1) self.layout().addWidget(self.hs00_unimplemented_label, 7, 0, 1, 2) # Spans both rows self.layout().addWidget(self.show_advanced_options_button, 8, 0, 1, 2) self.layout().addWidget(self.f142_advanced_group_box, 9, 0, 1, 2) self.layout().addWidget(self.ev42_advanced_group_box, 10, 0, 1, 2) self.layout().addWidget(self.ok_button, 11, 0, 1, 2) self._schema_type_changed(self.schema_combo.currentText()) def advanced_options_button_clicked(self): self._show_advanced_options( show=self.show_advanced_options_button.isChecked()) def _set_up_ev42_group_box(self): """ Sets up the UI for ev42 advanced options. """ self.ev42_nexus_elements = [ NEXUS_INDICES_INDEX_EVERY_MB, NEXUS_INDICES_INDEX_EVERY_KB, NEXUS_CHUNK_CHUNK_MB, NEXUS_CHUNK_CHUNK_KB, ] self.ev42_nexus_to_spinner_ui_element = {} self.ev42_advanced_group_box = QGroupBox( parent=self.show_advanced_options_button) self.ev42_advanced_group_box.setLayout(QFormLayout()) self.ev42_adc_pulse_debug_label = QLabel(ADC_PULSE_DEBUG) self.ev42_adc_pulse_debug_checkbox = QCheckBox() self.ev42_advanced_group_box.layout().addRow( self.ev42_adc_pulse_debug_label, self.ev42_adc_pulse_debug_checkbox) self.add_labels_and_spinboxes_for_advanced_options( self.ev42_nexus_elements, self.ev42_advanced_group_box, self.ev42_nexus_to_spinner_ui_element, ) def add_labels_and_spinboxes_for_advanced_options(self, elements, group_box, nexus_to_spinner): for nexus_string in elements: label = QLabel(nexus_string) spinner = QSpinBox() spinner.setRange(self.minimum_spinbox_value, self.maximum_spinbox_value) group_box.layout().addRow(label, spinner) nexus_to_spinner[nexus_string] = spinner def _set_up_f142_group_box(self): """ Sets up the UI for the f142 advanced options. """ self.f142_advanced_group_box = QGroupBox( parent=self.show_advanced_options_button) self.f142_advanced_group_box.setLayout(QFormLayout()) self.f142_nexus_to_spinner_ui_element = {} self.f142_nexus_elements = [ NEXUS_INDICES_INDEX_EVERY_MB, NEXUS_INDICES_INDEX_EVERY_KB, STORE_LATEST_INTO, ] self.add_labels_and_spinboxes_for_advanced_options( self.f142_nexus_elements, self.f142_advanced_group_box, self.f142_nexus_to_spinner_ui_element, ) def _show_advanced_options(self, show): schema = self.schema_combo.currentText() if schema == WriterModules.F142.value: self.f142_advanced_group_box.setVisible(show) elif schema == WriterModules.EV42.value: self.ev42_advanced_group_box.setVisible(show) self.advanced_options_enabled = show def _show_array_size(self, show: bool): self.array_size_spinbox.setVisible(show) self.array_size_label.setVisible(show) def _schema_type_changed(self, schema: str): self.parent().setWindowTitle(f"Editing {schema} stream field") self.hs00_unimplemented_label.setVisible(False) self.f142_advanced_group_box.setVisible(False) self.ev42_advanced_group_box.setVisible(False) self.show_advanced_options_button.setVisible(False) self.show_advanced_options_button.setChecked(False) self.value_units_label.setVisible(False) self.value_units_edit.setVisible(False) if schema == WriterModules.F142.value: self.value_units_label.setVisible(True) self.value_units_edit.setVisible(True) self._set_edits_visible(True, True) self.show_advanced_options_button.setVisible(True) self.f142_advanced_group_box.setVisible(False) elif schema == WriterModules.EV42.value: self._set_edits_visible(True, False) self.show_advanced_options_button.setVisible(True) self.ev42_advanced_group_box.setVisible(False) elif schema == WriterModules.HS00.value: self._set_edits_visible(True, False) self.hs00_unimplemented_label.setVisible(True) elif schema == WriterModules.NS10.value: self._set_edits_visible(True, False, "nicos/<device>/<parameter>") elif (schema == WriterModules.TDCTIME.value or schema == WriterModules.SENV.value): self._set_edits_visible(True, False) def _set_edits_visible(self, source: bool, type: bool, source_hint=None): self.source_label.setVisible(source) self.source_line_edit.setVisible(source) self.type_label.setVisible(type) self.type_combo.setVisible(type) self.array_radio.setVisible(type) self.scalar_radio.setVisible(type) if source_hint: self.source_line_edit.setPlaceholderText(source_hint) else: self.source_line_edit.setPlaceholderText("") def get_stream_group(self) -> h5py.Group: """ Create the stream group with a temporary in-memory HDF5 file. :return: The created HDF group. """ temp_file = create_temporary_in_memory_file() group = temp_file.create_group("children") group.create_dataset(name="type", dtype=STRING_DTYPE, data="stream") stream_group = group.create_group( self.parent().parent().field_name_edit.text()) stream_group.attrs[CommonAttrs.NX_CLASS] = CommonAttrs.NC_STREAM stream_group.create_dataset(name="topic", dtype=STRING_DTYPE, data=self.topic_line_edit.text()) stream_group.create_dataset( name="writer_module", dtype=STRING_DTYPE, data=self.schema_combo.currentText(), ) schema = self.schema_combo.currentText() stream_group.create_dataset("source", dtype=STRING_DTYPE, data=self.source_line_edit.text()) if schema == WriterModules.F142.value: self._create_f142_fields(stream_group) elif schema == WriterModules.EV42.value: self._create_ev42_fields(stream_group) return stream_group def _create_ev42_fields(self, stream_group: h5py.Group): """ Create ev42 fields in the given group if advanced options are specified. :param stream_group: The group to apply fields to. """ if self.advanced_options_enabled: if self.ev42_adc_pulse_debug_checkbox.isChecked(): stream_group.create_dataset( ADC_PULSE_DEBUG, dtype=bool, data=self.ev42_adc_pulse_debug_checkbox.isChecked(), ) self._create_dataset_from_spinner( stream_group, self.ev42_nexus_to_spinner_ui_element) def _create_f142_fields(self, stream_group: h5py.Group): """ Create f142 fields in the given group if advanced options are specified. :param stream_group: The group to apply fields to. """ stream_group.create_dataset("type", dtype=STRING_DTYPE, data=self.type_combo.currentText()) if self.array_radio.isChecked(): stream_group.create_dataset("array_size", data=self.array_size_spinbox.value()) if self.value_units_edit.text(): stream_group.create_dataset("value_units", data=self.value_units_edit.text()) if self.advanced_options_enabled: self._create_dataset_from_spinner( stream_group, self.f142_nexus_to_spinner_ui_element) @staticmethod def _create_dataset_from_spinner(stream_group: h5py.Group, nexus_to_spinner_dict: Dict[str, QSpinBox]): for (nexus_string, ui_element) in nexus_to_spinner_dict.items(): if ui_element.value() > 0: stream_group.create_dataset(nexus_string, dtype=int, data=ui_element.value()) def fill_in_existing_ev42_fields(self, field: h5py.Group): """ Fill in specific existing ev42 fields into the new UI field. :param field: The stream group :param new_ui_field: The new UI field to be filled in """ all_ev42_elements = list(self.ev42_nexus_elements) all_ev42_elements.append(ADC_PULSE_DEBUG) if check_if_advanced_options_should_be_enabled(all_ev42_elements, field): self._show_advanced_options(True) if ADC_PULSE_DEBUG in field.keys(): self.ev42_adc_pulse_debug_checkbox.setChecked( bool(field[ADC_PULSE_DEBUG][()])) fill_in_advanced_options( self.ev42_nexus_to_spinner_ui_element.items(), field) def fill_in_existing_f142_fields(self, field: h5py.Group): """ Fill in specific existing f142 fields into the new UI field. :param field: The stream group :param new_ui_field: The new UI field to be filled in """ self.type_combo.setCurrentText(field["type"][()]) if "array_size" in field.keys(): self.array_radio.setChecked(True) self.scalar_radio.setChecked(False) self.array_size_spinbox.setValue(field["array_size"][()]) else: self.array_radio.setChecked(False) self.scalar_radio.setChecked(True) if check_if_advanced_options_should_be_enabled( self.f142_nexus_elements, field): self._show_advanced_options(True) fill_in_advanced_options( self.f142_nexus_to_spinner_ui_element.items(), field) def update_existing_stream_info(self, field: h5py.Group): """ Fill in stream fields and properties into the new UI field. :param field: The stream group :param new_ui_field: The new UI field to be filled in """ schema = field["writer_module"][()] self.schema_combo.setCurrentText(str(schema)) self.topic_line_edit.setText(str(field["topic"][()])) self.source_line_edit.setText(str(field["source"][()])) if schema == WriterModules.F142.value: self.fill_in_existing_f142_fields(field) elif schema == WriterModules.EV42.value: self.fill_in_existing_ev42_fields(field)
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.setMinimumSize(QSize(400, 250)) self.setWindowTitle("Automate outlook mailing") self.LabelExcelFile = QLabel(self) self.LabelExcelFile.setText('Excel :') self.LabelExcelFile.move(20, 20) self.line = QLineEdit(self) self.line.move(80, 20) self.line.resize(200, 25) self.searchFileButton = QPushButton("Load", self) self.searchFileButton.clicked.connect(self.searchAndLoadFile) self.searchFileButton.move(300, 20) self.searchFileButton.resize(75, 25) # self.layout.addWidget(self.searchFileButton,2, 1, 1, 1) self.nameLabel = QLabel(self) self.nameLabel.setText('Subject :') self.nameLabel.move(20, 60) self.LineSubject = QLineEdit(self) self.LineSubject.move(80, 60) self.LineSubject.resize(200, 25) self.LabelArea = QLabel(self) self.LabelArea.setText('Body :') self.LabelArea.move(20, 100) self.text_area = QTextEdit(self) self.text_area.resize(200, 80) self.text_area.move(80, 100) self.pybutton = QPushButton('Save', self) self.pybutton.clicked.connect(self.clickMethod) self.pybutton.resize(200,32) self.pybutton.move(80, 200) self.createExample = QPushButton('Example File', self) self.createExample.clicked.connect(myExcel.CreateExample) self.createExample.resize(75,32) self.createExample.move(300, 100) self.autorun = QPushButton('Auto Run Off', self) self.autorun.clicked.connect(self.set_auto_run) self.autorun.resize(75,32) self.autorun.move(300, 150) self.autorun.setCheckable(True) self.start = QPushButton('Run', self) self.start.clicked.connect(self.run_business) self.start.resize(75,32) self.start.move(300, 200) def run_business(self): print("The business program starts") myBusiness.the_aim_of_the_program() pass def set_auto_run(self): """ print("Select Example") #self.button2.click() self.button2.setChecked(True) if self.button4.isChecked(): print("button4 is checked") self.button4.setChecked(False) pass else: print("button4 isnt checked") pass """ if self.autorun.isChecked(): print("autorun button is checked") self.autorun.setChecked(True) self.autorun.setText('Auto Run On') self.save_something('Automate outlook mailing','auto_run', 'True') pass else: self.autorun.setChecked(False) print("autorun button isnt checked") self.autorun.setText('Auto Run Off') self.save_something('Automate outlook mailing','auto_run', 'False') pass print("The business program starts") # myBusiness.the_aim_of_the_program() pass def save_something(self,section,somekey,something): if myConfig.configuration_file_has_been_persisted(): print("The program starts") #print(myConfig.get_saved_data("EXCEL","subject")) else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass myConfig.configuration_file_set_something_to_save(section,somekey,something) pass def clickMethod(self): print('Your name: ' + self.line.text()) if myConfig.configuration_file_has_been_persisted(): print("The program starts") print(myConfig.get_saved_data("EXCEL","subject")) else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass if self.line.text() != "": myConfig.configuration_file_set_something_to_save("EXCEL","file",self.line.text()) pass if self.LineSubject.text() != "": myConfig.configuration_file_set_something_to_save("EMAIL","subject",self.LineSubject.text()) pass if self.text_area.toPlainText() != "": myConfig.configuration_file_set_something_to_save("EMAIL","body",self.text_area.toPlainText()) pass # print(self.text_area.toPlainText()) #print(myConfig.get_mail_data()['subject']) # myConfig.configuration_file_create_persist() pass """ excel_file = "~tempfile.1.xlsx" #myExcel.getDataFromExcel(excel_file) if myConfig.configuration_file_has_been_persisted(): print("The program starts") print(myConfig.check_data("EMAIL",'subject')) # for key in (myConfig.get_mail_data()): print(key) if myConfig.check_data("EMAIL",'subject'): print(myConfig.get_mail_data()['subject']) myConfig.get_mail_data()['subject'] pass else: myConfig.configuration_file_create_persist() pass #myExcel.getDataFromExcel(excel_file,) pass else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass # myConfig.configuration_file_create_persist() pass """ def setFromConfigurationFile(self): #excel_file = "~tempfile.1.xlsx" #myExcel.getDataFromExcel(excel_file) if myConfig.configuration_file_has_been_persisted(): print("The program starts") #print(myConfig.check_data("EMAIL",'subject')) # for key in (myConfig.get_mail_data()): print(key) if myConfig.check_data("EMAIL",'subject'): #print(myConfig.get_mail_data()['subject']) #myConfig.get_mail_data()['subject'] print() print() print() self.line.setText(myConfig.get_saved_data("EXCEL",'file')) # self.line.setText("Hola perro") self.LineSubject.setText(myConfig.get_saved_data("EMAIL",'subject')) self.text_area.setText(myConfig.get_saved_data("EMAIL",'body')) if myConfig.check_data('Automate outlook mailing','auto_run'): if myConfig.get_saved_data('Automate outlook mailing','auto_run') == "True": self.autorun.setChecked(True) self.autorun.setText('Auto Run On') pass else: self.autorun.setChecked(False) self.autorun.setText('Auto Run Off') pass pass else: print('auto_run not exist') myConfig.configuration_file_create_persist() pass pass else: myConfig.configuration_file_create_persist() pass #myExcel.getDataFromExcel(excel_file,) pass else: print("The program needs to be configured") myConfig.configuration_file_create_persist() pass pass def searchAndLoadFile(self): #path_to_file, _ = QFileDialog.getOpenFileName(self, self.tr("Load Image"), self.tr("~/Desktop/"), self.tr("Images (*.jpg)")) path_to_file, _ = QFileDialog.getOpenFileName(self, self.tr("Load Excel"), self.tr("~/Desktop/"), self.tr("/ (*.xlsx)")) #self.test(path_to_file) print(path_to_file) #self.testFuncion(path_to_file) # self.filenameLoaded = path_to_file self.line.setText(path_to_file)
class MainWindow(QMainWindow): kill_thread = Signal() def __init__(self, app): self.app = app # self.qmp = QMP('localhost', 55555) self.qmp = QMP() self.qmp.stateChanged.connect(self.handle_pause_button) self.qmp.connectionChange.connect(self.handle_connect_button) self.paused = False super().__init__() self.init_ui() self.qmp.timeUpdate.connect(self.update_time) self.t = TimeThread(self.qmp) self.time_mult = TimeMultiplier(self.qmp, self.kill_thread) self.window = [] self.default_theme = QGuiApplication.palette() def init_ui(self): # Window Setup self.setWindowTitle("QEMU Control") self.setGeometry(100, 100, 275, 225) self.setFixedSize(self.size()) # App Icon icon = QIcon('package/icons/qemu-official.png') self.setWindowIcon(icon) # User Interface self.menu_bar() self.grid_layout() self.show() def menu_bar(self): bar = self.menuBar() # Menu Bar Actions file_ = bar.addMenu("File") edit = bar.addMenu("Edit") run = bar.addMenu("Run") tools = bar.addMenu("Tools") help_ = bar.addMenu("Help") # File Menu Options open_ = QAction("Open Image", self) file_.addAction(open_) exit_ = QAction("Exit", self) exit_.triggered.connect(self.close) exit_.setShortcut('Ctrl+W') file_.addAction(exit_) # Edit Menu Options prefs = QAction("Preferences", self, triggered=lambda:self.open_new_window(Preferences(self.app, self.default_theme, self.qmp, self.t))) edit.addAction(prefs) # Run Menu Options pause = QAction("Pause", self, triggered=lambda:self.qmp.command('stop')) run.addAction(pause) play = QAction("Play", self, triggered=lambda:self.qmp.command('cont')) run.addAction(play) # Debug Menu Options hexdmp = QAction("Memory Dump", self, triggered=(lambda: self.open_new_window(MemDumpWindow(self.qmp)) if self.qmp.isSockValid() else None)) tools.addAction(hexdmp) asm = QAction("Assembly View", self, triggered=(lambda: self.open_new_window(AssemblyWindow(self.qmp)) if self.qmp.isSockValid() else None)) tools.addAction(asm) registers = QAction("CPU Register View", self, triggered=(lambda: self.open_new_window(RegisterView(self.qmp)) if self.qmp.isSockValid() else None)) tools.addAction(registers) errors = QAction("Logging View", self, triggered=lambda:self.open_new_window(LoggingWindow(self.qmp))) tools.addAction(errors) tree = QAction("Memory Tree", self, triggered=(lambda: self.open_new_window(MemTree(self.qmp, self)) if self.qmp.isSockValid() else None)) tools.addAction(tree) mult = QAction("Time Multiplier", self, triggered=(lambda: self.time_mult.show() if self.qmp.isSockValid() else None)) tools.addAction(mult) trace = QAction("Trace Event Viewer", self, triggered=lambda: self.open_new_window(TraceWindow(self.qmp))) tools.addAction(trace) self.addPlugins(tools) # Help Menu Options usage = QAction("Usage Guide", self) help_.addAction(usage) def addPlugins(self, menu): plugins = menu.addMenu('Plugins') self.manager = PluginManager() self.manager.setPluginPlaces(['plugins']) self.manager.locatePlugins() self.manager.loadPlugins() for plugin in self.manager.getAllPlugins(): plugins.addAction(QAction(plugin.name, self, triggered=(lambda: self.open_new_window(plugin.plugin_object.display(self.qmp)) if self.qmp.isSockValid() else None))) def grid_layout(self): grid = QVBoxLayout() grid.setSpacing(15) self.pause_button = QPushButton('■') self.running_state = QLabel('Current State: <font color="grey">Inactive</font>') def cont_sim(): self.pause_button.setText('■') self.running_state.setText('Current State: <font color="green">Running</font>') self.qmp.command('cont') def stop_sim(): self.pause_button.setText('▶') self.running_state.setText('Current State: <font color="red">Paused</font>') self.qmp.command('stop') subgrid = QHBoxLayout() self.pause_button.clicked.connect(lambda: stop_sim() if not self.paused else cont_sim()) self.pause_button.setFixedSize(QSize(50, 50)) subgrid.addWidget(self.pause_button, 0) # self.pause_button.setCheckable(True) # self.handle_pause_button(False) self.pause_button.setEnabled(False) meatball = QLabel(self) logo = QPixmap('package/icons/nasa.png') logo = logo.scaled(75, 75, Qt.KeepAspectRatio) meatball.setPixmap(logo) subgrid.addWidget(meatball, 1) grid.addLayout(subgrid, 0) self.time = QLabel('Time: 00:00:00') self.time.setFont(QFont('Courier New')) grid.addWidget(self.time, 1) grid.addWidget(self.running_state, 2) self.banner = QLabel('<font color="grey">Connect to QMP to get started!</font>') grid.addWidget(self.banner, 3) conn_grid = QHBoxLayout() self.connect_button = QPushButton("Connect") self.connect_button.setCheckable(True) self.connect_button.clicked.connect(self.qmp_start) self.host = QLineEdit() self.host.returnPressed.connect(lambda: self.connect_button.click() if not self.connect_button.isChecked() else None) self.port = QLineEdit() self.port.returnPressed.connect(lambda: self.connect_button.click() if not self.connect_button.isChecked() else None) conn_grid.addWidget(self.host) conn_grid.addWidget(self.port) conn_grid.addWidget(self.connect_button) grid.addLayout(conn_grid) center = QWidget() center.setLayout(grid) self.setCentralWidget(center) def throwError(self): msgBox = QMessageBox(self) msgBox.setText('Lost Connection to QMP!') msgBox.show() @Slot(bool) def handle_pause_button(self, value): # Catches signals from QMPWrapper #print('recieved: ', value) # time.sleep(0.05) # fix race condition if value: self.paused = False self.pause_button.setText('■') self.running_state.setText('Current State: <font color="green">Running</font>') elif not value and value is not None: self.paused = True self.pause_button.setText('▶') self.running_state.setText('Current State: <font color="red">Paused</font>') def handle_connect_button(self, value): self.connect_button.setChecked(value) self.host.setReadOnly(value) self.port.setReadOnly(value) def open_new_window(self, new_window): if self.qmp.isSockValid(): self.window.append(new_window) def update_time(self, time): date = datetime.fromtimestamp(time / 1000000000, timezone.utc) self.time.setText(f'Time: {date.day - 1:02}:{date.hour:02}:{date.minute:02}:{date.second:02}') # -1 for day because it starts from 1 def qmp_start(self): if self.qmp.isSockValid(): self.qmp.sock_disconnect() self.kill_thread.emit() self.banner.setText('<font color="grey">Connect to QMP to get started!</font>') self.pause_button.setText('■') self.running_state.setText('Current State: <font color="grey">Inactive</font>') self.pause_button.setEnabled(False) return else: s = self.port.text() if s.isnumeric(): self.qmp.sock_connect(self.host.text(), int(s)) if self.qmp.isSockValid(): self.time_mult.start() self.banner.setText('QEMU Version ' + str(self.qmp.banner['QMP']['version']['package'])) self.pause_button.setEnabled(True) else: self.host.setText('127.0.0.1') self.port.setText('55555') self.qmp.sock_connect('127.0.0.1', 55555) if self.qmp.isSockValid(): self.time_mult.start() self.banner.setText('QEMU Version ' + str(self.qmp.banner['QMP']['version']['package'])) self.pause_button.setEnabled(True) # check if running initally if self.qmp.running: self.paused = False self.pause_button.setText('■') self.running_state.setText('Current State: <font color="green">Running</font>') else: self.paused = True self.pause_button.setText('▶') self.running_state.setText('Current State: <font color="red">Paused</font>') if not self.qmp.isAlive(): self.qmp.start() if not self.t.isAlive(): self.t.start() def closeEvent(self, event): self.kill_thread.emit() event.accept() def show_time_mult(self): self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.scene.addItem(self.time_mult.chart) self.view.show()
class PiecesPlayer(QWidget): """ main widget of application (used as widget inside PiecesMainWindow) """ def __init__(self, parent): """ standard constructor: set up class variables, ui elements and layout """ # TODO: split current piece info into separate lineedits for title, album name and length # TODO: make time changeable by clicking next to the slider (not only # by dragging the slider) # TODO: add "about" action to open info dialog in new "help" menu # TODO: add option to loop current piece (?) # TODO: more documentation # TODO: add some "whole piece time remaining" indicator? (complicated) # TODO: implement a playlist of pieces that can be edited and enable # going back to the previous piece (also un- and re-shuffling?) # TODO: implement debug dialog as menu action (if needed) if not isinstance(parent, PiecesMainWindow): raise ValueError('Parent widget must be a PiecesMainWindow') super(PiecesPlayer, self).__init__(parent=parent) # -- declare and setup variables for storing information -- # various data self._set_str = '' # string of currently loaded directory sets self._pieces = {} # {<piece1>: [<files piece1 consists of>], ...} self._playlist = [] # list of keys of self._pieces (determines order) self._shuffled = True # needed for (maybe) reshuffling when looping # doc for self._history: # key: timestamp ('HH:MM:SS'), # value: info_str of piece that started playing at that time self._history = {} self._status = 'Paused' self._current_piece = {'title': '', 'files': [], 'play_next': 0} self._default_volume = 60 # in percent from 0 - 100 self._volume_before_muted = self._default_volume # set to true by self.__event_movement_ended and used by self.__update self._skip_to_next = False # vlc-related variables self._vlc_instance = VLCInstance() self._vlc_mediaplayer = self._vlc_instance.media_player_new() self._vlc_mediaplayer.audio_set_volume(self._default_volume) self._vlc_medium = None self._vlc_events = self._vlc_mediaplayer.event_manager() # -- create and setup ui elements -- # buttons self._btn_play_pause = QPushButton(QIcon(get_icon_path('play')), '') self._btn_previous = QPushButton(QIcon(get_icon_path('previous')), '') self._btn_next = QPushButton(QIcon(get_icon_path('next')), '') self._btn_volume = QPushButton(QIcon(get_icon_path('volume-high')), '') self._btn_loop = QPushButton(QIcon(get_icon_path('loop')), '') self._btn_loop.setCheckable(True) self._btn_play_pause.clicked.connect(self.__action_play_pause) self._btn_previous.clicked.connect(self.__action_previous) self._btn_next.clicked.connect(self.__action_next) self._btn_volume.clicked.connect(self.__action_volume_clicked) # labels self._lbl_current_piece = QLabel('Current piece:') self._lbl_movements = QLabel('Movements:') self._lbl_time_played = QLabel('00:00') self._lbl_time_left = QLabel('-00:00') self._lbl_volume = QLabel('100%') # needed so that everything has the same position # independent of the number of digits of volume self._lbl_volume.setMinimumWidth(55) # sliders self._slider_time = QSlider(Qt.Horizontal) self._slider_volume = QSlider(Qt.Horizontal) self._slider_time.sliderReleased.connect( self.__event_time_changed_by_user) self._slider_volume.valueChanged.connect(self.__event_volume_changed) self._slider_time.setRange(0, 100) self._slider_volume.setRange(0, 100) self._slider_volume.setValue(self._default_volume) self._slider_volume.setMinimumWidth(100) # other elements self._checkbox_loop_playlist = QCheckBox('Loop playlist') self._lineedit_current_piece = QLineEdit() self._lineedit_current_piece.setReadOnly(True) self._lineedit_current_piece.textChanged.connect( self.__event_piece_text_changed) self._listwidget_movements = QListWidget() self._listwidget_movements.itemClicked.connect( self.__event_movement_selected) # -- create layout and insert ui elements-- self._layout = QVBoxLayout(self) # row 0 (name of current piece) self._layout_piece_name = QHBoxLayout() self._layout_piece_name.addWidget(self._lbl_current_piece) self._layout_piece_name.addWidget(self._lineedit_current_piece) self._layout.addLayout(self._layout_piece_name) # rows 1 - 5 (movements of current piece) self._layout.addWidget(self._lbl_movements) self._layout.addWidget(self._listwidget_movements) # row 6 (time) self._layout_time = QHBoxLayout() self._layout_time.addWidget(self._lbl_time_played) self._layout_time.addWidget(self._slider_time) self._layout_time.addWidget(self._lbl_time_left) self._layout.addLayout(self._layout_time) # row 7 (buttons and volume) self._layout_buttons_and_volume = QHBoxLayout() self._layout_buttons_and_volume.addWidget(self._btn_play_pause) self._layout_buttons_and_volume.addWidget(self._btn_previous) self._layout_buttons_and_volume.addWidget(self._btn_next) self._layout_buttons_and_volume.addWidget(self._btn_loop) self._layout_buttons_and_volume.addSpacing(40) # distance between loop and volume buttons: min. 40, but stretchable self._layout_buttons_and_volume.addStretch() self._layout_buttons_and_volume.addWidget(self._btn_volume) self._layout_buttons_and_volume.addWidget(self._slider_volume) self._layout_buttons_and_volume.addWidget(self._lbl_volume) self._layout.addLayout(self._layout_buttons_and_volume) # -- setup hotkeys -- self._KEY_CODES_PLAY_PAUSE = [269025044] self._KEY_CODES_NEXT = [269025047] self._KEY_CODES_PREVIOUS = [269025046] self._keyboard_listener = keyboard.Listener(on_press=self.__on_press) self._keyboard_listener.start() QShortcut(QKeySequence('Space'), self, self.__action_play_pause) # -- various setup -- self._timer = QTimer(self) self._timer.timeout.connect(self.__update) self._timer.start(100) # update every 100ms self.setMinimumWidth(900) self.setMinimumHeight(400) # get directory set(s) input and set up self._pieces # (exec_ means we'll wait for the user input before continuing) DirectorySetChooseDialog(self, self.set_pieces_and_playlist).exec_() # skip to next movement / next piece when current one has ended self._vlc_events.event_attach(VLCEventType.MediaPlayerEndReached, self.__event_movement_ended) def __action_next(self): """ switches to next file in self._current_piece['files'] or to the next piece, if the current piece has ended """ reset_pause_after_current = False # current movement is last of the current piece if self._current_piece['play_next'] == -1: if len(self._playlist) == 0: # reached end of playlist if self._btn_loop.isChecked(): self._playlist = list(self._pieces.keys()) if self._shuffled: shuffle(self._playlist) return if self._status == 'Playing': self.__action_play_pause() self._current_piece['title'] = '' self._current_piece['files'] = [] self._current_piece['play_next'] = -1 self._lineedit_current_piece.setText('') self.__update_movement_list() self.parentWidget().update_status_bar( self._status, 'End of playlist reached.') return else: if self.parentWidget().get_exit_after_current(): self.parentWidget().exit() if self.parentWidget().get_pause_after_current(): self.__action_play_pause() reset_pause_after_current = True # reset of the menu action will be at the end of this # function, or else we won't stay paused self._current_piece['title'] = self._playlist.pop(0) self._current_piece['files'] = [ p[1:-1] for p in self._pieces[self._current_piece['title']] ] # some pieces only have one movement self._current_piece['play_next'] = \ 1 if len(self._current_piece['files']) > 1 else -1 self.__update_vlc_medium(0) self._lineedit_current_piece.setText( create_info_str(self._current_piece['title'], self._current_piece['files'])) self.__update_movement_list() self._history[datetime.now().strftime('%H:%M:%S')] = \ self._lineedit_current_piece.text() else: self.__update_vlc_medium(self._current_piece['play_next']) # next is last movement if self._current_piece['play_next'] == \ len(self._current_piece['files']) - 1: self._current_piece['play_next'] = -1 else: # there are at least two movements of current piece left self._current_piece['play_next'] += 1 if self._status == 'Paused' and not reset_pause_after_current: self.__action_play_pause() elif reset_pause_after_current: self.parentWidget().set_pause_after_current(False) else: self._vlc_mediaplayer.play() self.parentWidget().update_status_bar( self._status, f'{len(self._pieces) - len(self._playlist)}/{len(self._pieces)}') def __action_play_pause(self): """ (gets called when self._btn_play_pause is clicked) toggles playing/pausing music and updates everything as needed """ # don't do anything now (maybe end of playlist reached?) if self._current_piece['title'] == '': return if self._status == 'Paused': if not self._vlc_medium: self.__action_next() self._vlc_mediaplayer.play() self._btn_play_pause.setIcon(QIcon(get_icon_path('pause'))) self._status = 'Playing' else: self._vlc_mediaplayer.pause() self._btn_play_pause.setIcon(QIcon(get_icon_path('play'))) self._status = 'Paused' self.parentWidget().update_status_bar( self._status, f'{len(self._pieces) - len(self._playlist)}/{len(self._pieces)}') def __action_previous(self): """ (called when self._btn_previous ist clicked) goes back one movement of the current piece, if possible (cannot go back to previous piece) """ # can't go back to previous piece, but current one has no or one movement if len(self._current_piece['files']) <= 1: pass # currently playing first movement, so nothing to do as well elif self._current_piece['play_next'] == 1: pass else: # we can go back one movement # currently at last movement if self._current_piece['play_next'] == -1: # set play_next to last movement self._current_piece['play_next'] = \ len(self._current_piece['files']) - 1 else: # currently before last movement # set play_next to current movement self._current_piece['play_next'] -= 1 self._vlc_mediaplayer.stop() self.__update_vlc_medium(self._current_piece['play_next'] - 1) self._vlc_mediaplayer.play() def __action_volume_clicked(self): """ (called when self._btn_volume is clicked) (un)mutes volume """ if self._slider_volume.value() == 0: # unmute volume self._slider_volume.setValue(self._volume_before_muted) else: # mute volume self._volume_before_muted = self._slider_volume.value() self._slider_volume.setValue(0) def __event_movement_ended(self, event): """ (called when self._vlc_media_player emits a MediaPlayerEndReached event) sets self._skip_to_next to True so the next self.__update call will trigger self.__action_next """ self._skip_to_next = True def __event_movement_selected(self): """ (called when self._listwidget_movements emits itemClicked) skips to the newly selected movement """ index = self._listwidget_movements.indexFromItem( self._listwidget_movements.currentItem()).row() # user selected a movement different from the current one if index != self.__get_current_movement_index(): self._current_piece['play_next'] = index self.__action_next() def __event_piece_text_changed(self): """ (called when self._lineedit_current_piece emits textChanged) ensures that the user sees the beginning of the text in self._lineedit_current_piece (if text is too long, the end will be cut off and the user must scroll manually to see it) """ self._lineedit_current_piece.setCursorPosition(0) def __event_volume_changed(self): """ (called when value of self._slider_volume changes) updates text of self._lbl_volume to new value of self._slider_value and sets icon of self._btn_volume to a fitting one """ volume = self._slider_volume.value() self._lbl_volume.setText(f'{volume}%') if volume == 0: self._btn_volume.setIcon(QIcon(get_icon_path('volume-muted'))) elif volume < 34: self._btn_volume.setIcon(QIcon(get_icon_path('volume-low'))) elif volume < 67: self._btn_volume.setIcon(QIcon(get_icon_path('volume-medium'))) else: self._btn_volume.setIcon(QIcon(get_icon_path('volume-high'))) self._vlc_mediaplayer.audio_set_volume(volume) def __event_time_changed_by_user(self): """ (called when user releases self._slider_time) synchronizes self._vlc_mediaplayer's position to the new value of self._slider_time """ self._vlc_mediaplayer.set_position(self._slider_time.value() / 100) def __get_current_movement_index(self): """ returns the index of the current movement in self._current_piece['files'] """ play_next = self._current_piece['play_next'] if play_next == -1: return len(self._current_piece['files']) - 1 else: return play_next - 1 def __on_press(self, key): """ (called by self._keyboard_listener when a key is pressed) looks up key code corresponding to key and calls the appropriate action function """ try: # key is not always of the same type (why would it be?!) key_code = key.vk except AttributeError: key_code = key.value.vk if key_code in self._KEY_CODES_PLAY_PAUSE: self.__action_play_pause() elif key_code in self._KEY_CODES_NEXT: self.__action_next() elif key_code in self._KEY_CODES_PREVIOUS: self.__action_previous() def __update_movement_list(self): """ removes all items currently in self._listwidget_movements and adds everything in self._current_piece['files] """ # TODO: use ID3 title instead of filename while self._listwidget_movements.count() > 0: self._listwidget_movements.takeItem(0) files = self._current_piece['files'] if os_name == 'nt': # windows paths look different than posix paths # remove path to file, title number and .mp3 ending files = [i[i.rfind('\\') + 3:-4] for i in files] else: files = [i[i.rfind('/') + 4:-4] for i in files] self._listwidget_movements.addItems(files) def __update(self): """ (periodically called when self._timer emits timeout signal) updates various ui elements""" # -- select currently playing movement in self._listwidget_movements -- if self._listwidget_movements.count() > 0: self._listwidget_movements.item( self.__get_current_movement_index()).setSelected(True) # -- update text of self._lbl_time_played and self._lbl_time_left, # if necessary -- if self._vlc_medium: try: time_played = self._vlc_mediaplayer.get_time() medium_duration = self._vlc_medium.get_duration() # other values don't make sense (but do occur) if (time_played >= 0) and (time_played <= medium_duration): self._lbl_time_played.setText( get_time_str_from_ms(time_played)) else: self._lbl_time_played.setText(get_time_str_from_ms(0)) self._lbl_time_left.setText( f'-{get_time_str_from_ms(medium_duration - time_played)}') except OSError: # don't know why that occurs sometimes pass # -- update value of self._slider_time -- # don't reset slider to current position if user is dragging it if not self._slider_time.isSliderDown(): try: self._slider_time.setValue( self._vlc_mediaplayer.get_position() * 100) except OSError: # don't know why that occurs sometimes pass if self._skip_to_next: self._skip_to_next = False self.__action_next() def __update_vlc_medium(self, files_index): old_medium = self._vlc_medium self._vlc_medium = self._vlc_instance.media_new( self._current_piece['files'][files_index]) self._vlc_medium.parse() self._vlc_mediaplayer.set_media(self._vlc_medium) if old_medium: # only release if not None old_medium.release() def get_history(self): """ getter function for parent widget """ return self._history def get_set_str(self): """ getter function for parent widget """ return self._set_str if self._set_str != '' \ else 'No directory set loaded.' def set_pieces_and_playlist(self, pieces, playlist, set_str, shuffled): """ needed so that DirectorySetChooseDialog can set our self._pieces and self._playlist """ # just to be sure if isinstance(pieces, dict) and isinstance(playlist, list): self._vlc_mediaplayer.stop() self._set_str = set_str self._pieces = pieces self._playlist = playlist self._shuffled = shuffled self._current_piece['title'] = self._playlist.pop(0) self._current_piece['files'] = [ p.replace('"', '') for p in self._pieces[self._current_piece['title']] ] self._current_piece['play_next'] = \ 1 if len(self._current_piece['files']) > 1 else -1 self._lineedit_current_piece.setText( create_info_str(self._current_piece['title'], self._current_piece['files'])) self.__update_movement_list() self.__update_vlc_medium(0) self._history[datetime.now().strftime('%H:%M:%S')] = \ self._lineedit_current_piece.text() def exit(self): """ exits cleanly """ try: # don't know why that occurs sometimes self._vlc_mediaplayer.stop() self._vlc_mediaplayer.release() self._vlc_instance.release() except OSError: pass self._keyboard_listener.stop()
class MainWindow(QMainWindow): def __init__(self, exp): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowIcon(QIcon('icons/main.ico')) # Setup status bar. Cannot do this in the Designer. self.btn_idle = QPushButton("Record", self) self.btn_idle.setStyleSheet("background-color : red") self.btn_idle.setCheckable(True) self.ui.statusbar.addWidget(self.btn_idle) self.exp = exp self.threadpool = QThreadPool() # Setup the GUI windows # self.showMaximized() self.set_windows() # Menu bar function binding self.ui.actionNew.triggered.connect(self.OnNewExperiment) self.ui.actionOpen.triggered.connect(self.OnOpenExperiment) self.ui.actionSave.triggered.connect(self.OnSaveExperiment) self.ui.actionTileWindows.triggered.connect(self.OnTileWindows) self.ui.actionOpenWindows.triggered.connect(self.OnShowWindows) self.ui.actionLoadScript.triggered.connect(self.OnLoadScript) self.ui.actionReloadScript.triggered.connect(self.OnReloadScript) # Status bar self.btn_idle.clicked.connect(self.OnRecord) # Keyboard shortcuts self.full_screen = False self.shortcut_full_screen = QShortcut(QKeySequence('F11'), self) self.shortcut_full_screen.activated.connect(self.OnFullScreen) # Start looking for data files self.start_file_thread() self.start_plot_thread() self.showMaximized() # Open the application in full screen mode self.show() def set_table_win(self): # Add data table sub-window self.data_table = DataTable(self.exp, self) self.data_table.signals.plot.connect(self.replot) self.DataTableWindow = QMdiSubWindow() self.DataTableWindow.setWidget(self.data_table) self.ui.mdiArea.addSubWindow(self.DataTableWindow) self.DataTableWindow.show() def set_param_win(self): # Add analysis parameters self.analysis_parameters = Parameter(self.exp, self) self.analysis_parameters.signals.plot.connect(self.replot) self.ParameterWindow = QMdiSubWindow() self.ParameterWindow.setWidget(self.analysis_parameters) self.ui.mdiArea.addSubWindow(self.ParameterWindow) self.ParameterWindow.show() # Add note window self.exp_notes = Notes(self.exp, self) self.NotesWindow = QMdiSubWindow() self.NotesWindow.setWidget(self.exp_notes) self.ui.mdiArea.addSubWindow(self.NotesWindow) self.NotesWindow.show() def set_figs_win(self): # Add plots self.FigureWindows = {} self.figs = {} _figs = self.exp.get_figures() for _name in _figs.keys(): self.figs[_name] = MplCanvas(_figs[_name]) self.FigureWindows[_name] = QMdiSubWindow() self.FigureWindows[_name].setWidget(self.figs[_name]) self.FigureWindows[_name].resize(500, 400) self.ui.mdiArea.addSubWindow(self.FigureWindows[_name]) self.FigureWindows[_name].show() def set_windows(self): self.set_table_win() self.set_param_win() self.set_figs_win() self.OnTileWindows() def clear_windows(self, subwindows='all'): if subwindows == 'all': subwindows = self.ui.mdiArea.subWindowList() for _win in subwindows: self.ui.mdiArea.removeSubWindow(_win) def refresh_windows(self): self.clear_windows() self.set_windows() def start_file_thread(self): # Start file thread self.file_thread = FileThread(self.exp, self) self.file_thread.signals.result.connect(self.add_result) self.file_thread.start() def stop_file_thread(self): self.file_thread.abort() def start_plot_thread(self): self.plot_thread = PlotThread(self) self.plot_thread.start() def stop_plot_thread(self): self.plot_thread.abort() @Slot() def replot(self): self.plot_thread.replot() @Slot() def OnFullScreen(self): if self.full_screen: self.showMaximized() else: self.showFullScreen() self.full_screen = not self.full_screen @Slot() def OnTileWindows(self): _win_width = self.ui.mdiArea.width() # Window width top_row_height = 450 _table_win_width = max(1200, _win_width * 0.65) _param_win_width = 3. / 7. * (_win_width - _table_win_width) _notes_win_width = (_win_width - _table_win_width - _param_win_width) # Position table window _ract = QRect(0., 0., _table_win_width, top_row_height) self.DataTableWindow.setGeometry(_ract) self.DataTableWindow.move(0, 0) # Positon parameter window _ract = QRect(0., 0., _param_win_width, top_row_height) self.ParameterWindow.setGeometry(_ract) self.ParameterWindow.move(_table_win_width, 0) # Position Note window _ract = QRect(0., 0., _notes_win_width, top_row_height) self.NotesWindow.setGeometry(_ract) self.NotesWindow.move(_table_win_width + _param_win_width, 0) # Tile figure windwos _fig_win_size = _win_width / 4. for ii, _name in enumerate(self.FigureWindows.keys()): x_shift = ii % 4 y_shift = math.floor(ii / 4) _rect = QRect(0., 0., _fig_win_size, _fig_win_size) self.FigureWindows[_name].setGeometry(_rect) self.FigureWindows[_name].move( _fig_win_size * x_shift, _fig_win_size * y_shift + top_row_height) @Slot() def OnShowWindows(self): self.refresh_windows() @Slot() def OnNewExperiment(self): self.OnSaveExperiment() _info = self.exp.get_exp_info() _name = _info['name'] _script = os.path.join(_info['script_dir'], _info['script']) dlg = NewExpDialog(name=_name, script=_script) if dlg.exec_(): _name = dlg.get_name() _script = dlg.get_script() self.exp = Experiment(name=_name, script=_script) self.file_thread.set_experiment(self.exp) self.clear_windows() self.set_windows() @Slot() def OnOpenExperiment(self): dlg = QFileDialog() dlg.setNameFilter("Experiment (*.info)") if dlg.exec_(): dirname = dlg.selectedFiles()[0] dirname = dirname.replace( '/', '\\' ) # Convert to Windows path. Maybe use pathlib in the future exp = load_exp(dirname) self.exp = exp self.file_thread.set_experiment(self.exp) self.clear_windows() self.set_windows() @Slot() def OnSaveExperiment(self): self.exp.save() @Slot() def OnLoadScript(self): dlg = QFileDialog() dlg.setNameFilter("Script (*.ipynb)") if dlg.exec_(): _script = dlg.selectedFiles()[0] self.exp.set_analysis_script(_script) self.clear_windows() self.set_windows() @Slot() def OnReloadScript(self): # Load from data folder instead of script folder _script = os.path.join(self.exp.exp_dir, self.exp.script_filename) if self.exp.script_filename.strip() == '': console_print( 'Main Window', 'Unknown scrit file! Use "Load Script" in the "Analysis" Menu.' .format(_script), method='error') return if not os.path.exists(_script): console_print('Main Window', 'Script ({}) doesn\'t exist!'.format(_script)) return _params = self.exp.get_parameters( ) # Preserve the parameters when reload self.exp.set_analysis_script(_script) self.clear_windows() self.set_windows() self.analysis_parameters.set_parameters( _params) # Set to current parameters @Slot() def OnRecord(self): _status = self.btn_idle.isChecked() if self.file_thread == None: # Restart the file thread if it crashed self.start_file_thread() self.file_thread.set_save(_status) if _status: self.btn_idle.setStyleSheet("background-color : green") else: self.btn_idle.setStyleSheet("background-color : red") return 1 @Slot(int) def add_result(self, data_id): self.data_table.add_run(data_id) self.replot() @Slot() def update_figures(self): # Refresh the GUI for new figures. for _name in self.figs.keys(): self.figs[_name].draw() return 1 def load_analysis_script(self, filename): self.exp.set_analysis_script(filename) # self.ui.mdiArea.removeSubWindow(self.ParameterWindow) self.analysis_parameters = Parameter(self.exp, self) self.ParameterWindow.setWidget(self.analysis_parameters)
class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.setWindowTitle("Backend Discord-GUI") self.changeStyle('fusion') palette = QPalette() palette.setColor(QPalette.Window, QColor(53, 53, 53)) palette.setColor(QPalette.WindowText, Qt.white) palette.setColor(QPalette.Text, Qt.white) palette.setColor(QPalette.Button, QColor(60, 60, 60)) palette.setColor(QPalette.ButtonText, Qt.white) palette.setColor(QPalette.Base, QColor(40, 40, 40)) palette.setColor(QPalette.ToolTipBase, QColor(60, 60, 60)) palette.setColor(QPalette.ToolTipText, Qt.white) palette.setColor(QPalette.PlaceholderText, QColor(100, 60, 60)) palette.setColor(QPalette.BrightText, Qt.white) palette.setColor(QPalette.Highlight, QColor(106, 13, 173)) palette.setColor(QPalette.HighlightedText, Qt.white) mainLayout = QVBoxLayout() hMainLayout = QHBoxLayout() passwordLayout = QHBoxLayout() self.username = QLineEdit(self) self.QUserLabel = QLabel("Username") self.username.setStyleSheet( "QToolTop { border: 0px; border-radius: 3px }") self.QUserLabel.setFont(QFont("Copperplate", 12)) self.password = QLineEdit(self) self.QPasswordLabel = QLabel("Password") self.password.setStyleSheet( "QToolTip { border: 0px; border-radius: 3px }") self.QPasswordLabel.setFont(QFont("Copperplate", 12)) self.showhideButton = QPushButton("Show") self.showhideButton.setCheckable(True) self.showhideButton.setChecked(False) self.showhideButton.clicked.connect(lambda: self.show_hide()) self.password.setEchoMode(QLineEdit.Password) passwordLayout.addWidget(self.QPasswordLabel) passwordLayout.addWidget(self.password) passwordLayout.addWidget(self.showhideButton) self.btn_Submit = QPushButton("Login") shortcut = QShortcut(QKeySequence("Return"), self.btn_Submit) shortcut.activated.connect(lambda: self.do_nothing()) shortcut.setEnabled(True) self.btn_SignUp = QPushButton("Sign Up") self.btn_SignUp.clicked.connect(lambda: window.openSignUp()) layout = QFormLayout() layout.addRow(self.QUserLabel, self.username) layout.addRow(passwordLayout) layout.addRow(self.btn_Submit) layout.addRow(self.btn_SignUp) Label = QLabel("Welcome To The\nBackend Discord-GUI Development") Label.setFont(QFont("Copperplate", 15, QFont.Bold)) Label.setAlignment(Qt.AlignCenter) mainLayout.addSpacing(80) mainLayout.addWidget(Label) mainLayout.addLayout(layout) mainLayout.addSpacing(100) hMainLayout.addSpacing(125) hMainLayout.addLayout(mainLayout) hMainLayout.addSpacing(125) self.setLayout(hMainLayout) QApplication.setPalette(palette) def do_nothing(self): print("Logged In") def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: pass def show_hide(self): if self.showhideButton.isChecked(): self.password.setEchoMode(QLineEdit.Normal) self.showhideButton.setText("Hide") else: self.password.setEchoMode(QLineEdit.Password) self.showhideButton.setText("Show") def changeStyle(self, styleName): QApplication.setStyle(QStyleFactory.create(styleName))