def testButtonClick(self): """Indirect qt signal emission using the QPushButton.click() method """ button = QPushButton('label') QObject.connect(button, SIGNAL('clicked()'), self.cb) self.args = tuple() button.click() self.assert_(self.called)
def testButtonClicked(self): """Connection of a python slot to QPushButton.clicked()""" button = QPushButton('Mylabel') QObject.connect(button, SIGNAL('clicked()'), self.cb) self.args = tuple() button.emit(SIGNAL('clicked(bool)'), False) self.assert_(self.called)
def testBoolinSignal(self): b = QPushButton() b.setCheckable(True) self._clicked = False b.toggled[bool].connect(self.buttonCb) b.toggle() self.assert_(self._clicked)
def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 WebEngineWidgets Example') self.toolBar = QToolBar() self.addToolBar(self.toolBar) self.backButton = QPushButton() self.backButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png')) self.backButton.clicked.connect(self.back) self.toolBar.addWidget(self.backButton) self.forwardButton = QPushButton() self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.forwardButton.clicked.connect(self.forward) self.toolBar.addWidget(self.forwardButton) self.addressLineEdit = QLineEdit() self.addressLineEdit.returnPressed.connect(self.load) self.toolBar.addWidget(self.addressLineEdit) self.webEngineView = QWebEngineView() self.setCentralWidget(self.webEngineView) initialUrl = 'http://qt.io' self.addressLineEdit.setText(initialUrl) self.webEngineView.load(QUrl(initialUrl)) self.webEngineView.page().titleChanged.connect(self.setWindowTitle) self.webEngineView.page().urlChanged.connect(self.urlChanged)
def testWindowButtonClickClose(self): button = QPushButton() window = QWidget() window.connect(button, SIGNAL('clicked()'), SLOT('close()')) window.show() self.assert_(window.isVisible()) button.click() self.assert_(not window.isVisible())
def testButton(self): #Connecting a lambda to a QPushButton.clicked() obj = QPushButton('label') ctr = Control() func = lambda: setattr(ctr, 'arg', True) QObject.connect(obj, SIGNAL('clicked()'), func) obj.click() self.assert_(ctr.arg) QObject.disconnect(obj, SIGNAL('clicked()'), func)
def testReturnWindow(self): widget = QWidget() button = QPushButton(widget) self.assertEqual(sys.getrefcount(widget), 2) window = button.window() self.assertEqual(sys.getrefcount(widget), 3) self.assertEqual(sys.getrefcount(window), 3) del widget
def testButtonClickClose(self): button = QPushButton() button.connect(button, SIGNAL('clicked()'), SLOT('close()')) button.show() self.assert_(button.isVisible()) button.click() self.assert_(not button.isVisible())
class ColorEdit(QWidget): def __init__(self, parent=None): super(ColorEdit, self).__init__(parent) self.color = QColor('#FF00FF') self.edit = QLineEdit() self.edit.setText('FF00FF') self.edit.setMaximumWidth(70) self.edit.textEdited.connect(self.editChanged) self.edit.returnPressed.connect(self.editChanged) self.box = QPushButton() self.box.setFlat(True) self.box.setFixedSize(18, 18) self.box.setStyleSheet('background-color: #FF00FF; border: 1px solid black;') self.box.setCursor(Qt.PointingHandCursor) self.box.clicked.connect(self.boxClicked) hlayout = QHBoxLayout() hlayout.setContentsMargins(0, 0, 0, 0) hlayout.setSpacing(0) hlayout.addWidget(QLabel('#')) hlayout.addWidget(self.edit) hlayout.addSpacing(5) hlayout.addWidget(self.box) hlayout.addStretch() self.setLayout(hlayout) def editChanged(self): self.setColorText(self.edit.text()) def boxClicked(self): dialog = QColorDialog() if dialog.exec_(): self.setColorText(dialog.selectedColor().name()) def setColorText(self, text): text = str(text).upper().replace('#', '') color = QColor('#' + text) if not color.isValid(): return self.box.setStyleSheet('background-color: #' + text + '; border: 1px solid black;') self.edit.setText(text) self.color = color return True def getColor(self): return self.color
def _setupUI(self): self.setWindowTitle("Export Attributes to USD") layout = QVBoxLayout() # This section contains the attributes tagged for export. label = QLabel() label.setText('Exported Attributes:') layout.addWidget(label) self.exportedAttrsModel = ExportedAttributesModel() self.exportedAttrsView = ExportedAttributesView() self.exportedAttrsView.verticalHeader().hide() self.exportedAttrsView.setModel(self.exportedAttrsModel) selectionModel = self.exportedAttrsView.selectionModel() selectionModel.selectionChanged.connect(self._onExportedAttrsSelectionChanged) self.exportedAttrsModel.dataChanged.connect(self._onModelDataChanged) layout.addWidget(self.exportedAttrsView) self.removeExportedAttrButton = QPushButton("Remove Exported Attribute") self.removeExportedAttrButton.clicked.connect(self._onRemoveExportedAttrPressed) self.removeExportedAttrButton.setEnabled(False) layout.addWidget(self.removeExportedAttrButton) # This section contains the attributes available for export. label = QLabel() label.setText('Available Attributes:') layout.addWidget(label) self.userDefinedCheckBox = QCheckBox('User Defined') self.userDefinedCheckBox.setToolTip('Show only user-defined (dynamic) attributes') self.userDefinedCheckBox.setChecked(True) self.userDefinedCheckBox.stateChanged.connect(self._syncUI) layout.addWidget(self.userDefinedCheckBox) self.addAttrsModel = AddAttributesModel() self.addAttrsView = AddAttributesView() self.addAttrsView.setModel(self.addAttrsModel) selectionModel = self.addAttrsView.selectionModel() selectionModel.selectionChanged.connect(self._onAddAttrsSelectionChanged) self.addAttrsModel.dataChanged.connect(self._onModelDataChanged) layout.addWidget(self.addAttrsView) self.addExportedAttrButton = QPushButton("Add Exported Attribute") self.addExportedAttrButton.clicked.connect(self._onAddExportedAttrPressed) self.addExportedAttrButton.setEnabled(False) layout.addWidget(self.addExportedAttrButton) self.setLayout(layout)
def __init__(self, parent=None): super(ColorEdit, self).__init__(parent) self.color = QColor('#FF00FF') self.edit = QLineEdit() self.edit.setText('FF00FF') self.edit.setMaximumWidth(70) self.edit.textEdited.connect(self.editChanged) self.edit.returnPressed.connect(self.editChanged) self.box = QPushButton() self.box.setFlat(True) self.box.setFixedSize(18, 18) self.box.setStyleSheet('background-color: #FF00FF; border: 1px solid black;') self.box.setCursor(Qt.PointingHandCursor) self.box.clicked.connect(self.boxClicked) hlayout = QHBoxLayout() hlayout.setContentsMargins(0, 0, 0, 0) hlayout.setSpacing(0) hlayout.addWidget(QLabel('#')) hlayout.addWidget(self.edit) hlayout.addSpacing(5) hlayout.addWidget(self.box) hlayout.addStretch() self.setLayout(hlayout)
def __init__(self, parent=None): super(BlockingClient, self).__init__(parent) self.thread = FortuneThread() self.currentFortune = '' hostLabel = QLabel("&Server name:") portLabel = QLabel("S&erver port:") for ipAddress in QNetworkInterface.allAddresses(): if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0: break else: ipAddress = QHostAddress(QHostAddress.LocalHost) ipAddress = ipAddress.toString() self.hostLineEdit = QLineEdit(ipAddress) self.portLineEdit = QLineEdit() self.portLineEdit.setValidator(QIntValidator(1, 65535, self)) hostLabel.setBuddy(self.hostLineEdit) portLabel.setBuddy(self.portLineEdit) self.statusLabel = QLabel( "This example requires that you run the Fortune Server example as well.") self.statusLabel.setWordWrap(True) self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) self.getFortuneButton.setEnabled(False) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) self.thread.newFortune.connect(self.showFortune) self.thread.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostLineEdit, 0, 1) mainLayout.addWidget(portLabel, 1, 0) mainLayout.addWidget(self.portLineEdit, 1, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Blocking Fortune Client") self.portLineEdit.setFocus()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle('PySide2 WebEngineWidgets Example') self.toolBar = QToolBar() self.addToolBar(self.toolBar) self.backButton = QPushButton() self.backButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png')) self.backButton.clicked.connect(self.back) self.toolBar.addWidget(self.backButton) self.forwardButton = QPushButton() self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) self.forwardButton.clicked.connect(self.forward) self.toolBar.addWidget(self.forwardButton) self.addressLineEdit = QLineEdit() self.addressLineEdit.returnPressed.connect(self.load) self.toolBar.addWidget(self.addressLineEdit) self.webEngineView = QWebEngineView() self.setCentralWidget(self.webEngineView) initialUrl = 'http://qt.io' self.addressLineEdit.setText(initialUrl) self.webEngineView.load(QUrl(initialUrl)) self.webEngineView.page().titleChanged.connect(self.setWindowTitle) self.webEngineView.page().urlChanged.connect(self.urlChanged) def load(self): url = QUrl.fromUserInput(self.addressLineEdit.text()) if url.isValid(): self.webEngineView.load(url) def back(self): self.webEngineView.page().triggerAction(QWebEnginePage.Back) def forward(self): self.webEngineView.page().triggerAction(QWebEnginePage.Forward) def urlChanged(self, url): self.addressLineEdit.setText(url.toString())
def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.server = FortuneServer() statusLabel = QLabel() statusLabel.setTextInteractionFlags(Qt.TextBrowserInteraction) statusLabel.setWordWrap(True) quitButton = QPushButton("Quit") quitButton.setAutoDefault(False) if not self.server.listen(): QMessageBox.critical(self, "Threaded Fortune Server", "Unable to start the server: %s." % self.server.errorString()) self.close() return for ipAddress in QNetworkInterface.allAddresses(): if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0: break else: ipAddress = QHostAddress(QHostAddress.LocalHost) ipAddress = ipAddress.toString() statusLabel.setText("The server is running on\n\nIP: %s\nport: %d\n\n" "Run the Fortune Client example now." % (ipAddress, self.server.serverPort())) quitButton.clicked.connect(self.close) buttonLayout = QHBoxLayout() buttonLayout.addStretch(1) buttonLayout.addWidget(quitButton) buttonLayout.addStretch(1) mainLayout = QVBoxLayout() mainLayout.addWidget(statusLabel) mainLayout.addLayout(buttonLayout) self.setLayout(mainLayout) self.setWindowTitle("Threaded Fortune Server")
def __init__(self, previewImage, fileName): super(ImageView, self).__init__() self.fileName = fileName mainLayout = QVBoxLayout(self) self.imageLabel = QLabel() self.imageLabel.setPixmap(QPixmap.fromImage(previewImage)) mainLayout.addWidget(self.imageLabel) topLayout = QHBoxLayout() self.fileNameLabel = QLabel(QDir.toNativeSeparators(fileName)) self.fileNameLabel.setTextInteractionFlags(Qt.TextBrowserInteraction) topLayout.addWidget(self.fileNameLabel) topLayout.addStretch() copyButton = QPushButton("Copy") copyButton.setToolTip("Copy file name to clipboard") topLayout.addWidget(copyButton) copyButton.clicked.connect(self.copy) launchButton = QPushButton("Launch") launchButton.setToolTip("Launch image viewer") topLayout.addWidget(launchButton) launchButton.clicked.connect(self.launch) mainLayout.addLayout(topLayout)
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 __init__(self, parent=None): super(HelpWindow,self).__init__(parent) self.setWindowTitle("Facepager 3.0 - Help") self.setMinimumWidth(600); self.setMinimumHeight(600); central = QWidget() self.setCentralWidget(central) vLayout = QVBoxLayout(central) self.page = MyQWebEnginePage() self.browser = QWebEngineView(central) self.browser.setPage(self.page) vLayout.addWidget(self.browser) hLayout = QHBoxLayout() vLayout.addLayout(hLayout) hLayout.addStretch(5) dismiss = QPushButton(central) dismiss.setText("Close") dismiss.clicked.connect(self.hide) hLayout.addWidget(dismiss)
def initializeWindow(self): layout = QVBoxLayout() self.m_deviceBox = QComboBox() self.m_deviceBox.activated[int].connect(self.deviceChanged) for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput): self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo) layout.addWidget(self.m_deviceBox) self.m_modeButton = QPushButton() self.m_modeButton.clicked.connect(self.toggleMode) self.m_modeButton.setText(self.PUSH_MODE_LABEL) layout.addWidget(self.m_modeButton) self.m_suspendResumeButton = QPushButton( clicked=self.toggleSuspendResume) self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) layout.addWidget(self.m_suspendResumeButton) volumeBox = QHBoxLayout() volumeLabel = QLabel("Volume:") self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100, singleStep=10) self.m_volumeSlider.valueChanged.connect(self.volumeChanged) volumeBox.addWidget(volumeLabel) volumeBox.addWidget(self.m_volumeSlider) layout.addLayout(volumeBox) window = QWidget() window.setLayout(layout) self.setCentralWidget(window)
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 testSetFocusWidget(self): widget = QPushButton() widget.show() context = self.app.inputContext() self.assertEqual(context.focusWidget(), None) if not widget.testAttribute(Qt.WA_InputMethodEnabled): widget.setAttribute(Qt.WA_InputMethodEnabled) context.setFocusWidget(widget) self.assertEqual(context.focusWidget(), widget)
def __init__(self): QWidget.__init__(self) m = QMenu(self) b = QPushButton("Hello", self) b.setMenu(m)
from PySide2.QtWidgets import QApplication, QWidget, QPushButton, QMainWindow import sys app = QApplication(sys.argv) window = QWidget() window.show() # Windoes are hidden by default app.exec_() # All widgets without parents are windows pushbutton_window = QPushButton() pushbutton_window.show() app.exec_() # QMainWindow provides more stuff main_window = QMainWindow() main_window.show() app.exec_()
def _create_switch_group(self, layout, group_name, button3, switch1, switch2, switch3): group_box = QGroupBox(group_name, self) layout.addWidget(group_box) group_layout = QGridLayout(group_box) group_box.setLayout(group_layout) group_layout.setMargin(0) group_layout.setSpacing(0) l = QLabel('S', group_box) l.setAlignment(Qt.AlignCenter) font = l.font() font.setPointSize(7) font.setBold(True) l.setFont(font) l.setMinimumWidth(30) group_layout.addWidget(l, 0, 0, Qt.AlignBottom) l = QLabel('PRESET', group_box) l.setAlignment(Qt.AlignCenter) l.setFont(font) l.setMinimumWidth(30) group_layout.addWidget(l, 0, 1, Qt.AlignBottom) l = QLabel(button3, group_box) l.setAlignment(Qt.AlignCenter) l.setFont(font) l.setMinimumWidth(30) group_layout.addWidget(l, 0, 2, Qt.AlignBottom) b1 = QPushButton(group_box) b1.setFixedSize(20, 20) group_layout.addWidget(b1, 1, 0, Qt.AlignCenter) b2 = QPushButton(group_box) b2.setFixedSize(20, 20) group_layout.addWidget(b2, 1, 1, Qt.AlignCenter) b3 = QPushButton(group_box) b3.setFixedSize(20, 20) group_layout.addWidget(b3, 1, 2, Qt.AlignCenter) s1 = self._create_switch(group_box, group_layout, 0, switch1) s2 = self._create_switch(group_box, group_layout, 1, switch2) s3 = self._create_switch(group_box, group_layout, 2, switch3) return b1, b2, b3, s1, s2, s3
def __init__(self, parent=None, *args, appctxt=None, **kwargs): """Initializes all GUI elements and a separate thread.""" super().__init__(parent) self.appctxt = appctxt self.worker = Worker(self) self.workerThread = QThread() self.worker.moveToThread(self.workerThread) self.workerThread.finished.connect(self.worker.deleteLater) self.worker.started.connect(self.startProgress) self.worker.ended.connect(self.endProgress) self.worker.translationsReady.connect(self.showTranslations) self.workerThread.start() screenGeometry = QGuiApplication.screens()[0].geometry() self.setGeometry(screenGeometry.width() / 5, screenGeometry.height() / 5, screenGeometry.width() / 3, screenGeometry.height() / 3) self.setMinimumSize(screenGeometry.width() / 4, screenGeometry.height() / 4) self.fileMenu = self.menuBar().addMenu(self.tr("&File")) self.exitAct = self.fileMenu.addAction(self.tr("&Exit")) self.exitAct.setStatusTip(self.tr("Exit from FreeLingvo")) self.exitAct.triggered.connect(self.close) self.helpMenu = self.menuBar().addMenu(self.tr("&Help")) self.aboutAct = self.helpMenu.addAction(self.tr("&About")) self.aboutAct.setStatusTip( self.tr("Show information about FreeLingvo")) self.aboutAct.triggered.connect(self.about) self.searchText = QLineEdit() self.searchText.setPlaceholderText( self.tr("What word(s) to look for?")) self.searchText.setClearButtonEnabled(True) self.searchText.returnPressed.connect(self.worker.findTranslations) self.translateButton = QPushButton(self.tr("Translate")) self.translateButton.clicked.connect(self.worker.findTranslations) self.dictsCombo = QComboBox() self.dictsCombo.setInsertPolicy(QComboBox.InsertAlphabetically) self.dictsCombo.setToolTip( self.tr("Dictionary used to search for words")) dictNames = os.listdir(self.appctxt.get_resource("dictionaries")) dictNames = [name.replace(".tei", "") for name in dictNames] self.dictsCombo.addItems(dictNames) self.dictsCombo.currentIndexChanged[str].connect(self.worker.loadDict) self.dictsCombo.setCurrentIndex(1) self.translationsBrowser = QTextBrowser() self.translationsBrowser.setUndoRedoEnabled(True) self.undoButton = QPushButton( QIcon(self.appctxt.get_resource("images/arrow_back.png")), "") self.undoButton.setEnabled(False) self.undoButton.setToolTip(self.tr("Show previous translation")) self.undoButton.clicked.connect(self.translationsBrowser.undo) self.translationsBrowser.undoAvailable.connect( self.undoButton.setEnabled) self.redoButton = QPushButton( QIcon(self.appctxt.get_resource("images/arrow_forward.png")), "") self.redoButton.setEnabled(False) self.redoButton.setToolTip(self.tr("Show next translation")) self.redoButton.clicked.connect(self.translationsBrowser.redo) self.translationsBrowser.redoAvailable.connect( self.redoButton.setEnabled) self.sizeLabel = QLabel(self.tr("Font size:")) self.sizeCombo = QComboBox() for size in QFontDatabase.standardSizes(): self.sizeCombo.addItem(str(size)) self.sizeCombo.setCurrentText(str(self.font().pointSize())) self.sizeCombo.currentIndexChanged[str].connect(self.changeFontSize) self.controlsLayout = QHBoxLayout() self.controlsLayout.addWidget(self.searchText) self.controlsLayout.addWidget(self.translateButton) self.controlsLayout.addWidget(self.dictsCombo) self.browserToolsLayout = QHBoxLayout() self.browserToolsLayout.addWidget(self.undoButton) self.browserToolsLayout.addWidget(self.redoButton) self.browserToolsLayout.addStretch(1) self.browserToolsLayout.addWidget(self.sizeLabel) self.browserToolsLayout.addWidget(self.sizeCombo) self.centralLayout = QVBoxLayout() self.centralLayout.addLayout(self.controlsLayout) self.centralLayout.addLayout(self.browserToolsLayout) self.centralLayout.addWidget(self.translationsBrowser) centralWidget = QWidget() centralWidget.setLayout(self.centralLayout) self.setCentralWidget(centralWidget) self.statusBar().showMessage(self.tr("Ready"), 2000)
class shotgun_ui(QWidget): e_local_export = Signal() e_shotgun_export = Signal(str) export_path = None def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) # Setup UI view v_main_box = QVBoxLayout() # Setup list for production handoff export option self.handoff_type_list = QComboBox() self.handoff_type_list.addItems(['Local Export', 'Shotgun Export']) self.handoff_type_label = QLabel('Handoff Type') self.handoff_type_label.setBuddy(self.handoff_type_list) self.handoff_type_list.currentTextChanged.connect( self.__on_handoff_type_changed) # Setup Local Export option self.export_layout = QHBoxLayout() self.export_path_button = QPushButton('Browse') self.export_path_button.clicked.connect(self.__browse_export_path) self.export_path, self.export_path_label = self.__create_line_label( '', 'Export Path', 200) self.__add_widget_to_layout(self.export_layout, self.export_path, self.export_path_button) # Setup Shotgun export option self.sg_hostname, self.sg_hostname_label = self.__create_line_label( 'https://thomaslacroix.shotgunstudio.com', 'Shotgun URL', 350) self.sg_login, self.sg_login_label = self.__create_line_label( '*****@*****.**', 'Username', 200) pull = QPushButton('Export Latest') pull.clicked.connect(self.__pull_latest) self.__add_widget_to_layout(v_main_box, self.handoff_type_label, self.handoff_type_list, self.export_path_label) v_main_box.addLayout(self.export_layout) self.__add_widget_to_layout(v_main_box, self.sg_hostname_label, self.sg_hostname, self.sg_login_label, self.sg_login, pull) self.__update_ui_handoff_type('Local Export') self.setLayout(v_main_box) def get_shotgun_api(self) -> shotgun_api.shotgun: """get_shotgun_api will return the shotgun_api Returns: shotgun_api.shotgun -- Shotgun api """ return self.shotgun def create_folders(self, show_tc: str, seq_tc: str, seq_rev_nbr: int, episode_tc: str = None) -> str: """create_folders will create the structure of folders from shows to sequence revision Arguments: show_tc {str} -- Show tracking code seq_tc {str} -- Sequence tracking code seq_rev_nbr {int} -- Sequence revision number episode_tc {str} -- Episode tracking code (default: {None}) Returns: str -- Sequence revision path """ show_path = os.path.join(self.export_path.text(), show_tc) self.__create_folder(show_path) sequence_path = os.path.join(show_path, seq_tc) if episode_tc is not None: episode_path = os.path.join(show_path, episode_tc) self.__create_folder(episode_path) sequence_path = os.path.join(episode_path, seq_tc) self.__create_folder(sequence_path) sequence_revision_path = os.path.join(sequence_path, 'v{0}'.format(seq_rev_nbr)) self.__create_folder(sequence_revision_path) return sequence_revision_path def get_shot_download_paths(self, export_path: str, shot: str) -> Tuple[str, str, str]: """get_shot_download_paths will create folders for show, artwork and thumbnails and return those paths Arguments: export_path {str} -- Base export path shot {str} -- Shot name Returns: Tuple[str, str, str] -- show_path, artwork_path, thumb_path """ show_folder_path = os.path.join(export_path, shot) self.__create_folder(show_folder_path) artwork_folder_path = os.path.join(show_folder_path, 'artwork') self.__create_folder(artwork_folder_path) thumb_folder_path = os.path.join(show_folder_path, 'thumbnail') self.__create_folder(thumb_folder_path) return show_folder_path, artwork_folder_path, thumb_folder_path def export_to_version(self, shots: List, sg_password: str, show_tc: str, seq_rev_nbr: int, seq_tc: str, fn_progress: Callable[[str], None]) -> Dict: """export_to_version will export to shotgun a project, a sequence, a shot and version Arguments: shots {List} -- List of shots sg_password {str} -- Shotgun password show_tc {str} -- Show tracking code seq_rev_nbr {int} -- Sequence revision number seq_tc {str} -- Sequence tracking code Callable[[str], None]) -- fn_progress is a progress function Returns: Dict -- Mapping of shot to quicktime info with his corresponding shotgun version """ fn_progress('get or create shotgun project') sg_show = self.shotgun.get_project(show_tc) if sg_show is None: sg_show = self.shotgun.create_project(show_tc) fn_progress('get or create shotgun sequence') sg_seq = self.shotgun.get_sequence(sg_show, seq_tc) if sg_seq is None: sg_seq = self.shotgun.create_seq(sg_show, seq_tc) shot_to_file = {} for shot_name in shots: fn_progress( 'get or create shotgun shot for shot {0}'.format(shot_name)) sg_shot = self.shotgun.get_shot(sg_show, sg_seq, shot_name) if sg_shot is None: sg_shot = self.shotgun.create_shot(sg_show, sg_seq, shot_name) fn_progress( 'get or create shotgun version for shot {0}'.format(shot_name)) version = self.shotgun.get_version(sg_show, sg_shot) if version is None: new_version = 1 else: ver = re.search('(.*)v([0-9]+)', version['code']) new_version = int(ver.group(2)) + 1 version = self.shotgun.create_version(sg_show, sg_shot, new_version) mov_name = '{0}_v{1}_{2}.mov'.format(seq_tc, seq_rev_nbr, shot_name) shot_to_file[shot_name] = { 'mov_name': mov_name, 'version': version } return shot_to_file def init_local_export(self) -> bool: """init_local_export will initialise the export Returns: bool -- If the export path is valid or not """ if len(self.export_path.text()) <= 0: self.__info('You need to select an export path') return False if os.path.exists(self.export_path.text()) is False: self.__info('Invalid export path') return False return True def init_shotgun_export(self) -> bool: """init_shotgun_export will init the shotgun export Returns: bool -- Can login to shotgun """ if self.sg_login.text() == '' or self.sg_hostname.text() == '': self.__info('You need to enter your shotgun info') return '', False sg_password, ok = QInputDialog().getText(self, 'Shotgun password', 'Shotgun password:'******'', False self.shotgun = shotgun_api.shotgun(self.sg_hostname.text(), self.sg_login.text(), sg_password) return sg_password, True def __pull_latest(self): """__pull_latest will export the latest sequence revision """ if self.selected_handoff_type == 'Local Export': if self.init_local_export(): self.e_local_export.emit() else: sg_password, ok = self.init_shotgun_export() if ok: self.e_shotgun_export.emit(sg_password) def __create_line_label(self, name: str, label: str, min_width: int = 200) -> Tuple[Dict, Dict]: """__create_line_label will create a line edit button and his label Arguments: name {str} -- Default value label {str} -- Label name min_width {int} -- Minium width (default: {200}) Returns: Tuple[Dict, Dict] -- Line Edit, Label """ line_edit = QLineEdit(name) line_edit.setMinimumWidth(min_width) label = QLabel(label) label.setBuddy(line_edit) return line_edit, label def __add_widget_to_layout(self, layout: Dict, *widgets: Dict): """__add_widget_to_layout will add all the widget to a layout __add_widget_to_layout(layout, widget1, widget2, widget3) Arguments: layout {Dict} -- Layout to add widget to widgets {*Dict} -- All the widgets to add """ for w in widgets: layout.addWidget(w) def __error(self, message: str): """__error will show a error message with a given message Arguments: message {str} -- Message to show """ err = QErrorMessage(self.parent()) err.setWindowTitle('Flix') err.showMessage(message) err.exec_() def __info(self, message: str): """__info will show a message with a given message Arguments: message {str} -- Message to show """ msgbox = QMessageBox(self.parent()) msgbox.setWindowTitle('Flix') msgbox.setText(message) msgbox.exec_() def __on_handoff_type_changed(self, handoff_type: str): """__on_handoff_type_changed triggered when the handoff type changed Arguments: handoff_type {str} -- Handoff type from the event """ self.__update_ui_handoff_type(handoff_type) def __browse_export_path(self): """__browse_export_path will create a dialog window to browse and set an export path """ dialog = QFileDialog() export_p = None if self.export_path.text() is not '': if os.path.exists(self.export_path.text()): export_p = self.export_path.text() export_p = dialog.getExistingDirectory(dir=export_p) if len(export_p) < 1: return self.export_path.setText(export_p) def __update_ui_handoff_type(self, handoff_type: str): """__update_ui_handoff_type will update the UI depending of the handoff type Arguments: handoff_type {str} -- Handoff type """ if handoff_type == 'Local Export': self.sg_hostname.hide() self.sg_hostname_label.hide() self.sg_login.hide() self.sg_login_label.hide() self.export_path_label.show() self.export_path.show() self.export_path_button.show() else: self.sg_hostname.show() self.sg_hostname_label.show() self.sg_login.show() self.sg_login_label.show() self.export_path_label.hide() self.export_path.hide() self.export_path_button.hide() self.selected_handoff_type = handoff_type def __create_folder(self, path: str): """__create_folder will create a folder if it does not exist Arguments: path {str} -- Path to create the folder """ if not os.path.exists(path): os.makedirs(path)
def __init__(self, filename, image, parent=None): super(ComparisonWidget, self).__init__(parent) load_button = QPushButton(self.tr('Load reference image...')) self.comp_label = QLabel(self.tr('Comparison:')) self.normal_radio = QRadioButton(self.tr('Normal')) self.normal_radio.setToolTip(self.tr('Show reference (raw pixels)')) self.normal_radio.setChecked(True) self.difference_radio = QRadioButton(self.tr('Difference')) self.difference_radio.setToolTip( self.tr('Show evidence/reference difference')) self.ssim_radio = QRadioButton(self.tr('SSIM Map')) self.ssim_radio.setToolTip(self.tr('Structure similarity quality map')) self.butter_radio = QRadioButton(self.tr('Butteraugli')) self.butter_radio.setToolTip( self.tr('Butteraugli spatial changes heatmap')) self.gray_check = QCheckBox(self.tr('Grayscale')) self.gray_check.setToolTip(self.tr('Show desaturated output')) self.equalize_check = QCheckBox(self.tr('Equalized')) self.equalize_check.setToolTip(self.tr('Apply histogram equalization')) self.last_radio = self.normal_radio self.metric_button = QPushButton(self.tr('Compute metrics')) self.metric_button.setToolTip( self.tr('Image quality assessment metrics')) self.evidence = image self.reference = self.difference = self.ssim_map = self.butter_map = None basename = os.path.basename(filename) self.evidence_viewer = ImageViewer( self.evidence, None, self.tr('Evidence: {}'.format(basename))) self.reference_viewer = ImageViewer(np.full_like(self.evidence, 127), None, self.tr('Reference')) self.table_widget = QTableWidget(21, 3) self.table_widget.setHorizontalHeaderLabels( [self.tr('Metric'), self.tr('Value'), self.tr('Better')]) self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('RMSE'))) self.table_widget.setItem( 0, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(0, 0).setToolTip( self. tr('Root Mean Square Error (RMSE) is commonly used to compare \n' 'the difference between the reference and evidence images \n' 'by directly computing the variation in pixel values. \n' 'The combined image is close to the reference image when \n' 'RMSE value is zero. RMSE is a good indicator of the spectral \n' 'quality of the reference image.')) self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('SAM'))) self.table_widget.setItem( 1, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(1, 0).setToolTip( self. tr('It computes the spectral angle between the pixel, vector of the \n' 'evidence image and reference image. It is worked out in either \n' 'degrees or radians. It is performed on a pixel-by-pixel base. \n' 'A SAM equal to zero denotes the absence of spectral distortion.' )) self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('ERGAS'))) self.table_widget.setItem( 2, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(2, 0).setToolTip( self. tr('It is used to compute the quality of reference image in terms \n' 'of normalized average error of each band of the reference image. \n' 'Increase in the value of ERGAS indicates distortion in the \n' 'reference image, lower value of ERGAS indicates that it is \n' 'similar to the reference image.')) self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('MB'))) self.table_widget.setItem( 3, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(3, 0).setToolTip( self. tr('Mean Bias is the difference between the mean of the evidence \n' 'image and reference image. The ideal value is zero and indicates \n' 'that the evidence and reference images are similar. Mean value \n' 'refers to the grey level of pixels in an image.')) self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('PFE'))) self.table_widget.setItem( 4, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(4, 0).setToolTip( self. tr('It computes the norm of the difference between the corresponding \n' 'pixels of the reference and fused image to the norm of the reference \n' 'image. When the calculated value is zero, it indicates that both the \n' 'reference and fused images are similar and value will be increased \n' 'when the merged image is not similar to the reference image.')) self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('PSNR'))) self.table_widget.setItem( 5, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(5, 0).setToolTip( self. tr('It is widely used metric it is computed by the number of gray levels \n' 'in the image divided by the corresponding pixels in the evidence and \n' 'the reference images. When the value is high, both images are similar.' )) self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('PSNR-B'))) self.table_widget.setItem( 6, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(6, 0).setToolTip( self.tr('PSNR with Blocking Effect Factor.')) self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('SSIM'))) self.table_widget.setItem( 7, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(7, 0).setToolTip( self. tr('SSIM is used to compare the local patterns of pixel intensities between \n' ' the reference and fused images. The range varies between -1 to 1. \n' 'The value 1 indicates the reference and fused images are similar.' )) self.table_widget.setItem(8, 0, QTableWidgetItem(self.tr('MS-SSIM'))) self.table_widget.setItem( 8, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(8, 0).setToolTip( self.tr('Multiscale version of SSIM.')) self.table_widget.setItem(9, 0, QTableWidgetItem(self.tr('RASE'))) self.table_widget.setItem( 9, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(9, 0).setToolTip( self.tr('Relative average spectral error')) self.table_widget.setItem(10, 0, QTableWidgetItem(self.tr('SCC'))) self.table_widget.setItem( 10, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(10, 0).setToolTip( self.tr('Spatial Correlation Coefficient')) self.table_widget.setItem(11, 0, QTableWidgetItem(self.tr('UQI'))) self.table_widget.setItem( 11, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(11, 0).setToolTip( self.tr('Universal Image Quality Index')) self.table_widget.setItem(12, 0, QTableWidgetItem(self.tr('VIF-P'))) self.table_widget.setItem( 12, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(12, 0).setToolTip( self.tr('Pixel-based Visual Information Fidelity')) self.table_widget.setItem(13, 0, QTableWidgetItem(self.tr('SSIMulacra'))) self.table_widget.setItem( 13, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(13, 0).setToolTip( self.tr('Structural SIMilarity Unveiling Local ' 'And Compression Related Artifacts')) self.table_widget.setItem(14, 0, QTableWidgetItem(self.tr('Butteraugli'))) self.table_widget.setItem( 14, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(14, 0).setToolTip( self.tr('Estimate psychovisual error')) self.table_widget.setItem(15, 0, QTableWidgetItem(self.tr('Correlation'))) self.table_widget.setItem( 15, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(15, 0).setToolTip(self.tr('Histogram correlation')) self.table_widget.setItem(16, 0, QTableWidgetItem(self.tr('Chi-Square'))) self.table_widget.setItem( 16, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(16, 0).setToolTip(self.tr('Histogram Chi-Square')) self.table_widget.setItem(17, 0, QTableWidgetItem(self.tr('Chi-Square 2'))) self.table_widget.setItem( 17, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(17, 0).setToolTip(self.tr('Alternative Chi-Square')) self.table_widget.setItem(18, 0, QTableWidgetItem(self.tr('Intersection'))) self.table_widget.setItem( 18, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(18, 0).setToolTip(self.tr('Histogram intersection')) self.table_widget.setItem(19, 0, QTableWidgetItem(self.tr('Hellinger'))) self.table_widget.setItem( 19, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(19, 0).setToolTip( self.tr('Histogram Hellinger distance')) self.table_widget.setItem(20, 0, QTableWidgetItem(self.tr('Divergence'))) self.table_widget.setItem( 20, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(20, 0).setToolTip( self.tr('Kullback-Leibler divergence')) for i in range(self.table_widget.rowCount()): modify_font(self.table_widget.item(i, 0), bold=True) self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection) self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_widget.resizeColumnsToContents() self.table_widget.setMaximumWidth(250) self.table_widget.setAlternatingRowColors(True) self.stopped = False self.comp_label.setEnabled(False) self.normal_radio.setEnabled(False) self.difference_radio.setEnabled(False) self.ssim_radio.setEnabled(False) self.butter_radio.setEnabled(False) self.gray_check.setEnabled(False) self.equalize_check.setEnabled(False) self.metric_button.setEnabled(False) self.table_widget.setEnabled(False) load_button.clicked.connect(self.load) self.normal_radio.clicked.connect(self.change) self.difference_radio.clicked.connect(self.change) self.butter_radio.clicked.connect(self.change) self.gray_check.stateChanged.connect(self.change) self.equalize_check.stateChanged.connect(self.change) self.ssim_radio.clicked.connect(self.change) self.evidence_viewer.viewChanged.connect( self.reference_viewer.changeView) self.reference_viewer.viewChanged.connect( self.evidence_viewer.changeView) self.metric_button.clicked.connect(self.metrics) top_layout = QHBoxLayout() top_layout.addWidget(load_button) top_layout.addStretch() top_layout.addWidget(self.comp_label) top_layout.addWidget(self.normal_radio) top_layout.addWidget(self.difference_radio) top_layout.addWidget(self.ssim_radio) top_layout.addWidget(self.butter_radio) top_layout.addWidget(self.gray_check) top_layout.addWidget(self.equalize_check) metric_layout = QVBoxLayout() index_label = QLabel(self.tr('Image Quality Assessment')) index_label.setAlignment(Qt.AlignCenter) modify_font(index_label, bold=True) metric_layout.addWidget(index_label) metric_layout.addWidget(self.table_widget) metric_layout.addWidget(self.metric_button) center_layout = QHBoxLayout() center_layout.addWidget(self.evidence_viewer) center_layout.addWidget(self.reference_viewer) center_layout.addLayout(metric_layout) main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addLayout(center_layout) self.setLayout(main_layout)
class MainWindow(QMainWindow, Ui_MainWindow): """docstring for MainWindow.""" def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self._csvFilePath = "" self.serialport = serial.Serial() self.receiver_thread = readerThread(self) self.receiver_thread.setPort(self.serialport) self._localEcho = None self.setupUi(self) self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) font = QtGui.QFont() font.setFamily(EDITOR_FONT) font.setPointSize(10) self.txtEdtOutput.setFont(font) self.txtEdtInput.setFont(font) self.quickSendTable.setFont(font) if UI_FONT is not None: font = QtGui.QFont() font.setFamily(UI_FONT) font.setPointSize(9) self.dockWidget_PortConfig.setFont(font) self.dockWidget_SendHex.setFont(font) self.dockWidget_QuickSend.setFont(font) self.setupFlatUi() self.onEnumPorts() icon = QtGui.QIcon(":/icon.ico") self.setWindowIcon(icon) self.actionAbout.setIcon(icon) icon = QtGui.QIcon(":/qt_logo_16.ico") self.actionAbout_Qt.setIcon(icon) self._viewGroup = QActionGroup(self) self._viewGroup.addAction(self.actionAscii) self._viewGroup.addAction(self.actionHex_lowercase) self._viewGroup.addAction(self.actionHEX_UPPERCASE) self._viewGroup.setExclusive(True) # bind events self.actionOpen_Cmd_File.triggered.connect(self.openCSV) self.actionSave_Log.triggered.connect(self.onSaveLog) self.actionExit.triggered.connect(self.onExit) self.actionOpen.triggered.connect(self.openPort) self.actionClose.triggered.connect(self.closePort) self.actionPort_Config_Panel.triggered.connect(self.onTogglePrtCfgPnl) self.actionQuick_Send_Panel.triggered.connect(self.onToggleQckSndPnl) self.actionSend_Hex_Panel.triggered.connect(self.onToggleHexPnl) self.dockWidget_PortConfig.visibilityChanged.connect(self.onVisiblePrtCfgPnl) self.dockWidget_QuickSend.visibilityChanged.connect(self.onVisibleQckSndPnl) self.dockWidget_SendHex.visibilityChanged.connect(self.onVisibleHexPnl) self.actionLocal_Echo.triggered.connect(self.onLocalEcho) self.actionAlways_On_Top.triggered.connect(self.onAlwaysOnTop) self.actionAscii.triggered.connect(self.onViewChanged) self.actionHex_lowercase.triggered.connect(self.onViewChanged) self.actionHEX_UPPERCASE.triggered.connect(self.onViewChanged) self.actionAbout.triggered.connect(self.onAbout) self.actionAbout_Qt.triggered.connect(self.onAboutQt) self.btnOpen.clicked.connect(self.onOpen) self.btnClear.clicked.connect(self.onClear) self.btnSaveLog.clicked.connect(self.onSaveLog) self.btnEnumPorts.clicked.connect(self.onEnumPorts) self.btnSendHex.clicked.connect(self.sendHex) self.receiver_thread.read.connect(self.receive) self.receiver_thread.exception.connect(self.readerExcept) self._signalMap = QSignalMapper(self) self._signalMap.mapped[int].connect(self.tableClick) # initial action self.actionHEX_UPPERCASE.setChecked(True) self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE) self.initQuickSend() self.restoreLayout() self.moveScreenCenter() self.syncMenu() if self.isMaximized(): self.setMaximizeButton("restore") else: self.setMaximizeButton("maximize") self.LoadSettings() def setupFlatUi(self): self._dragPos = self.pos() self._isDragging = False self.setMouseTracking(True) self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(""" QWidget { background-color:#99d9ea; /*background-image: url(:/background.png);*/ outline: 1px solid #0057ff; } QLabel { color:#202020; font-size:13px; font-family:Century; } QComboBox { color:#202020; font-size:13px; font-family:Century Schoolbook; } QComboBox { border: none; padding: 1px 18px 1px 3px; } QComboBox:editable { background: white; } QComboBox:!editable, QComboBox::drop-down:editable { background: #62c7e0; } QComboBox:!editable:hover, QComboBox::drop-down:editable:hover { background: #c7eaf3; } QComboBox:!editable:pressed, QComboBox::drop-down:editable:pressed { background: #35b6d7; } QComboBox:on { padding-top: 3px; padding-left: 4px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 16px; border: none; } QComboBox::down-arrow { image: url(:/downarrow.png); } QComboBox::down-arrow:on { image: url(:/uparrow.png); } QGroupBox { color:#202020; font-size:12px; font-family:Century Schoolbook; border: 1px solid gray; margin-top: 15px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; left:5px; top:3px; } QCheckBox { color:#202020; spacing: 5px; font-size:12px; font-family:Century Schoolbook; } QScrollBar:horizontal { background-color:#99d9ea; border: none; height: 15px; margin: 0px 20px 0 20px; } QScrollBar::handle:horizontal { background: #61b9e1; min-width: 20px; } QScrollBar::add-line:horizontal { image: url(:/rightarrow.png); border: none; background: #7ecfe4; width: 20px; subcontrol-position: right; subcontrol-origin: margin; } QScrollBar::sub-line:horizontal { image: url(:/leftarrow.png); border: none; background: #7ecfe4; width: 20px; subcontrol-position: left; subcontrol-origin: margin; } QScrollBar:vertical { background-color:#99d9ea; border: none; width: 15px; margin: 20px 0px 20px 0px; } QScrollBar::handle::vertical { background: #61b9e1; min-height: 20px; } QScrollBar::add-line::vertical { image: url(:/downarrow.png); border: none; background: #7ecfe4; height: 20px; subcontrol-position: bottom; subcontrol-origin: margin; } QScrollBar::sub-line::vertical { image: url(:/uparrow.png); border: none; background: #7ecfe4; height: 20px; subcontrol-position: top; subcontrol-origin: margin; } QTableView { background-color: white; /*selection-background-color: #FF92BB;*/ border: 1px solid #eeeeee; color: #2f2f2f; } QTableView::focus { /*border: 1px solid #2a7fff;*/ } QTableView QTableCornerButton::section { border: none; border-right: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; background-color: #8ae6d2; } QTableView QWidget { background-color: white; } QTableView::item:focus { border: 1px red; background-color: transparent; color: #2f2f2f; } QHeaderView::section { border: none; border-right: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; padding-left: 2px; padding-right: 2px; color: #444444; background-color: #8ae6d2; } QTextEdit { background-color:white; color:#2f2f2f; border: 1px solid white; } QTextEdit::focus { border: 1px solid #2a7fff; } QPushButton { background-color:#30a7b8; border:none; color:#ffffff; font-size:14px; font-family:Century Schoolbook; } QPushButton:hover { background-color:#51c0d1; } QPushButton:pressed { background-color:#3a9ecc; } QMenuBar { color: #2f2f2f; } QMenuBar::item { background-color: transparent; margin: 8px 0px 0px 0px; padding: 1px 8px 1px 8px; height: 15px; } QMenuBar::item:selected { background: #51c0d1; } QMenuBar::item:pressed { } QMenu { color: #2f2f2f; } QMenu { margin: 2px; } QMenu::item { padding: 2px 25px 2px 21px; border: 1px solid transparent; } QMenu::item:selected { background: #51c0d1; } QMenu::icon { background: transparent; border: 2px inset transparent; } QDockWidget { font-size:13px; font-family:Century; color: #202020; titlebar-close-icon: none; titlebar-normal-icon: none; } QDockWidget::title { margin: 0; padding: 2px; subcontrol-origin: content; subcontrol-position: right top; text-align: left; background: #67baed; } QDockWidget::float-button { max-width: 12px; max-height: 12px; background-color:transparent; border:none; image: url(:/restore_inactive.png); } QDockWidget::float-button:hover { background-color:#227582; image: url(:/restore_active.png); } QDockWidget::float-button:pressed { padding: 0; background-color:#14464e; image: url(:/restore_active.png); } QDockWidget::close-button { max-width: 12px; max-height: 12px; background-color:transparent; border:none; image: url(:/close_inactive.png); } QDockWidget::close-button:hover { background-color:#ea5e00; image: url(:/close_active.png); } QDockWidget::close-button:pressed { background-color:#994005; image: url(:/close_active.png); padding: 0; } """) self.dockWidgetContents.setStyleSheet(""" QPushButton { min-height:23px; } """) self.dockWidget_QuickSend.setStyleSheet(""" QPushButton { background-color:#27b798; font-family:Consolas; font-size:12px; min-width:46px; } QPushButton:hover { background-color:#3bd5b4; } QPushButton:pressed { background-color:#1d8770; } """) self.dockWidgetContents_2.setStyleSheet(""" QPushButton { min-height:23px; min-width:50px; } """) w = self.frameGeometry().width() self._minBtn = QPushButton(self) self._minBtn.setGeometry(w-103,0,28,24) self._minBtn.clicked.connect(self.onMinimize) self._minBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/minimize_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/minimize_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/minimize_active.png); } """) self._maxBtn = QPushButton(self) self._maxBtn.setGeometry(w-74,0,28,24) self._maxBtn.clicked.connect(self.onMaximize) self.setMaximizeButton("maximize") self._closeBtn = QPushButton(self) self._closeBtn.setGeometry(w-45,0,36,24) self._closeBtn.clicked.connect(self.onExit) self._closeBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/close_inactive.png); } QPushButton:hover { background-color:#ea5e00; image: url(:/close_active.png); } QPushButton:pressed { background-color:#994005; image: url(:/close_active.png); } """) def resizeEvent(self, event): w = event.size().width() self._minBtn.move(w-103,0) self._maxBtn.move(w-74,0) self._closeBtn.move(w-45,0) def onMinimize(self): self.showMinimized() def isMaximized(self): return ((self.windowState() == Qt.WindowMaximized)) def onMaximize(self): if self.isMaximized(): self.showNormal() self.setMaximizeButton("maximize") else: self.showMaximized() self.setMaximizeButton("restore") def setMaximizeButton(self, style): if "maximize" == style: self._maxBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/maximize_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/maximize_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/maximize_active.png); } """) elif "restore" == style: self._maxBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/restore_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/restore_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/restore_active.png); } """) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self._isDragging = True self._dragPos = event.globalPos() - self.pos() event.accept() def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton and self._isDragging and not self.isMaximized(): self.move(event.globalPos() - self._dragPos) event.accept() def mouseReleaseEvent(self, event): self._isDragging = False event.accept() def SaveSettings(self): root = ET.Element("MyTerm") GUISettings = ET.SubElement(root, "GUISettings") PortCfg = ET.SubElement(GUISettings, "PortConfig") ET.SubElement(PortCfg, "port").text = self.cmbPort.currentText() ET.SubElement(PortCfg, "baudrate").text = self.cmbBaudRate.currentText() ET.SubElement(PortCfg, "databits").text = self.cmbDataBits.currentText() ET.SubElement(PortCfg, "parity").text = self.cmbParity.currentText() ET.SubElement(PortCfg, "stopbits").text = self.cmbStopBits.currentText() ET.SubElement(PortCfg, "rtscts").text = self.chkRTSCTS.isChecked() and "on" or "off" ET.SubElement(PortCfg, "xonxoff").text = self.chkXonXoff.isChecked() and "on" or "off" View = ET.SubElement(GUISettings, "View") ET.SubElement(View, "LocalEcho").text = self.actionLocal_Echo.isChecked() and "on" or "off" ET.SubElement(View, "ReceiveView").text = self._viewGroup.checkedAction().text() with open(get_config_path('settings.xml'), 'w') as f: f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write(ET.tostring(root, encoding='utf-8', pretty_print=True).decode("utf-8")) def LoadSettings(self): if os.path.isfile(get_config_path("settings.xml")): with open(get_config_path("settings.xml"), 'r') as f: tree = safeET.parse(f) port = tree.findtext('GUISettings/PortConfig/port', default='') if port != '': self.cmbPort.setCurrentText(port) baudrate = tree.findtext('GUISettings/PortConfig/baudrate', default='38400') if baudrate != '': self.cmbBaudRate.setCurrentText(baudrate) databits = tree.findtext('GUISettings/PortConfig/databits', default='8') id = self.cmbDataBits.findText(databits) if id >= 0: self.cmbDataBits.setCurrentIndex(id) parity = tree.findtext('GUISettings/PortConfig/parity', default='None') id = self.cmbParity.findText(parity) if id >= 0: self.cmbParity.setCurrentIndex(id) stopbits = tree.findtext('GUISettings/PortConfig/stopbits', default='1') id = self.cmbStopBits.findText(stopbits) if id >= 0: self.cmbStopBits.setCurrentIndex(id) rtscts = tree.findtext('GUISettings/PortConfig/rtscts', default='off') if 'on' == rtscts: self.chkRTSCTS.setChecked(True) else: self.chkRTSCTS.setChecked(False) xonxoff = tree.findtext('GUISettings/PortConfig/xonxoff', default='off') if 'on' == xonxoff: self.chkXonXoff.setChecked(True) else: self.chkXonXoff.setChecked(False) LocalEcho = tree.findtext('GUISettings/View/LocalEcho', default='off') if 'on' == LocalEcho: self.actionLocal_Echo.setChecked(True) self._localEcho = True else: self.actionLocal_Echo.setChecked(False) self._localEcho = False ReceiveView = tree.findtext('GUISettings/View/ReceiveView', default='HEX(UPPERCASE)') if 'Ascii' in ReceiveView: self.actionAscii.setChecked(True) elif 'lowercase' in ReceiveView: self.actionHex_lowercase.setChecked(True) elif 'UPPERCASE' in ReceiveView: self.actionHEX_UPPERCASE.setChecked(True) def closeEvent(self, event): self.saveLayout() self.saveCSV() self.SaveSettings() event.accept() def tableClick(self, row): self.sendTableRow(row) def initQuickSend(self): #self.quickSendTable.horizontalHeader().setDefaultSectionSize(40) #self.quickSendTable.horizontalHeader().setMinimumSectionSize(25) self.quickSendTable.setRowCount(50) self.quickSendTable.setColumnCount(20) for row in range(50): item = QPushButton(str("Send")) item.clicked.connect(self._signalMap.map) self._signalMap.setMapping(item, row) self.quickSendTable.setCellWidget(row, 0, item) self.quickSendTable.setRowHeight(row, 20) if os.path.isfile(get_config_path('QckSndBckup.csv')): self.loadCSV(get_config_path('QckSndBckup.csv')) self.quickSendTable.resizeColumnsToContents() def openCSV(self): fileName = QFileDialog.getOpenFileName(self, "Select a file", os.getcwd(), "CSV Files (*.csv)")[0] if fileName: self.loadCSV(fileName, notifyExcept = True) def saveCSV(self): # scan table rows = self.quickSendTable.rowCount() cols = self.quickSendTable.columnCount() tmp_data = [[self.quickSendTable.item(row, col) is not None and self.quickSendTable.item(row, col).text() or '' for col in range(1, cols)] for row in range(rows)] data = [] # delete trailing blanks for row in tmp_data: for idx, d in enumerate(row[::-1]): if '' != d: break new_row = row[:len(row) - idx] data.append(new_row) #import pprint #pprint.pprint(data, width=120, compact=True) # write to file with open(get_config_path('QckSndBckup.csv'), 'w') as csvfile: csvwriter = csv.writer(csvfile, delimiter=',', lineterminator='\n') csvwriter.writerows(data) def loadCSV(self, path, notifyExcept = False): data = [] set_rows = 0 set_cols = 0 try: with open(path) as csvfile: csvData = csv.reader(csvfile) for row in csvData: data.append(row) set_rows = set_rows + 1 if len(row) > set_cols: set_cols = len(row) except IOError as e: print("({})".format(e)) if notifyExcept: QMessageBox.critical(self, "Open failed", str(e), QMessageBox.Close) return rows = self.quickSendTable.rowCount() cols = self.quickSendTable.columnCount() # clear table for col in range(cols): for row in range(rows): self.quickSendTable.setItem(row, col, QTableWidgetItem("")) self._csvFilePath = path if (cols - 1) < set_cols: # first colume is used by the "send" buttons. cols = set_cols + 10 self.quickSendTable.setColumnCount(cols) if rows < set_rows: rows = set_rows + 20 self.quickSendTable.setRowCount(rows) for row, rowdat in enumerate(data): if len(rowdat) > 0: for col, cell in enumerate(rowdat, 1): self.quickSendTable.setItem(row, col, QTableWidgetItem(str(cell))) self.quickSendTable.resizeColumnsToContents() #self.quickSendTable.resizeRowsToContents() def sendTableRow(self, row): cols = self.quickSendTable.columnCount() try: data = ['0' + self.quickSendTable.item(row, col).text() for col in range(1, cols) if self.quickSendTable.item(row, col) is not None and self.quickSendTable.item(row, col).text() is not ''] except: print("Exception in get table data(row = %d)" % (row + 1)) else: tmp = [d[-2] + d[-1] for d in data if len(d) >= 2] for t in tmp: if not is_hex(t): QMessageBox.critical(self, "Error", "'%s' is not hexadecimal." % (t), QMessageBox.Close) return h = [int(t, 16) for t in tmp] self.transmitHex(h) def sendHex(self): hexStr = self.txtEdtInput.toPlainText() hexStr = ''.join(hexStr.split(" ")) hexarray = [] for i in range(0, len(hexStr), 2): hexarray.append(int(hexStr[i:i+2], 16)) self.transmitHex(hexarray) def readerExcept(self, e): self.closePort() QMessageBox.critical(self, "Read failed", str(e), QMessageBox.Close) def timestamp(self): return datetime.datetime.now().time().isoformat()[:-3] def receive(self, data): self.appendOutputText("\n%s R<-:%s" % (self.timestamp(), data)) def appendOutputText(self, data, color=Qt.black): # the qEditText's "append" methon will add a unnecessary newline. # self.txtEdtOutput.append(data.decode('utf-8')) tc=self.txtEdtOutput.textColor() self.txtEdtOutput.moveCursor(QtGui.QTextCursor.End) self.txtEdtOutput.setTextColor(QtGui.QColor(color)) self.txtEdtOutput.insertPlainText(data) self.txtEdtOutput.moveCursor(QtGui.QTextCursor.End) self.txtEdtOutput.setTextColor(tc) def transmitHex(self, hexarray): if len(hexarray) > 0: byteArray = bytearray(hexarray) if self.serialport.isOpen(): try: self.serialport.write(byteArray) except serial.SerialException as e: print("Exception in transmitHex(%s)" % repr(hexarray)) QMessageBox.critical(self, "Exception in transmitHex", str(e), QMessageBox.Close) else: # self.txCount += len( b ) # self.frame.statusbar.SetStatusText('Tx:%d' % self.txCount, 2) text = ''.join(['%02X ' % i for i in hexarray]) self.appendOutputText("\n%s T->:%s" % (self.timestamp(), text), Qt.blue) def GetPort(self): return self.cmbPort.currentText() def GetDataBits(self): s = self.cmbDataBits.currentText() if s == '5': return serial.FIVEBITS elif s == '6': return serial.SIXBITS elif s == '7': return serial.SEVENBITS elif s == '8': return serial.EIGHTBITS def GetParity(self): s = self.cmbParity.currentText() if s == 'None': return serial.PARITY_NONE elif s == 'Even': return serial.PARITY_EVEN elif s == 'Odd': return serial.PARITY_ODD elif s == 'Mark': return serial.PARITY_MARK elif s == 'Space': return serial.PARITY_SPACE def GetStopBits(self): s = self.cmbStopBits.currentText() if s == '1': return serial.STOPBITS_ONE elif s == '1.5': return serial.STOPBITS_ONE_POINT_FIVE elif s == '2': return serial.STOPBITS_TWO def openPort(self): if self.serialport.isOpen(): return _port = self.GetPort() if '' == _port: QMessageBox.information(self, "Invalid parameters", "Port is empty.") return _baudrate = self.cmbBaudRate.currentText() if '' == _baudrate: QMessageBox.information(self, "Invalid parameters", "Baudrate is empty.") return self.serialport.port = _port self.serialport.baudrate = _baudrate self.serialport.bytesize = self.GetDataBits() self.serialport.stopbits = self.GetStopBits() self.serialport.parity = self.GetParity() self.serialport.rtscts = self.chkRTSCTS.isChecked() self.serialport.xonxoff = self.chkXonXoff.isChecked() # self.serialport.timeout = THREAD_TIMEOUT # self.serialport.writeTimeout = SERIAL_WRITE_TIMEOUT try: self.serialport.open() except serial.SerialException as e: QMessageBox.critical(self, "Could not open serial port", str(e), QMessageBox.Close) else: self._start_reader() self.setWindowTitle("%s on %s [%s, %s%s%s%s%s]" % ( appInfo.title, self.serialport.portstr, self.serialport.baudrate, self.serialport.bytesize, self.serialport.parity, self.serialport.stopbits, self.serialport.rtscts and ' RTS/CTS' or '', self.serialport.xonxoff and ' Xon/Xoff' or '', ) ) pal = self.btnOpen.palette() pal.setColor(QtGui.QPalette.Button, QtGui.QColor(0,0xff,0x7f)) self.btnOpen.setAutoFillBackground(True) self.btnOpen.setPalette(pal) self.btnOpen.setText('Close') self.btnOpen.update() def closePort(self): if self.serialport.isOpen(): self._stop_reader() self.serialport.close() self.setWindowTitle(appInfo.title) pal = self.btnOpen.style().standardPalette() self.btnOpen.setAutoFillBackground(True) self.btnOpen.setPalette(pal) self.btnOpen.setText('Open') self.btnOpen.update() def _start_reader(self): """Start reader thread""" self.receiver_thread.start() def _stop_reader(self): """Stop reader thread only, wait for clean exit of thread""" self.receiver_thread.join() def onTogglePrtCfgPnl(self): if self.actionPort_Config_Panel.isChecked(): self.dockWidget_PortConfig.show() else: self.dockWidget_PortConfig.hide() def onToggleQckSndPnl(self): if self.actionQuick_Send_Panel.isChecked(): self.dockWidget_QuickSend.show() else: self.dockWidget_QuickSend.hide() def onToggleHexPnl(self): if self.actionSend_Hex_Panel.isChecked(): self.dockWidget_SendHex.show() else: self.dockWidget_SendHex.hide() def onVisiblePrtCfgPnl(self, visible): self.actionPort_Config_Panel.setChecked(visible) def onVisibleQckSndPnl(self, visible): self.actionQuick_Send_Panel.setChecked(visible) def onVisibleHexPnl(self, visible): self.actionSend_Hex_Panel.setChecked(visible) def onLocalEcho(self): self._localEcho = self.actionLocal_Echo.isChecked() def onAlwaysOnTop(self): if self.actionAlways_On_Top.isChecked(): style = self.windowFlags() self.setWindowFlags(style|Qt.WindowStaysOnTopHint) self.show() else: style = self.windowFlags() self.setWindowFlags(style & ~Qt.WindowStaysOnTopHint) self.show() def onOpen(self): if self.serialport.isOpen(): self.closePort() else: self.openPort() def onClear(self): self.txtEdtOutput.clear() def onSaveLog(self): fileName = QFileDialog.getSaveFileName(self, "Save as", os.getcwd(), "Log files (*.log);;Text files (*.txt);;All files (*.*)")[0] if fileName: import codecs f = codecs.open(fileName, 'w', 'utf-8') f.write(self.txtEdtOutput.toPlainText()) f.close() def moveScreenCenter(self): w = self.frameGeometry().width() h = self.frameGeometry().height() desktop = QDesktopWidget() screenW = desktop.screen().width() screenH = desktop.screen().height() self.setGeometry((screenW-w)/2, (screenH-h)/2, w, h) def onEnumPorts(self): for p in enum_ports(): self.cmbPort.addItem(p) # self.cmbPort.update() def onAbout(self): q = QWidget() icon = QtGui.QIcon(":/icon.ico") q.setWindowIcon(icon) QMessageBox.about(q, "About MyTerm", appInfo.aboutme) def onAboutQt(self): QMessageBox.aboutQt(None) def onExit(self): if self.serialport.isOpen(): self.closePort() self.close() def restoreLayout(self): if os.path.isfile(get_config_path("layout.dat")): try: f=open(get_config_path("layout.dat"), 'rb') geometry, state=pickle.load(f) self.restoreGeometry(geometry) self.restoreState(state) except Exception as e: print("Exception on restoreLayout, {}".format(e)) else: try: f=QFile(':/default_layout.dat') f.open(QIODevice.ReadOnly) geometry, state=pickle.loads(f.readAll()) self.restoreGeometry(geometry) self.restoreState(state) except Exception as e: print("Exception on restoreLayout, {}".format(e)) def saveLayout(self): with open(get_config_path("layout.dat"), 'wb') as f: pickle.dump((self.saveGeometry(), self.saveState()), f) def syncMenu(self): self.actionPort_Config_Panel.setChecked(not self.dockWidget_PortConfig.isHidden()) self.actionQuick_Send_Panel.setChecked(not self.dockWidget_QuickSend.isHidden()) self.actionSend_Hex_Panel.setChecked(not self.dockWidget_SendHex.isHidden()) def onViewChanged(self): checked = self._viewGroup.checkedAction() if checked is None: self.actionHEX_UPPERCASE.setChecked(True) self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE) else: if 'Ascii' in checked.text(): self.receiver_thread.setViewMode(VIEWMODE_ASCII) elif 'lowercase' in checked.text(): self.receiver_thread.setViewMode(VIEWMODE_HEX_LOWERCASE) elif 'UPPERCASE' in checked.text(): self.receiver_thread.setViewMode(VIEWMODE_HEX_UPPERCASE)
class AbstractReferenceSelector(ABC, QWidget, metaclass=SelectorMeta): def __init__(self, parent=None): QWidget.__init__(self, parent) self.completer = None self.p_selected_id = 0 self.layout = QHBoxLayout() self.layout.setMargin(0) self.name = QLineEdit() self.name.setText("") self.layout.addWidget(self.name) self.details = QLabel() self.details.setText("") self.details.setVisible(False) self.layout.addWidget(self.details) self.button = QPushButton("...") self.button.setFixedWidth(self.button.fontMetrics().width(" ... ")) self.layout.addWidget(self.button) self.setLayout(self.layout) self.setFocusProxy(self.name) self.button.clicked.connect(self.on_button_clicked) self.table = None self.selector_field = None self.details_field = None self.dialog = None def getId(self): return self.p_selected_id def setId(self, selected_id): if self.p_selected_id == selected_id: return self.p_selected_id = selected_id self.dialog.Model.setFilter(f"{self.table}.id={selected_id}") row_idx = self.dialog.Model.index(0, 0).row() name = self.dialog.Model.record(row_idx).value( self.dialog.Model.fieldIndex(self.selector_field)) self.name.setText(name) if self.details_field: details = self.dialog.Model.record(row_idx).value( self.dialog.Model.fieldIndex(self.details_field)) self.details.setText(details) self.dialog.Model.setFilter("") self.changed.emit() @Signal def changed(self): pass selected_id = Property(int, getId, setId, notify=changed, user=True) def on_button_clicked(self): ref_point = self.mapToGlobal(self.name.geometry().bottomLeft()) self.dialog.setGeometry(ref_point.x(), ref_point.y(), self.dialog.width(), self.dialog.height()) res = self.dialog.exec_() if res: self.selected_id = self.dialog.selected_id @abstractmethod def init_db(self, db): pass def init_db(self, table, selector_field, details_field=None): self.table = table self.selector_field = selector_field if details_field: self.name.setFixedWidth(self.name.fontMetrics().width("X") * 15) self.details_field = details_field self.details.setVisible(True) self.completer = QCompleter(self.dialog.Model) self.completer.setCompletionColumn( self.dialog.Model.fieldIndex(self.selector_field)) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.name.setCompleter(self.completer) self.completer.activated[QModelIndex].connect(self.on_completion) @Slot(QModelIndex) def on_completion(self, index): model = index.model() self.selected_id = model.data(model.index(index.row(), 0), Qt.DisplayRole) def isCustom(self): return True
def __init__(self, mode, parentQWidget = None): QVBoxLayout.__init__(self) self.sig.connect(self.addThreadList) self.mode = mode self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.groupBoxSearch = QGroupBox() self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };") vboxSearch = QVBoxLayout() self.searchTitle = QLabel("Search Messages") vboxSearch.addWidget(self.searchTitle) self.searchHLayout = QHBoxLayout() self.editTextSearch = QTextEdit('') self.editTextSearch.setFixedSize(200,30) self.buttonSearch = QPushButton('Search') self.buttonSearch.setFixedSize(100,30) self.buttonSearch.clicked.connect(self.searchMsg) vboxSearch.addWidget(self.editTextSearch) self.searchHLayout.addWidget(self.buttonSearch) self.searchCursor = QLabel() self.searchHLayout.addWidget(self.searchCursor) vboxSearch.addLayout(self.searchHLayout) self.browseHLayout = QHBoxLayout() self.buttonLookUp = QPushButton('\u21e7') #Arrow up self.buttonLookUp.setFixedWidth(100) self.buttonLookUp.clicked.connect(self.moveToPrev) self.buttonLookDown = QPushButton('\u21e9') #Arrow down self.buttonLookDown.setFixedWidth(100) self.buttonLookDown.clicked.connect(self.moveToNext) self.browseHLayout.addWidget(self.buttonLookUp) self.browseHLayout.addWidget(self.buttonLookDown) vboxSearch.addLayout(self.browseHLayout) self.groupBoxSearch.setLayout(vboxSearch) self.addWidget(self.groupBoxSearch) self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.buttonHiddenLifelines = QPushButton('Show hidden life-lines') self.buttonHiddenLifelines.setFixedWidth(200) self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines) self.addWidget(self.buttonHiddenLifelines) self.buttonHiddenMessages = QPushButton('Show hidden Messages') self.buttonHiddenMessages.setFixedWidth(200) self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages) self.addWidget(self.buttonHiddenMessages) if const.mode_interactive == mode: self.buttonCapture = QPushButton('Capture') self.buttonCapture.setFixedWidth(200) self.buttonCapture.clicked.connect(self.notifyCapture) self.addWidget(self.buttonCapture) self.msgRcv = [] self.msgInfo = QLabel("Message Info.") self.groupBoxMessageInfo = QGroupBox() self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;") vbox = QVBoxLayout() vbox.addWidget(self.msgInfo) self.tableTime = QTableWidget(3,2) self.tableTime.setHorizontalHeaderLabels(['-','time']) self.tableTime.setColumnWidth(0,80) self.tableTime.setColumnWidth(1,150) vwidth = self.tableTime.verticalHeader().length() hwidth = self.tableTime.horizontalHeader().height() fwidth = self.tableTime.frameWidth() * 2 self.tableTime.setFixedHeight(vwidth + hwidth + fwidth) self.tableTime.horizontalHeader().setStretchLastSection(True) self.tableTime.setItem(0,0,QTableWidgetItem('begin')) self.tableTime.setItem(0,1,QTableWidgetItem(' - ')) self.tableTime.setItem(1,0,QTableWidgetItem('end')) self.tableTime.setItem(1,1,QTableWidgetItem(' - ')) self.tableTime.setItem(2,0,QTableWidgetItem('duration')) self.tableTime.setItem(2,1,QTableWidgetItem(' - ')) vbox.addWidget(self.tableTime) self.titleArg = QLabel('Argument List') vbox.addWidget(self.titleArg) max_arg_num = 10 self.tableArgs = QTableWidget(max_arg_num,2) self.tableArgs.setHorizontalHeaderLabels(['type','value']) for idx in range(0,max_arg_num): self.tableArgs.setItem(idx,0,QTableWidgetItem()) self.tableArgs.setItem(idx,1,QTableWidgetItem()) self.tableArgs.horizontalHeader().setStretchLastSection(True) vbox.addWidget(self.tableArgs) self.titleArg = QLabel('Return Value List') vbox.addWidget(self.titleArg) max_ret_num = 4 self.tableRet = QTableWidget(max_ret_num,2) self.tableRet.setHorizontalHeaderLabels(['type','value']) for idx in range(0,max_ret_num): self.tableRet.setItem(idx,0,QTableWidgetItem()) self.tableRet.setItem(idx,1,QTableWidgetItem()) self.tableRet.horizontalHeader().setStretchLastSection(True) vwidth = self.tableRet.verticalHeader().length() hwidth = self.tableRet.horizontalHeader().height() fwidth = self.tableRet.frameWidth() * 2 self.tableRet.setFixedHeight(vwidth + hwidth + fwidth) vbox.addWidget(self.tableRet) self.buttonSrcView = QPushButton('view code') self.buttonSrcView.setFixedWidth(200) self.buttonSrcView.clicked.connect(self.openSourceViewer) self.buttonHide = QPushButton('Hide') self.buttonHide.setFixedWidth(200) self.buttonHide.clicked.connect(self.notifyHide) self.buttonHideAllMsg = QPushButton('Hide All') self.buttonHideAllMsg.setFixedWidth(200) self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected) self.groupBoxMessageInfo.setLayout(vbox) self.checkHideCircular = QCheckBox('Hide Circular Messages') self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked) self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage) self.addWidget(self.checkHideCircular) self.addWidget(self.groupBoxMessageInfo) self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy)
def __init__(self, game: Game, package: Package, parent=None) -> None: super().__init__(parent=parent) self.setMinimumWidth(400) self.game = game self.package = package self.custom_name_text = None self.country = self.game.blue.country_name # Make dialog modal to prevent background windows to close unexpectedly. self.setModal(True) self.setWindowTitle("Create flight") self.setWindowIcon(EVENT_ICONS["strike"]) layout = QVBoxLayout() self.task_selector = QFlightTypeComboBox(self.game.theater, package.target) self.task_selector.setCurrentIndex(0) self.task_selector.currentIndexChanged.connect(self.on_task_changed) layout.addLayout(QLabeledWidget("Task:", self.task_selector)) self.aircraft_selector = QAircraftTypeSelector( self.game.blue.air_wing.available_aircraft_types, self.task_selector.currentData(), ) self.aircraft_selector.setCurrentIndex(0) self.aircraft_selector.currentIndexChanged.connect( self.on_aircraft_changed) layout.addLayout(QLabeledWidget("Aircraft:", self.aircraft_selector)) self.squadron_selector = SquadronSelector( self.game.air_wing_for(player=True), self.task_selector.currentData(), self.aircraft_selector.currentData(), ) self.squadron_selector.setCurrentIndex(0) layout.addLayout(QLabeledWidget("Squadron:", self.squadron_selector)) self.divert = QArrivalAirfieldSelector( [cp for cp in game.theater.controlpoints if cp.captured], self.aircraft_selector.currentData(), "None", ) layout.addLayout(QLabeledWidget("Divert:", self.divert)) self.flight_size_spinner = QFlightSizeSpinner() self.update_max_size(self.squadron_selector.aircraft_available) layout.addLayout(QLabeledWidget("Size:", self.flight_size_spinner)) squadron = self.squadron_selector.currentData() if squadron is None: roster = None else: roster = FlightRoster( squadron, initial_size=self.flight_size_spinner.value()) self.roster_editor = FlightRosterEditor(roster) self.flight_size_spinner.valueChanged.connect( self.roster_editor.resize) self.squadron_selector.currentIndexChanged.connect( self.on_squadron_changed) roster_layout = QHBoxLayout() layout.addLayout(roster_layout) roster_layout.addWidget(QLabel("Assigned pilots:")) roster_layout.addLayout(self.roster_editor) # When an off-map spawn overrides the start type to in-flight, we save # the selected type into this value. If a non-off-map spawn is selected # we restore the previous choice. self.restore_start_type: Optional[str] = None self.start_type = QComboBox() for start_type in StartType: self.start_type.addItem(start_type.value, start_type) self.start_type.setCurrentText( self.game.settings.default_start_type.value) layout.addLayout( QLabeledWidget( "Start type:", self.start_type, tooltip="Selects the start type for this flight.", )) layout.addWidget( QLabel( "Any option other than Cold will make this flight " + "non-targetable<br />by OCA/Aircraft missions. This will affect " + "game balance.")) self.custom_name = QLineEdit() self.custom_name.textChanged.connect(self.set_custom_name_text) layout.addLayout( QLabeledWidget("Custom Flight Name (Optional)", self.custom_name)) layout.addStretch() self.create_button = QPushButton("Create") self.create_button.clicked.connect(self.create_flight) layout.addWidget(self.create_button, alignment=Qt.AlignRight) self.setLayout(layout)
def __init__(self): super(Window, self).__init__() self.label = QLabel('Enter Your Age') self.lineEdit = QLineEdit() self.label1 = QLabel('Year of Birth') self.combo1 = QComboBox() self.okButton = QPushButton('OK') self.moreButton = QPushButton('More') self.moreButton.setCheckable(True) self.groupBox = QGroupBox() self.groupBox.setTitle('Details') self.nameLabel = QLabel('Name') self.nameLineEdit = QLineEdit() self.label3 = QLabel('Year of Birth') self.combo2 = QComboBox() self.topLayout1 = QHBoxLayout() self.topLayout1.addWidget(self.label) self.topLayout1.addWidget(self.lineEdit) self.topLayout2 = QHBoxLayout() self.topLayout2.addWidget(self.label1) self.topLayout2.addWidget(self.combo1) for x in range(ord('A'), ord('F')): self.combo1.addItem(str(chr(x))) self.leftLayout = QVBoxLayout() self.leftLayout.addLayout(self.topLayout1) self.leftLayout.addLayout(self.topLayout2) self.leftLayout.addStretch() self.rightLayout = QVBoxLayout() self.rightLayout.addWidget(self.okButton) self.rightLayout.addWidget(self.moreButton) self.bottomLayout1 = QHBoxLayout() self.bottomLayout1.addWidget(self.nameLabel) self.bottomLayout1.addWidget(self.nameLineEdit) self.bottomLayout2 = QHBoxLayout() self.bottomLayout2.addWidget(self.label3) self.bottomLayout2.addWidget(self.combo2) self.combo2.addItem("None") self.bottomLayout = QVBoxLayout() self.bottomLayout.addLayout(self.bottomLayout1) self.bottomLayout.addLayout(self.bottomLayout2) self.groupBox.setLayout(self.bottomLayout) self.groupBox.setVisible(False) self.moreButton.toggled.connect(lambda v: self.groupBox.setVisible(v)) self.combo2.setMinimumSize(self.combo2.sizeHint()) self.mainLayout = QGridLayout() self.mainLayout.addLayout(self.leftLayout, 0, 0) self.mainLayout.addLayout(self.rightLayout, 0, 1) # self.mainLayout.addLayout(self.bottomLayout, 1, 0) self.mainLayout.addWidget(self.groupBox) self.mainLayout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(self.mainLayout)
class EditWindow(QDialog): updateIdSignal = Signal(int,int) cancelCreatingRectSignal = Signal() def __init__(self): QDialog.__init__(self) self.setWindowTitle("editWindow") self.itemSelected=False self.lastChoosenIdExist=False self.rectCreated=False self.errorMessage=QErrorMessage() self.label = QLabel(" ") self.cancelButton=QPushButton("Cancel") self.cancelButton.setShortcut("ESC") self.okButton=QPushButton("OK") self.listWidget=QListWidget() self.layout = QGridLayout() self.layout.addWidget(self.label,0,0) self.layout.addWidget(self.cancelButton,1,0) self.layout.addWidget(self.okButton,1,1) self.layout.addWidget(self.listWidget,2,0, 2,2) self.setLayout(self.layout) self.setTabOrder(self.okButton, self.cancelButton) self.listWidget.currentRowChanged.connect(self.listWidgetRowChaged) self.listWidget.itemDoubleClicked.connect(self.listWidgetDoubleClicked) self.okButton.clicked.connect(self.okButtonClicked) self.cancelButton.clicked.connect(self.cancelButtonClicked) @Slot() def setLastChoosenId(self,lastChoosenId): self.lastChoosenId=lastChoosenId self.lastChoosenIdExist=True self.listWidget.setCurrentRow(self.lastChoosenId) @Slot() def listWidgetRowChaged(self): if (self.listItems[self.listWidget.currentRow()][-1]=="\n"): self.label.setText(self.listItems[self.listWidget.currentRow()][:-1]) else: self.label.setText(self.listItems[self.listWidget.currentRow()]) self.itemSelected=True @Slot() def listWidgetDoubleClicked(self,item): self.itemSelected=True self.updateIdSignal.emit(self.listWidget.row(item),self.rectCreated) self.rectCreated=False self.close() @Slot() def okButtonClicked(self,clicked): if (self.itemSelected==True): self.updateIdSignal.emit(self.listWidget.currentRow(),self.rectCreated) self.rectCreated=False self.close() else: self.errorMessage.showMessage("Choose a class") @Slot() def cancelButtonClicked(self,clicked): self.cancelCreatingRectSignal.emit() self.close() def readClassesTxt(self,dirName): self.dirName=dirName list=self.dirName.split("/") list.append("classes.txt") path="/".join(list) if (os.path.isfile(path)): f=open(path, "r") content=f.readlines() f.close() self.listItems=content if (self.listItems): for className in self.listItems: item=QtWidgets.QListWidgetItem() if (className[-1]=="\n"): item.setText(className[:-1]) #removed "/n" else: item.setText(className) #removed "/n" self.listWidget.addItem(item) else: self.errorMessage.showMessage("classes.txt does not exist") self.close()
def init_ui(self): self.vbox = QVBoxLayout() self.hbox = QHBoxLayout() # Set layout self.setLayout(self.vbox) # OBS Settings group_frame = QGroupBox("OBS") group_frame.setLayout(QVBoxLayout()) label = QLabel("Hostname/IP") group_frame.layout().addWidget(label) self.obs_host = QLineEdit() group_frame.layout().addWidget(self.obs_host) label = QLabel("Port") group_frame.layout().addWidget(label) self.obs_port = QLineEdit() self.obs_port.setValidator(QIntValidator(1024, 65535)) group_frame.layout().addWidget(self.obs_port) label = QLabel("Password") group_frame.layout().addWidget(label) self.auth_password = QLineEdit() group_frame.layout().addWidget(self.auth_password) self.hbox.addWidget(group_frame) # TouchOSC Settings group_frame = QGroupBox("TouchOSC") group_frame.setLayout(QVBoxLayout()) label = QLabel("Hostname/IP") group_frame.layout().addWidget(label) self.touchosc_host = QLineEdit() group_frame.layout().addWidget(self.touchosc_host) label = QLabel("Port") group_frame.layout().addWidget(label) self.touchosc_port = QLineEdit() self.touchosc_port.setValidator(QIntValidator(1024, 65535)) group_frame.layout().addWidget(self.touchosc_port) self.hbox.addWidget(group_frame) # OSC Settings group_frame = QGroupBox("OSC") group_frame.setLayout(QVBoxLayout()) label = QLabel("Port") group_frame.layout().addWidget(label) self.osc_port = QLineEdit() self.osc_port.setValidator(QIntValidator(1024, 65535)) group_frame.layout().addWidget(self.osc_port) self.hbox.addWidget(group_frame) # Add all to layout self.vbox.addLayout(self.hbox) # Start button icon = QIcon(resource_path('icons/play.png')) self.start_button = QPushButton(icon, "Start") self.start_button.pressed.connect(self.start_pressed) self.vbox.addWidget(self.start_button) self.setWindowTitle('OBS TouchOSC')
class MainWindow(QWidget): def __init__(self, appctx): super().__init__() self.appctx = appctx self.obs = None self.tick_timer = QTimer() self.tick_timer.setInterval(200) self.tick_timer.timeout.connect(self.tick) self.tick_timer.start() company = 'dunkelstern' if sys.platform != 'darwin' else 'de.dunkelstern' self.settings = QSettings(company, 'OBSTouchOSC') self.init_ui() self.load_settings() def load_settings(self): self.obs_host.setText(self.settings.value('obs/host', '127.0.0.1')) self.obs_port.setText(self.settings.value('obs/port', '4444')) self.auth_password.setText(self.settings.value('obs/password', '')) self.touchosc_host.setText(self.settings.value('touchosc/host', '')) self.touchosc_port.setText(self.settings.value('touchosc/port', '9000')) self.osc_port.setText(self.settings.value('osc/port', '8000')) def save_settings(self): self.settings.setValue('obs/host', self.obs_host.text()) self.settings.setValue('obs/port', self.obs_port.text()) self.settings.setValue('obs/password', self.auth_password.text()) self.settings.setValue('touchosc/host', self.touchosc_host.text()) self.settings.setValue('touchosc/port', self.touchosc_port.text()) self.settings.setValue('osc/port', self.osc_port.text()) self.settings.sync() def init_ui(self): self.vbox = QVBoxLayout() self.hbox = QHBoxLayout() # Set layout self.setLayout(self.vbox) # OBS Settings group_frame = QGroupBox("OBS") group_frame.setLayout(QVBoxLayout()) label = QLabel("Hostname/IP") group_frame.layout().addWidget(label) self.obs_host = QLineEdit() group_frame.layout().addWidget(self.obs_host) label = QLabel("Port") group_frame.layout().addWidget(label) self.obs_port = QLineEdit() self.obs_port.setValidator(QIntValidator(1024, 65535)) group_frame.layout().addWidget(self.obs_port) label = QLabel("Password") group_frame.layout().addWidget(label) self.auth_password = QLineEdit() group_frame.layout().addWidget(self.auth_password) self.hbox.addWidget(group_frame) # TouchOSC Settings group_frame = QGroupBox("TouchOSC") group_frame.setLayout(QVBoxLayout()) label = QLabel("Hostname/IP") group_frame.layout().addWidget(label) self.touchosc_host = QLineEdit() group_frame.layout().addWidget(self.touchosc_host) label = QLabel("Port") group_frame.layout().addWidget(label) self.touchosc_port = QLineEdit() self.touchosc_port.setValidator(QIntValidator(1024, 65535)) group_frame.layout().addWidget(self.touchosc_port) self.hbox.addWidget(group_frame) # OSC Settings group_frame = QGroupBox("OSC") group_frame.setLayout(QVBoxLayout()) label = QLabel("Port") group_frame.layout().addWidget(label) self.osc_port = QLineEdit() self.osc_port.setValidator(QIntValidator(1024, 65535)) group_frame.layout().addWidget(self.osc_port) self.hbox.addWidget(group_frame) # Add all to layout self.vbox.addLayout(self.hbox) # Start button icon = QIcon(resource_path('icons/play.png')) self.start_button = QPushButton(icon, "Start") self.start_button.pressed.connect(self.start_pressed) self.vbox.addWidget(self.start_button) self.setWindowTitle('OBS TouchOSC') def enable_controls(self, enabled): for i in range(0, self.hbox.count()): control = self.hbox.itemAt(i).widget() control.setEnabled(enabled) def stop_pressed(self): # stop server self.obs.stop() self.obs = None # enable all controls self.enable_controls(True) # switch to play button icon = QIcon(resource_path('icons/play.png')) self.start_button.setIcon(icon) self.start_button.setText('Start') self.start_button.pressed.disconnect() self.start_button.pressed.connect(self.start_pressed) def start_pressed(self): # validate all inputs for not_empty in [self.obs_host, self.touchosc_host]: if not_empty.text() == '': not_empty.setFocus() return for valid in [self.obs_port, self.touchosc_port, self.osc_port]: if not valid.hasAcceptableInput(): valid.setFocus() return # Save settings self.save_settings() # disable all controls self.enable_controls(False) # switch to stop button icon = QIcon(resource_path('icons/stop.png')) self.start_button.setIcon(icon) self.start_button.setText('Stop') self.start_button.pressed.disconnect() self.start_button.pressed.connect(self.stop_pressed) # Start server self.obs = OBSRemote(int(self.osc_port.text()), self.touchosc_host.text(), int(self.touchosc_port.text()), self.obs_host.text(), int(self.obs_port.text()), password=self.auth_password.text()) self.obs.start() def tick(self): if self.obs: self.obs.tick()
def __init__(self, parent): super().__init__(parent) self.setTitle("Troubleshooting") msg = "Select your problem from the list." self._button1 = QRadioButton("Installing SpineOpt fails with one of the following messages (or similar):") msg1a = MonoSpaceFontTextBrowser(self) msg1b = MonoSpaceFontTextBrowser(self) msg1a.append( """ \u22ee<br> Updating git-repo `https://github.com/Spine-project/SpineJuliaRegistry`<br> Resolving package versions...<br> ERROR: expected package `UUIDs [cf7118a7]` to be registered<br> \u22ee """ ) msg1b.append( """ \u22ee<br> Updating git-repo `https://github.com/Spine-project/SpineJuliaRegistry`<br> Resolving package versions...<br> ERROR: cannot find name corresponding to UUID f269a46b-ccf7-5d73-abea-4c690281aa53 in a registry<br> \u22ee """ ) self._button2 = QRadioButton("On Windows 7, installing SpineOpt fails with the following message (or similar):") msg2 = MonoSpaceFontTextBrowser(self) msg2.append( """ \u22ee<br> Downloading artifact: OpenBLAS32<br> Exception setting "SecurityProtocol": "Cannot convert null to type "System.Net.<br> SecurityProtocolType" due to invalid enumeration values. Specify one of the fol<br> lowing enumeration values and try again. The possible enumeration values are "S<br> sl3, Tls"."<br> At line:1 char:35<br> + [System.Net.ServicePointManager]:: <<<< SecurityProtocol =<br> + CategoryInfo : InvalidOperation: (:) [], RuntimeException<br> + FullyQualifiedErrorId : PropertyAssignmentException<br> \u22ee """ ) layout = QVBoxLayout(self) layout.addWidget(WrapLabel(msg)) layout.addStretch() layout.addWidget(self._button1) layout.addWidget(msg1a) layout.addWidget(msg1b) layout.addStretch() layout.addWidget(self._button2) layout.addWidget(msg2) layout.addStretch() button_view_log = QPushButton("View process log") widget_view_log = QWidget() layout_view_log = QHBoxLayout(widget_view_log) layout_view_log.addStretch() layout_view_log.addWidget(button_view_log) layout.addWidget(widget_view_log) layout.addStretch() self.registerField("problem1", self._button1) self.registerField("problem2", self._button2) self._button1.toggled.connect(self.completeChanged) self._button2.toggled.connect(self.completeChanged) button_view_log.clicked.connect(self._show_log)
def _init_widgets(self): # status status_box = QGroupBox(self) status_box.setTitle("Status") self._status_label = QLabel(self) self._status_label.setText(self.workspace.instance.sync.status_string) status_layout = QVBoxLayout() status_layout.addWidget(self._status_label) status_box.setLayout(status_layout) # table self._team_table = QTeamTable(self.workspace.instance) team_box = QGroupBox(self) team_box.setTitle("Team") # operations # pull function button pullfunc_btn = QPushButton(self) pullfunc_btn.setText("Pull func") pullfunc_btn.setToolTip("Pull current function from the selected user") pullfunc_btn.clicked.connect(self._on_pullfunc_clicked) # push function button pushfunc_btn = QPushButton() pushfunc_btn.setText('Push func') pushfunc_btn.setToolTip("Push current function to the repo") pushfunc_btn.clicked.connect(self._on_pushfunc_clicked) # pull patches button pullpatches_btn = QPushButton(self) pullpatches_btn.setText("Pull patches") pullpatches_btn.setToolTip("Pull all patches from the selected user") pullpatches_btn.clicked.connect(self._on_pullpatches_clicked) actions_box = QGroupBox(self) actions_box.setTitle("Actions") actions_layout = QHBoxLayout() actions_layout.addWidget(pullfunc_btn) actions_layout.addWidget(pushfunc_btn) actions_layout.addWidget(pullpatches_btn) actions_box.setLayout(actions_layout) team_layout = QVBoxLayout() team_layout.addWidget(self._team_table) team_layout.addWidget(actions_box) team_box.setLayout(team_layout) main_layout = QVBoxLayout() main_layout.addWidget(status_box) main_layout.addWidget(team_box) self.setLayout(main_layout)
class ComparisonWidget(ToolWidget): def __init__(self, filename, image, parent=None): super(ComparisonWidget, self).__init__(parent) load_button = QPushButton(self.tr('Load reference image...')) self.comp_label = QLabel(self.tr('Comparison:')) self.normal_radio = QRadioButton(self.tr('Normal')) self.normal_radio.setToolTip(self.tr('Show reference (raw pixels)')) self.normal_radio.setChecked(True) self.difference_radio = QRadioButton(self.tr('Difference')) self.difference_radio.setToolTip( self.tr('Show evidence/reference difference')) self.ssim_radio = QRadioButton(self.tr('SSIM Map')) self.ssim_radio.setToolTip(self.tr('Structure similarity quality map')) self.butter_radio = QRadioButton(self.tr('Butteraugli')) self.butter_radio.setToolTip( self.tr('Butteraugli spatial changes heatmap')) self.gray_check = QCheckBox(self.tr('Grayscale')) self.gray_check.setToolTip(self.tr('Show desaturated output')) self.equalize_check = QCheckBox(self.tr('Equalized')) self.equalize_check.setToolTip(self.tr('Apply histogram equalization')) self.last_radio = self.normal_radio self.metric_button = QPushButton(self.tr('Compute metrics')) self.metric_button.setToolTip( self.tr('Image quality assessment metrics')) self.evidence = image self.reference = self.difference = self.ssim_map = self.butter_map = None basename = os.path.basename(filename) self.evidence_viewer = ImageViewer( self.evidence, None, self.tr('Evidence: {}'.format(basename))) self.reference_viewer = ImageViewer(np.full_like(self.evidence, 127), None, self.tr('Reference')) self.table_widget = QTableWidget(21, 3) self.table_widget.setHorizontalHeaderLabels( [self.tr('Metric'), self.tr('Value'), self.tr('Better')]) self.table_widget.setItem(0, 0, QTableWidgetItem(self.tr('RMSE'))) self.table_widget.setItem( 0, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(0, 0).setToolTip( self. tr('Root Mean Square Error (RMSE) is commonly used to compare \n' 'the difference between the reference and evidence images \n' 'by directly computing the variation in pixel values. \n' 'The combined image is close to the reference image when \n' 'RMSE value is zero. RMSE is a good indicator of the spectral \n' 'quality of the reference image.')) self.table_widget.setItem(1, 0, QTableWidgetItem(self.tr('SAM'))) self.table_widget.setItem( 1, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(1, 0).setToolTip( self. tr('It computes the spectral angle between the pixel, vector of the \n' 'evidence image and reference image. It is worked out in either \n' 'degrees or radians. It is performed on a pixel-by-pixel base. \n' 'A SAM equal to zero denotes the absence of spectral distortion.' )) self.table_widget.setItem(2, 0, QTableWidgetItem(self.tr('ERGAS'))) self.table_widget.setItem( 2, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(2, 0).setToolTip( self. tr('It is used to compute the quality of reference image in terms \n' 'of normalized average error of each band of the reference image. \n' 'Increase in the value of ERGAS indicates distortion in the \n' 'reference image, lower value of ERGAS indicates that it is \n' 'similar to the reference image.')) self.table_widget.setItem(3, 0, QTableWidgetItem(self.tr('MB'))) self.table_widget.setItem( 3, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(3, 0).setToolTip( self. tr('Mean Bias is the difference between the mean of the evidence \n' 'image and reference image. The ideal value is zero and indicates \n' 'that the evidence and reference images are similar. Mean value \n' 'refers to the grey level of pixels in an image.')) self.table_widget.setItem(4, 0, QTableWidgetItem(self.tr('PFE'))) self.table_widget.setItem( 4, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(4, 0).setToolTip( self. tr('It computes the norm of the difference between the corresponding \n' 'pixels of the reference and fused image to the norm of the reference \n' 'image. When the calculated value is zero, it indicates that both the \n' 'reference and fused images are similar and value will be increased \n' 'when the merged image is not similar to the reference image.')) self.table_widget.setItem(5, 0, QTableWidgetItem(self.tr('PSNR'))) self.table_widget.setItem( 5, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(5, 0).setToolTip( self. tr('It is widely used metric it is computed by the number of gray levels \n' 'in the image divided by the corresponding pixels in the evidence and \n' 'the reference images. When the value is high, both images are similar.' )) self.table_widget.setItem(6, 0, QTableWidgetItem(self.tr('PSNR-B'))) self.table_widget.setItem( 6, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(6, 0).setToolTip( self.tr('PSNR with Blocking Effect Factor.')) self.table_widget.setItem(7, 0, QTableWidgetItem(self.tr('SSIM'))) self.table_widget.setItem( 7, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(7, 0).setToolTip( self. tr('SSIM is used to compare the local patterns of pixel intensities between \n' ' the reference and fused images. The range varies between -1 to 1. \n' 'The value 1 indicates the reference and fused images are similar.' )) self.table_widget.setItem(8, 0, QTableWidgetItem(self.tr('MS-SSIM'))) self.table_widget.setItem( 8, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(8, 0).setToolTip( self.tr('Multiscale version of SSIM.')) self.table_widget.setItem(9, 0, QTableWidgetItem(self.tr('RASE'))) self.table_widget.setItem( 9, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(9, 0).setToolTip( self.tr('Relative average spectral error')) self.table_widget.setItem(10, 0, QTableWidgetItem(self.tr('SCC'))) self.table_widget.setItem( 10, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(10, 0).setToolTip( self.tr('Spatial Correlation Coefficient')) self.table_widget.setItem(11, 0, QTableWidgetItem(self.tr('UQI'))) self.table_widget.setItem( 11, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(11, 0).setToolTip( self.tr('Universal Image Quality Index')) self.table_widget.setItem(12, 0, QTableWidgetItem(self.tr('VIF-P'))) self.table_widget.setItem( 12, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(12, 0).setToolTip( self.tr('Pixel-based Visual Information Fidelity')) self.table_widget.setItem(13, 0, QTableWidgetItem(self.tr('SSIMulacra'))) self.table_widget.setItem( 13, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(13, 0).setToolTip( self.tr('Structural SIMilarity Unveiling Local ' 'And Compression Related Artifacts')) self.table_widget.setItem(14, 0, QTableWidgetItem(self.tr('Butteraugli'))) self.table_widget.setItem( 14, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(14, 0).setToolTip( self.tr('Estimate psychovisual error')) self.table_widget.setItem(15, 0, QTableWidgetItem(self.tr('Correlation'))) self.table_widget.setItem( 15, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(1)')) self.table_widget.item(15, 0).setToolTip(self.tr('Histogram correlation')) self.table_widget.setItem(16, 0, QTableWidgetItem(self.tr('Chi-Square'))) self.table_widget.setItem( 16, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(16, 0).setToolTip(self.tr('Histogram Chi-Square')) self.table_widget.setItem(17, 0, QTableWidgetItem(self.tr('Chi-Square 2'))) self.table_widget.setItem( 17, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(17, 0).setToolTip(self.tr('Alternative Chi-Square')) self.table_widget.setItem(18, 0, QTableWidgetItem(self.tr('Intersection'))) self.table_widget.setItem( 18, 2, QTableWidgetItem(QIcon('icons/high.svg'), '(+' + u'\u221e' + ')')) self.table_widget.item(18, 0).setToolTip(self.tr('Histogram intersection')) self.table_widget.setItem(19, 0, QTableWidgetItem(self.tr('Hellinger'))) self.table_widget.setItem( 19, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(19, 0).setToolTip( self.tr('Histogram Hellinger distance')) self.table_widget.setItem(20, 0, QTableWidgetItem(self.tr('Divergence'))) self.table_widget.setItem( 20, 2, QTableWidgetItem(QIcon('icons/low.svg'), '(0)')) self.table_widget.item(20, 0).setToolTip( self.tr('Kullback-Leibler divergence')) for i in range(self.table_widget.rowCount()): modify_font(self.table_widget.item(i, 0), bold=True) self.table_widget.setSelectionMode(QAbstractItemView.SingleSelection) self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers) self.table_widget.resizeColumnsToContents() self.table_widget.setMaximumWidth(250) self.table_widget.setAlternatingRowColors(True) self.stopped = False self.comp_label.setEnabled(False) self.normal_radio.setEnabled(False) self.difference_radio.setEnabled(False) self.ssim_radio.setEnabled(False) self.butter_radio.setEnabled(False) self.gray_check.setEnabled(False) self.equalize_check.setEnabled(False) self.metric_button.setEnabled(False) self.table_widget.setEnabled(False) load_button.clicked.connect(self.load) self.normal_radio.clicked.connect(self.change) self.difference_radio.clicked.connect(self.change) self.butter_radio.clicked.connect(self.change) self.gray_check.stateChanged.connect(self.change) self.equalize_check.stateChanged.connect(self.change) self.ssim_radio.clicked.connect(self.change) self.evidence_viewer.viewChanged.connect( self.reference_viewer.changeView) self.reference_viewer.viewChanged.connect( self.evidence_viewer.changeView) self.metric_button.clicked.connect(self.metrics) top_layout = QHBoxLayout() top_layout.addWidget(load_button) top_layout.addStretch() top_layout.addWidget(self.comp_label) top_layout.addWidget(self.normal_radio) top_layout.addWidget(self.difference_radio) top_layout.addWidget(self.ssim_radio) top_layout.addWidget(self.butter_radio) top_layout.addWidget(self.gray_check) top_layout.addWidget(self.equalize_check) metric_layout = QVBoxLayout() index_label = QLabel(self.tr('Image Quality Assessment')) index_label.setAlignment(Qt.AlignCenter) modify_font(index_label, bold=True) metric_layout.addWidget(index_label) metric_layout.addWidget(self.table_widget) metric_layout.addWidget(self.metric_button) center_layout = QHBoxLayout() center_layout.addWidget(self.evidence_viewer) center_layout.addWidget(self.reference_viewer) center_layout.addLayout(metric_layout) main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addLayout(center_layout) self.setLayout(main_layout) def load(self): filename, basename, reference = load_image(self) if filename is None: return if reference.shape != self.evidence.shape: QMessageBox.critical( self, self.tr('Error'), self.tr('Evidence and reference must have the same size!')) return self.reference = reference self.reference_viewer.set_title( self.tr('Reference: {}'.format(basename))) self.difference = norm_mat(cv.absdiff(self.evidence, self.reference)) self.comp_label.setEnabled(True) self.normal_radio.setEnabled(True) self.difference_radio.setEnabled(True) self.ssim_radio.setEnabled(False) self.butter_radio.setEnabled(False) self.gray_check.setEnabled(True) self.equalize_check.setEnabled(True) self.metric_button.setEnabled(True) for i in range(self.table_widget.rowCount()): self.table_widget.setItem(i, 1, QTableWidgetItem()) self.normal_radio.setChecked(True) self.table_widget.setEnabled(False) self.change() def change(self): if self.normal_radio.isChecked(): result = self.reference self.gray_check.setEnabled(False) self.equalize_check.setEnabled(False) self.last_radio = self.normal_radio elif self.difference_radio.isChecked(): result = self.difference self.gray_check.setEnabled(True) self.equalize_check.setEnabled(True) self.last_radio = self.difference_radio elif self.ssim_radio.isChecked(): result = self.ssim_map self.gray_check.setEnabled(False) self.equalize_check.setEnabled(True) self.last_radio = self.ssim_radio elif self.butter_radio.isChecked(): result = self.butter_map self.gray_check.setEnabled(True) self.equalize_check.setEnabled(False) self.last_radio = self.butter_radio else: self.last_radio.setChecked(True) return if self.equalize_check.isChecked(): result = equalize_img(result) if self.gray_check.isChecked(): result = desaturate(result) self.reference_viewer.update_original(result) def metrics(self): progress = QProgressDialog(self.tr('Computing metrics...'), self.tr('Cancel'), 1, self.table_widget.rowCount(), self) progress.canceled.connect(self.cancel) progress.setWindowModality(Qt.WindowModal) img1 = cv.cvtColor(self.evidence, cv.COLOR_BGR2GRAY) img2 = cv.cvtColor(self.reference, cv.COLOR_BGR2GRAY) x = img1.astype(np.float64) y = img2.astype(np.float64) rmse = self.rmse(x, y) progress.setValue(1) if self.stopped: return sam = sewar.sam(img1, img2) progress.setValue(2) if self.stopped: return ergas = sewar.ergas(img1, img2) progress.setValue(3) if self.stopped: return mb = self.mb(x, y) progress.setValue(4) if self.stopped: return pfe = self.pfe(x, y) progress.setValue(5) if self.stopped: return psnr = self.psnr(x, y) progress.setValue(6) if self.stopped: return try: psnrb = sewar.psnrb(img1, img2) except NameError: # FIXME: C'\`e un bug in psnrb (https://github.com/andrewekhalel/sewar/issues/17) psnrb = 0 progress.setValue(7) if self.stopped: return ssim, self.ssim_map = self.ssim(x, y) progress.setValue(8) if self.stopped: return mssim = sewar.msssim(img1, img2).real progress.setValue(9) if self.stopped: return rase = sewar.rase(img1, img2) progress.setValue(10) if self.stopped: return scc = sewar.scc(img1, img2) progress.setValue(11) if self.stopped: return uqi = sewar.uqi(img1, img2) progress.setValue(12) if self.stopped: return vifp = sewar.vifp(img1, img2) progress.setValue(13) if self.stopped: return ssimul = self.ssimul(img1, img2) progress.setValue(14) if self.stopped: return butter, self.butter_map = self.butter(img1, img2) progress.setValue(15) if self.stopped: return sizes = [256, 256, 256] ranges = [0, 256] * 3 channels = [0, 1, 2] hist1 = cv.calcHist([self.evidence], channels, None, sizes, ranges) hist2 = cv.calcHist([self.reference], channels, None, sizes, ranges) correlation = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL) progress.setValue(16) if self.stopped: return chi_square = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR) progress.setValue(17) if self.stopped: return chi_square2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR_ALT) progress.setValue(18) if self.stopped: return intersection = cv.compareHist(hist1, hist2, cv.HISTCMP_INTERSECT) progress.setValue(19) if self.stopped: return hellinger = cv.compareHist(hist1, hist2, cv.HISTCMP_HELLINGER) progress.setValue(20) if self.stopped: return divergence = cv.compareHist(hist1, hist2, cv.HISTCMP_KL_DIV) progress.setValue(21) self.table_widget.setItem(0, 1, QTableWidgetItem('{:.2f}'.format(rmse))) self.table_widget.setItem(1, 1, QTableWidgetItem('{:.4f}'.format(sam))) self.table_widget.setItem(2, 1, QTableWidgetItem('{:.2f}'.format(ergas))) self.table_widget.setItem(3, 1, QTableWidgetItem('{:.4f}'.format(mb))) self.table_widget.setItem(4, 1, QTableWidgetItem('{:.2f}'.format(pfe))) if psnr > 0: self.table_widget.setItem( 5, 1, QTableWidgetItem('{:.2f} dB'.format(psnr))) else: self.table_widget.setItem( 5, 1, QTableWidgetItem('+' + u'\u221e' + ' dB')) self.table_widget.setItem(6, 1, QTableWidgetItem('{:.2f}'.format(psnrb))) self.table_widget.setItem(7, 1, QTableWidgetItem('{:.4f}'.format(ssim))) self.table_widget.setItem(8, 1, QTableWidgetItem('{:.4f}'.format(mssim))) self.table_widget.setItem(9, 1, QTableWidgetItem('{:.2f}'.format(rase))) self.table_widget.setItem(10, 1, QTableWidgetItem('{:.4f}'.format(scc))) self.table_widget.setItem(11, 1, QTableWidgetItem('{:.4f}'.format(uqi))) self.table_widget.setItem(12, 1, QTableWidgetItem('{:.4f}'.format(vifp))) self.table_widget.setItem(13, 1, QTableWidgetItem('{:.4f}'.format(ssimul))) self.table_widget.setItem(14, 1, QTableWidgetItem('{:.2f}'.format(butter))) self.table_widget.setItem( 15, 1, QTableWidgetItem('{:.2f}'.format(correlation))) self.table_widget.setItem( 16, 1, QTableWidgetItem('{:.2f}'.format(chi_square))) self.table_widget.setItem( 17, 1, QTableWidgetItem('{:.2f}'.format(chi_square2))) self.table_widget.setItem( 18, 1, QTableWidgetItem('{:.2f}'.format(intersection))) self.table_widget.setItem(19, 1, QTableWidgetItem('{:.2f}'.format(hellinger))) self.table_widget.setItem( 20, 1, QTableWidgetItem('{:.2f}'.format(divergence))) self.table_widget.resizeColumnsToContents() self.table_widget.setEnabled(True) self.metric_button.setEnabled(False) self.ssim_radio.setEnabled(True) self.butter_radio.setEnabled(True) def cancel(self): self.stopped = True @staticmethod def rmse(x, y): return np.sqrt(np.mean(np.square(x - y))) @staticmethod def mb(x, y): mx = np.mean(x) my = np.mean(y) return (mx - my) / mx @staticmethod def pfe(x, y): return np.linalg.norm(x - y) / np.linalg.norm(x) * 100 @staticmethod def ssim(x, y): c1 = 6.5025 c2 = 58.5225 k = (11, 11) s = 1.5 x2 = x**2 y2 = y**2 xy = x * y mu_x = cv.GaussianBlur(x, k, s) mu_y = cv.GaussianBlur(y, k, s) mu_x2 = mu_x**2 mu_y2 = mu_y**2 mu_xy = mu_x * mu_y s_x2 = cv.GaussianBlur(x2, k, s) - mu_x2 s_y2 = cv.GaussianBlur(y2, k, s) - mu_y2 s_xy = cv.GaussianBlur(xy, k, s) - mu_xy t1 = 2 * mu_xy + c1 t2 = 2 * s_xy + c2 t3 = t1 * t2 t1 = mu_x2 + mu_y2 + c1 t2 = s_x2 + s_y2 + c2 t1 *= t2 ssim_map = cv.divide(t3, t1) ssim = cv.mean(ssim_map)[0] return ssim, 255 - norm_mat(ssim_map, to_bgr=True) @staticmethod def corr(x, y): return np.corrcoef(x, y)[0, 1] @staticmethod def psnr(x, y): k = np.mean(np.square(x - y)) if k == 0: return -1 return 20 * math.log10((255**2) / k) @staticmethod def butter(x, y): try: exe = butter_exe() if exe is None: raise FileNotFoundError temp_dir = QTemporaryDir() if temp_dir.isValid(): filename1 = os.path.join(temp_dir.path(), 'img1.png') cv.imwrite(filename1, x) filename2 = os.path.join(temp_dir.path(), 'img2.png') cv.imwrite(filename2, y) filename3 = os.path.join(temp_dir.path(), 'map.ppm') p = run([exe, filename1, filename2, filename3], stdout=PIPE) value = float(p.stdout) heatmap = cv.imread(filename3, cv.IMREAD_COLOR) return value, heatmap except FileNotFoundError: return -1, cv.cvtColor(np.full_like(x, 127), cv.COLOR_GRAY2BGR) @staticmethod def ssimul(x, y): try: exe = ssimul_exe() if exe is None: raise FileNotFoundError temp_dir = QTemporaryDir() if temp_dir.isValid(): filename1 = os.path.join(temp_dir.path(), 'img1.png') cv.imwrite(filename1, x) filename2 = os.path.join(temp_dir.path(), 'img2.png') cv.imwrite(filename2, y) p = run([exe, filename1, filename2], stdout=PIPE) value = float(p.stdout) return value except FileNotFoundError: return -1
class DatePicker(QWidget): selectionChanged = Signal() def __init__(self, parent=None): super(DatePicker, self).__init__(parent) self.button = QPushButton(self) icon = QIcon("logo.svg") self.button.setIcon(icon) self.setFixedSize(32, 32) self.button.setFixedSize(32, 32) self.button.setIconSize(QSize(22, 22)) self.__margin__ = 5 self.dialog = QDialog() self.dialog.setWindowFlags(Qt.Window | Qt.FramelessWindowHint | Qt.Popup) self.dialog.setFixedSize(480, 240) self.dialog.setLayout(QHBoxLayout()) self.calender = QCalendarWidget(self) self.dialog.layout().addWidget(self.calender) self.dialog.layout().setContentsMargins(0, 0, 0, 0) self.dialog.layout().setSpacing(0) self.button.clicked.connect(self.showCalender) self.calender.selectionChanged.connect(self.__onSelectionChanged__) def show(self): self.showCalender() def close(self): self.dialog.close() @Slot() def showCalender(self): print('in show') p = self.mapToGlobal(QPoint(0, self.height() + self.__margin__)) self.dialog.setGeometry(p.x(), p.y(), 0, 0) self.dialog.show() def setIcon(self, icon): if type(icon) is QIcon: self.button.setIcon(icon) elif type(icon) is str: self.button.setIcon(QIcon(icon)) else: raise Exception( 'Wrong argument type, icon should be either PySide2.QtGui.QIcon or str "string"' ) def icon(self): return self.button.icon() def setIconSize(self, iconSize): self.button.setIconSize(iconSize) # if type(iconSize) is QSize: # self.button.setIconSize(iconSize) # elif type(iconSize) is int: # self.button.setIcon(QSize(iconSize, iconSize)) # elif type(type) is iter: # import collections # if isinstance(iconSize, collections.Iterable): # if len(iconSize) == 1: # self.setIconSize(iconSize[0]) # elif len(iconSize) == 2: # self.setIconSize(QSize(iconSize[0], iconSize[1])) # else: # raise Exception() # else: # raise Exception("Wrong argument type, iconSize should be either PySide2.QtCore.QSize or int value or width and height " # "or iterable contains one QSize, one int or two int values for width and height respectively") def iconSize(self): return self.button.iconSize() def setFirstDayOfWeek(self, firstDayOfWeek): self.calender.setFirstDayOfWeek(firstDayOfWeek) # if type(firstDayOfWeek) is Qt.DayOfWeek: # self.calender.setFirstDayOfWeek(firstDayOfWeek) # elif type(firstDayOfWeek) is int: # if firstDayOfWeek < 1 or firstDayOfWeek > 7: # raise Exception("Wrong argument, firstDayOfWeek should be from 1 to 7 (Monday --> Sunday)") # self.calender.setFirstDayOfWeek(Qt.DayOfWeek(firstDayOfWeek)) # else: # raise Exception("Wrong type, firstDayOfWeek should be either PySide2.QtCore.Qt.DayOf or int (1 --> 7) (Monday --> Sunday)") def firstDayOfWeek(self): self.calender.firstDayOfWeek() def selectedDate(self): self.calender.selectedDate() def setSelectedDate(self, args, kwargs): self.calender.setSelectedDate(args, kwargs) def minimumDate(self): self.calender.minimumDate() def setMinimumDate(self): self.calender.setMinimumDate() def __onSelectionChanged__(self): self.selectionChanged.emit()
def createLayout(self): self.GridGroupBox = QGroupBox("ESD tranisent control") l1 = QLabel("HOST PORT") h1 = QHBoxLayout() a3host = QLineEdit('127.0.0.1') a3col = QLabel(':') a3port = QLineEdit('22222') h1.addWidget(a3host) h1.addWidget(a3col) h1.addWidget(a3port) l3 = QLabel("COM port") hbb = QHBoxLayout() comport = QComboBox() #comport.addItem('COM1') comport.addItems(['COM1', 'COM2', 'COM3', 'COM4', 'COM5']) l4 = QLabel("Baue rate") comBaud = QComboBox() comBaud.addItems(['9600', '115200']) hbb.addWidget(comport) hbb.addWidget(l4) hbb.addWidget(comBaud) l4 = QLabel("Profile CSV") self.prof = QLineEdit() hb = QHBoxLayout() btnSel = QPushButton("Select") btnSel.clicked.connect(self.openFileNameDialog) hb.addWidget(self.prof) hb.addWidget(btnSel) l5 = QLabel("INCA Label") self.label = QLineEdit("PhyMod_trq2qBas_MAP") self.labelType = QComboBox() l6 = QLabel("Type") self.labelType.addItems([r'MAP/CURVE', 'Single']) h2 = QHBoxLayout() h2.addWidget(self.label) h2.addWidget(l6) h2.addWidget(self.labelType) fbox = QFormLayout() fbox.addRow(l1, h1) fbox.addRow(l3, hbb) fbox.addRow(l4, hb) fbox.addRow(l5, h2) hbox = QHBoxLayout() init = QPushButton("Init") HeatBeat = QPushButton("Heart beat") run = QPushButton("Run") stop = QPushButton("Stop") hbox.addWidget(init) hbox.addWidget(stop) hbox.addWidget(run) hbox.addWidget(HeatBeat) fbox.addRow(QLabel("control"), hbox) self.GridGroupBox.setLayout(fbox)
class MainWindow(QMainWindow): """Main class for interacting with the applications GUI.""" @Slot(str) def startProgress(self, message): """Shows that the window is busy doing some work.""" self.translateButton.setEnabled(False) self.dictsCombo.setEnabled(False) label = QLabel(message) label.setAlignment(Qt.AlignHCenter) progressBar = QProgressBar() progressBar.setRange(0, 0) self.statusBar().clearMessage() self.statusBar().addWidget(label, 1) self.statusBar().addWidget(progressBar, 1) QGuiApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) @Slot() def endProgress(self): """Shows that the window is ready for the interaction.""" self.statusBar().setParent(None) self.statusBar().showMessage(self.tr("Done"), 2000) QGuiApplication.restoreOverrideCursor() self.translateButton.setEnabled(True) self.dictsCombo.setEnabled(True) @Slot() def about(self): """Shows the "about" message box.""" title = self.tr("About FreeLingvo") text = self.tr( "<b>FreeLingvo</b> is a dictionary search application" " that can work with over 140 dictionaries without" " Internet connection and is available under the" " GNU General Public License v3.<br><br>" "To search for translations in the selected" " dictionary, you must enter the desired word" " in the field and press \"Enter\" or click the" " \"translate\" button. You can also enter a sentence." " In this case, the sentence will be divided into" " separate words and possible combinations of these words." " The program will search for each word and combination" " in the selected dictionary, in which case the" " output can be large.<br><br>" "<b>Homepage:</b>" "<a href=\"https://github.com/ache2014/FreeLingvo\">" " GitHub</a><br>" "<b>Contact:</b>" "<a href=\"mailto:[email protected]\">" " [email protected]</a>") QMessageBox.about(self, title, text) @Slot(list) def showTranslations(self, translations): """Shows translations in the translations browser""" if translations: text = "<hr>".join(translations) else: text = self.tr("Sorry, no translations were found for:") text += "<br><b>{}</b>".format(self.searchText.text()) cursor = self.translationsBrowser.textCursor() cursor.select(QTextCursor.Document) cursor.insertHtml(text) @Slot(str) def changeFontSize(self, size): """Changes the font size for the translations browser.""" self.translationsBrowser.setFont(QFont(self.font().family(), int(size))) self.update() def __init__(self, parent=None, *args, appctxt=None, **kwargs): """Initializes all GUI elements and a separate thread.""" super().__init__(parent) self.appctxt = appctxt self.worker = Worker(self) self.workerThread = QThread() self.worker.moveToThread(self.workerThread) self.workerThread.finished.connect(self.worker.deleteLater) self.worker.started.connect(self.startProgress) self.worker.ended.connect(self.endProgress) self.worker.translationsReady.connect(self.showTranslations) self.workerThread.start() screenGeometry = QGuiApplication.screens()[0].geometry() self.setGeometry(screenGeometry.width() / 5, screenGeometry.height() / 5, screenGeometry.width() / 3, screenGeometry.height() / 3) self.setMinimumSize(screenGeometry.width() / 4, screenGeometry.height() / 4) self.fileMenu = self.menuBar().addMenu(self.tr("&File")) self.exitAct = self.fileMenu.addAction(self.tr("&Exit")) self.exitAct.setStatusTip(self.tr("Exit from FreeLingvo")) self.exitAct.triggered.connect(self.close) self.helpMenu = self.menuBar().addMenu(self.tr("&Help")) self.aboutAct = self.helpMenu.addAction(self.tr("&About")) self.aboutAct.setStatusTip( self.tr("Show information about FreeLingvo")) self.aboutAct.triggered.connect(self.about) self.searchText = QLineEdit() self.searchText.setPlaceholderText( self.tr("What word(s) to look for?")) self.searchText.setClearButtonEnabled(True) self.searchText.returnPressed.connect(self.worker.findTranslations) self.translateButton = QPushButton(self.tr("Translate")) self.translateButton.clicked.connect(self.worker.findTranslations) self.dictsCombo = QComboBox() self.dictsCombo.setInsertPolicy(QComboBox.InsertAlphabetically) self.dictsCombo.setToolTip( self.tr("Dictionary used to search for words")) dictNames = os.listdir(self.appctxt.get_resource("dictionaries")) dictNames = [name.replace(".tei", "") for name in dictNames] self.dictsCombo.addItems(dictNames) self.dictsCombo.currentIndexChanged[str].connect(self.worker.loadDict) self.dictsCombo.setCurrentIndex(1) self.translationsBrowser = QTextBrowser() self.translationsBrowser.setUndoRedoEnabled(True) self.undoButton = QPushButton( QIcon(self.appctxt.get_resource("images/arrow_back.png")), "") self.undoButton.setEnabled(False) self.undoButton.setToolTip(self.tr("Show previous translation")) self.undoButton.clicked.connect(self.translationsBrowser.undo) self.translationsBrowser.undoAvailable.connect( self.undoButton.setEnabled) self.redoButton = QPushButton( QIcon(self.appctxt.get_resource("images/arrow_forward.png")), "") self.redoButton.setEnabled(False) self.redoButton.setToolTip(self.tr("Show next translation")) self.redoButton.clicked.connect(self.translationsBrowser.redo) self.translationsBrowser.redoAvailable.connect( self.redoButton.setEnabled) self.sizeLabel = QLabel(self.tr("Font size:")) self.sizeCombo = QComboBox() for size in QFontDatabase.standardSizes(): self.sizeCombo.addItem(str(size)) self.sizeCombo.setCurrentText(str(self.font().pointSize())) self.sizeCombo.currentIndexChanged[str].connect(self.changeFontSize) self.controlsLayout = QHBoxLayout() self.controlsLayout.addWidget(self.searchText) self.controlsLayout.addWidget(self.translateButton) self.controlsLayout.addWidget(self.dictsCombo) self.browserToolsLayout = QHBoxLayout() self.browserToolsLayout.addWidget(self.undoButton) self.browserToolsLayout.addWidget(self.redoButton) self.browserToolsLayout.addStretch(1) self.browserToolsLayout.addWidget(self.sizeLabel) self.browserToolsLayout.addWidget(self.sizeCombo) self.centralLayout = QVBoxLayout() self.centralLayout.addLayout(self.controlsLayout) self.centralLayout.addLayout(self.browserToolsLayout) self.centralLayout.addWidget(self.translationsBrowser) centralWidget = QWidget() centralWidget.setLayout(self.centralLayout) self.setCentralWidget(centralWidget) self.statusBar().showMessage(self.tr("Ready"), 2000) def closeEvent(self, event): """Destroys the thread properly before exiting.""" self.workerThread.quit() self.workerThread.wait() super().closeEvent(event)
def setupFlatUi(self): self._dragPos = self.pos() self._isDragging = False self.setMouseTracking(True) self.setWindowFlags(Qt.FramelessWindowHint) self.setStyleSheet(""" QWidget { background-color:#99d9ea; /*background-image: url(:/background.png);*/ outline: 1px solid #0057ff; } QLabel { color:#202020; font-size:13px; font-family:Century; } QComboBox { color:#202020; font-size:13px; font-family:Century Schoolbook; } QComboBox { border: none; padding: 1px 18px 1px 3px; } QComboBox:editable { background: white; } QComboBox:!editable, QComboBox::drop-down:editable { background: #62c7e0; } QComboBox:!editable:hover, QComboBox::drop-down:editable:hover { background: #c7eaf3; } QComboBox:!editable:pressed, QComboBox::drop-down:editable:pressed { background: #35b6d7; } QComboBox:on { padding-top: 3px; padding-left: 4px; } QComboBox::drop-down { subcontrol-origin: padding; subcontrol-position: top right; width: 16px; border: none; } QComboBox::down-arrow { image: url(:/downarrow.png); } QComboBox::down-arrow:on { image: url(:/uparrow.png); } QGroupBox { color:#202020; font-size:12px; font-family:Century Schoolbook; border: 1px solid gray; margin-top: 15px; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top left; left:5px; top:3px; } QCheckBox { color:#202020; spacing: 5px; font-size:12px; font-family:Century Schoolbook; } QScrollBar:horizontal { background-color:#99d9ea; border: none; height: 15px; margin: 0px 20px 0 20px; } QScrollBar::handle:horizontal { background: #61b9e1; min-width: 20px; } QScrollBar::add-line:horizontal { image: url(:/rightarrow.png); border: none; background: #7ecfe4; width: 20px; subcontrol-position: right; subcontrol-origin: margin; } QScrollBar::sub-line:horizontal { image: url(:/leftarrow.png); border: none; background: #7ecfe4; width: 20px; subcontrol-position: left; subcontrol-origin: margin; } QScrollBar:vertical { background-color:#99d9ea; border: none; width: 15px; margin: 20px 0px 20px 0px; } QScrollBar::handle::vertical { background: #61b9e1; min-height: 20px; } QScrollBar::add-line::vertical { image: url(:/downarrow.png); border: none; background: #7ecfe4; height: 20px; subcontrol-position: bottom; subcontrol-origin: margin; } QScrollBar::sub-line::vertical { image: url(:/uparrow.png); border: none; background: #7ecfe4; height: 20px; subcontrol-position: top; subcontrol-origin: margin; } QTableView { background-color: white; /*selection-background-color: #FF92BB;*/ border: 1px solid #eeeeee; color: #2f2f2f; } QTableView::focus { /*border: 1px solid #2a7fff;*/ } QTableView QTableCornerButton::section { border: none; border-right: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; background-color: #8ae6d2; } QTableView QWidget { background-color: white; } QTableView::item:focus { border: 1px red; background-color: transparent; color: #2f2f2f; } QHeaderView::section { border: none; border-right: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; padding-left: 2px; padding-right: 2px; color: #444444; background-color: #8ae6d2; } QTextEdit { background-color:white; color:#2f2f2f; border: 1px solid white; } QTextEdit::focus { border: 1px solid #2a7fff; } QPushButton { background-color:#30a7b8; border:none; color:#ffffff; font-size:14px; font-family:Century Schoolbook; } QPushButton:hover { background-color:#51c0d1; } QPushButton:pressed { background-color:#3a9ecc; } QMenuBar { color: #2f2f2f; } QMenuBar::item { background-color: transparent; margin: 8px 0px 0px 0px; padding: 1px 8px 1px 8px; height: 15px; } QMenuBar::item:selected { background: #51c0d1; } QMenuBar::item:pressed { } QMenu { color: #2f2f2f; } QMenu { margin: 2px; } QMenu::item { padding: 2px 25px 2px 21px; border: 1px solid transparent; } QMenu::item:selected { background: #51c0d1; } QMenu::icon { background: transparent; border: 2px inset transparent; } QDockWidget { font-size:13px; font-family:Century; color: #202020; titlebar-close-icon: none; titlebar-normal-icon: none; } QDockWidget::title { margin: 0; padding: 2px; subcontrol-origin: content; subcontrol-position: right top; text-align: left; background: #67baed; } QDockWidget::float-button { max-width: 12px; max-height: 12px; background-color:transparent; border:none; image: url(:/restore_inactive.png); } QDockWidget::float-button:hover { background-color:#227582; image: url(:/restore_active.png); } QDockWidget::float-button:pressed { padding: 0; background-color:#14464e; image: url(:/restore_active.png); } QDockWidget::close-button { max-width: 12px; max-height: 12px; background-color:transparent; border:none; image: url(:/close_inactive.png); } QDockWidget::close-button:hover { background-color:#ea5e00; image: url(:/close_active.png); } QDockWidget::close-button:pressed { background-color:#994005; image: url(:/close_active.png); padding: 0; } """) self.dockWidgetContents.setStyleSheet(""" QPushButton { min-height:23px; } """) self.dockWidget_QuickSend.setStyleSheet(""" QPushButton { background-color:#27b798; font-family:Consolas; font-size:12px; min-width:46px; } QPushButton:hover { background-color:#3bd5b4; } QPushButton:pressed { background-color:#1d8770; } """) self.dockWidgetContents_2.setStyleSheet(""" QPushButton { min-height:23px; min-width:50px; } """) w = self.frameGeometry().width() self._minBtn = QPushButton(self) self._minBtn.setGeometry(w-103,0,28,24) self._minBtn.clicked.connect(self.onMinimize) self._minBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/minimize_inactive.png); } QPushButton:hover { background-color:#227582; image: url(:/minimize_active.png); } QPushButton:pressed { background-color:#14464e; image: url(:/minimize_active.png); } """) self._maxBtn = QPushButton(self) self._maxBtn.setGeometry(w-74,0,28,24) self._maxBtn.clicked.connect(self.onMaximize) self.setMaximizeButton("maximize") self._closeBtn = QPushButton(self) self._closeBtn.setGeometry(w-45,0,36,24) self._closeBtn.clicked.connect(self.onExit) self._closeBtn.setStyleSheet(""" QPushButton { background-color:transparent; border:none; outline: none; image: url(:/close_inactive.png); } QPushButton:hover { background-color:#ea5e00; image: url(:/close_active.png); } QPushButton:pressed { background-color:#994005; image: url(:/close_active.png); } """)
class UserExportedAttributeWidget(mayaMixin.MayaQWidgetDockableMixin, QWidget): _currentInstance = None @classmethod def closeCurrentInstance(cls): if cls._currentInstance is not None: if cls._currentInstance._mayaSelectionChangedJob is not None: cmds.scriptJob(kill=cls._currentInstance._mayaSelectionChangedJob) cls._currentInstance._mayaSelectionChangedJob = None if cls._currentInstance._mayaUndoJob is not None: cmds.scriptJob(kill=cls._currentInstance._mayaUndoJob) cls._currentInstance._mayaUndoJob = None if cls._currentInstance._mayaRedoJob is not None: cmds.scriptJob(kill=cls._currentInstance._mayaRedoJob) cls._currentInstance._mayaRedoJob = None cls._currentInstance.close() cls._currentInstance = None def __init__(self, parent=None): UserExportedAttributeWidget.closeCurrentInstance() super(UserExportedAttributeWidget, self).__init__(parent=parent) self._setupUI() self._mayaSelectionChangedJob = cmds.scriptJob(event=["SelectionChanged", self._syncUI]) self._mayaUndoJob = cmds.scriptJob(event=["Undo", self._syncUI]) self._mayaRedoJob = cmds.scriptJob(event=["Redo", self._syncUI]) UserExportedAttributeWidget._currentInstance = self # Force a sync on the first load. self._syncUI() def _setupUI(self): self.setWindowTitle("Export Attributes to USD") layout = QVBoxLayout() # This section contains the attributes tagged for export. label = QLabel() label.setText('Exported Attributes:') layout.addWidget(label) self.exportedAttrsModel = ExportedAttributesModel() self.exportedAttrsView = ExportedAttributesView() self.exportedAttrsView.verticalHeader().hide() self.exportedAttrsView.setModel(self.exportedAttrsModel) selectionModel = self.exportedAttrsView.selectionModel() selectionModel.selectionChanged.connect(self._onExportedAttrsSelectionChanged) self.exportedAttrsModel.dataChanged.connect(self._onModelDataChanged) layout.addWidget(self.exportedAttrsView) self.removeExportedAttrButton = QPushButton("Remove Exported Attribute") self.removeExportedAttrButton.clicked.connect(self._onRemoveExportedAttrPressed) self.removeExportedAttrButton.setEnabled(False) layout.addWidget(self.removeExportedAttrButton) # This section contains the attributes available for export. label = QLabel() label.setText('Available Attributes:') layout.addWidget(label) self.userDefinedCheckBox = QCheckBox('User Defined') self.userDefinedCheckBox.setToolTip('Show only user-defined (dynamic) attributes') self.userDefinedCheckBox.setChecked(True) self.userDefinedCheckBox.stateChanged.connect(self._syncUI) layout.addWidget(self.userDefinedCheckBox) self.addAttrsModel = AddAttributesModel() self.addAttrsView = AddAttributesView() self.addAttrsView.setModel(self.addAttrsModel) selectionModel = self.addAttrsView.selectionModel() selectionModel.selectionChanged.connect(self._onAddAttrsSelectionChanged) self.addAttrsModel.dataChanged.connect(self._onModelDataChanged) layout.addWidget(self.addAttrsView) self.addExportedAttrButton = QPushButton("Add Exported Attribute") self.addExportedAttrButton.clicked.connect(self._onAddExportedAttrPressed) self.addExportedAttrButton.setEnabled(False) layout.addWidget(self.addExportedAttrButton) self.setLayout(layout) def _onExportedAttrsSelectionChanged(self, selected, deselected): if selected.isEmpty(): self.removeExportedAttrButton.setEnabled(False) else: self.removeExportedAttrButton.setEnabled(True) def _onAddAttrsSelectionChanged(self, selected, deselected): if selected.isEmpty(): self.addExportedAttrButton.setEnabled(False) else: self.addExportedAttrButton.setEnabled(True) def _onRemoveExportedAttrPressed(self): selectedNodeNames = cmds.ls(selection=True, long=True) if not selectedNodeNames: return mayaAttrNames = [x.data() for x in self.exportedAttrsView.selectedIndexes()] if not mayaAttrNames: return for selectedNodeName in selectedNodeNames: ExportedAttribute.RemoveExportedAttributesForNode(selectedNodeName, mayaAttrNames) self._syncUI() def _onAddExportedAttrPressed(self): selectedNodeNames = cmds.ls(selection=True, long=True) if not selectedNodeNames: return exportedAttrs = [ExportedAttribute(x.data()) for x in self.addAttrsView.selectedIndexes()] if not exportedAttrs: return for selectedNodeName in selectedNodeNames: ExportedAttribute.UpdateExportedAttributesForNode(selectedNodeName, exportedAttrs) self._syncUI() def _onModelDataChanged(self, topLeft, bottomRight): self._syncUI() def _syncUI(self): # Since _syncUI is called in response to events that invalidate/clear # the selections in the views, disable the buttons until something is # selected again. self.removeExportedAttrButton.setEnabled(False) self.addExportedAttrButton.setEnabled(False) selectedNodeNames = cmds.ls(selection=True, long=True) if not selectedNodeNames: self.addAttrsModel.setStringList([]) self.exportedAttrsModel.exportedAttributes = [] self.exportedAttrsView.resizeColumnsToContents() return # Collect the export attributes common to all selected nodes. If the # same attribute is configured differently on multiple objects (e.g. # different usdAttrName), then do not include that attribute. allExportedAttributeNames = set() commonExportedAttributeNames = set() commonExportedAttrs = {} for exportedAttr in ExportedAttribute.GetExportedAttributesFromNode(selectedNodeNames[0]): mayaAttrName = exportedAttr.mayaAttrName allExportedAttributeNames.add(mayaAttrName) commonExportedAttributeNames.add(mayaAttrName) commonExportedAttrs[mayaAttrName] = exportedAttr for selectedNodeName in selectedNodeNames[1:]: exportedAttrNames = set() for exportedAttr in ExportedAttribute.GetExportedAttributesFromNode(selectedNodeName): mayaAttrName = exportedAttr.mayaAttrName allExportedAttributeNames.add(mayaAttrName) if (mayaAttrName in commonExportedAttrs and commonExportedAttrs[mayaAttrName] == exportedAttr): exportedAttrNames.add(mayaAttrName) commonExportedAttributeNames.intersection_update(exportedAttrNames) commonExportedAttrs = [commonExportedAttrs[x] for x in commonExportedAttributeNames] commonExportedAttrs.sort(key=lambda x: x.mayaAttrName) self.exportedAttrsModel.exportedAttributes = commonExportedAttrs # Normally, the combo boxes for selecting usdAttrType and # primvarInterpolation would only appear when the table cell is put into # edit mode. Instead, we want the combo boxes to always be visible, so # we tell the view to open them as persistent editors. for row in xrange(self.exportedAttrsModel.rowCount()): usdAttrTypeIndex = self.exportedAttrsModel.index(row, ExportedAttributesModel.USD_ATTR_TYPE_COLUMN) self.exportedAttrsView.openPersistentEditor(usdAttrTypeIndex) # Only open the interpolation editor if this is a primvar. if self.exportedAttrsModel.data(usdAttrTypeIndex) == USD_ATTR_TYPE_PRIMVAR: primvarInterpolationIndex = self.exportedAttrsModel.index(row, ExportedAttributesModel.PRIMVAR_INTERPOLATION_COLUMN) self.exportedAttrsView.openPersistentEditor(primvarInterpolationIndex) # Only open the double-to-single precision editor if the Maya # attribute is double-based. mayaAttrNameIndex = self.exportedAttrsModel.index(row, ExportedAttributesModel.MAYA_ATTR_NAME_COLUMN) mayaAttrName = self.exportedAttrsModel.data(mayaAttrNameIndex) if _ShouldEnableDoublePrecisionEditor(mayaAttrName): doublePrecisionIndex = self.exportedAttrsModel.index(row, ExportedAttributesModel.DOUBLE_PRECISION_COLUMN) self.exportedAttrsView.openPersistentEditor(doublePrecisionIndex) self.exportedAttrsView.resizeColumnsToContents() # Collect the attributes common to all selected nodes. cmdOptions = {'read': True} if self.userDefinedCheckBox.isChecked(): cmdOptions['userDefined'] = True commonAttrNames = set(cmds.listAttr(selectedNodeNames[0], **cmdOptions) or []) for selectedNodeName in selectedNodeNames[1:]: attrNames = set(cmds.listAttr(selectedNodeName, **cmdOptions) or []) commonAttrNames.intersection_update(attrNames) # Subtract out reserved attribute names and attributes already being # exported by ANY node. commonAttrNames -= RESERVED_ATTRIBUTES commonAttrNames -= allExportedAttributeNames self.addAttrsModel.setStringList(sorted(list(commonAttrNames)))
class AudioTest(QMainWindow): PUSH_MODE_LABEL = "Enable push mode" PULL_MODE_LABEL = "Enable pull mode" SUSPEND_LABEL = "Suspend playback" RESUME_LABEL = "Resume playback" DurationSeconds = 1 ToneSampleRateHz = 600 DataSampleRateHz = 44100 def __init__(self): super(AudioTest, self).__init__() self.m_device = QAudioDeviceInfo.defaultOutputDevice() self.m_output = None self.initializeWindow() self.initializeAudio() def initializeWindow(self): layout = QVBoxLayout() self.m_deviceBox = QComboBox() self.m_deviceBox.activated[int].connect(self.deviceChanged) for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput): self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo) layout.addWidget(self.m_deviceBox) self.m_modeButton = QPushButton() self.m_modeButton.clicked.connect(self.toggleMode) self.m_modeButton.setText(self.PUSH_MODE_LABEL) layout.addWidget(self.m_modeButton) self.m_suspendResumeButton = QPushButton( clicked=self.toggleSuspendResume) self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) layout.addWidget(self.m_suspendResumeButton) volumeBox = QHBoxLayout() volumeLabel = QLabel("Volume:") self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100, singleStep=10) self.m_volumeSlider.valueChanged.connect(self.volumeChanged) volumeBox.addWidget(volumeLabel) volumeBox.addWidget(self.m_volumeSlider) layout.addLayout(volumeBox) window = QWidget() window.setLayout(layout) self.setCentralWidget(window) def initializeAudio(self): self.m_pullTimer = QTimer(self) self.m_pullTimer.timeout.connect(self.pullTimerExpired) self.m_pullMode = True self.m_format = QAudioFormat() self.m_format.setSampleRate(self.DataSampleRateHz) self.m_format.setChannelCount(1) self.m_format.setSampleSize(16) self.m_format.setCodec('audio/pcm') self.m_format.setByteOrder(QAudioFormat.LittleEndian) self.m_format.setSampleType(QAudioFormat.SignedInt) info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice()) if not info.isFormatSupported(self.m_format): qWarning("Default format not supported - trying to use nearest") self.m_format = info.nearestFormat(self.m_format) self.m_generator = Generator(self.m_format, self.DurationSeconds * 1000000, self.ToneSampleRateHz, self) self.createAudioOutput() def createAudioOutput(self): self.m_audioOutput = QAudioOutput(self.m_device, self.m_format) self.m_audioOutput.notify.connect(self.notified) self.m_audioOutput.stateChanged.connect(self.handleStateChanged) self.m_generator.start() self.m_audioOutput.start(self.m_generator) self.m_volumeSlider.setValue(self.m_audioOutput.volume() * 100) def deviceChanged(self, index): self.m_pullTimer.stop() self.m_generator.stop() self.m_audioOutput.stop() self.m_device = self.m_deviceBox.itemData(index) self.createAudioOutput() def volumeChanged(self, value): if self.m_audioOutput is not None: self.m_audioOutput.setVolume(value / 100.0) def notified(self): qWarning("bytesFree = %d, elapsedUSecs = %d, processedUSecs = %d" % ( self.m_audioOutput.bytesFree(), self.m_audioOutput.elapsedUSecs(), self.m_audioOutput.processedUSecs())) def pullTimerExpired(self): if self.m_audioOutput is not None and self.m_audioOutput.state() != QAudio.StoppedState: chunks = self.m_audioOutput.bytesFree() // self.m_audioOutput.periodSize() for _ in range(chunks): data = self.m_generator.read(self.m_audioOutput.periodSize()) if data is None or len(data) != self.m_audioOutput.periodSize(): break self.m_output.write(data) def toggleMode(self): self.m_pullTimer.stop() self.m_audioOutput.stop() if self.m_pullMode: self.m_modeButton.setText(self.PULL_MODE_LABEL) self.m_output = self.m_audioOutput.start() self.m_pullMode = False self.m_pullTimer.start(20) else: self.m_modeButton.setText(self.PUSH_MODE_LABEL) self.m_pullMode = True self.m_audioOutput.start(self.m_generator) self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) def toggleSuspendResume(self): if self.m_audioOutput.state() == QAudio.SuspendedState: qWarning("status: Suspended, resume()") self.m_audioOutput.resume() self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) elif self.m_audioOutput.state() == QAudio.ActiveState: qWarning("status: Active, suspend()") self.m_audioOutput.suspend() self.m_suspendResumeButton.setText(self.RESUME_LABEL) elif self.m_audioOutput.state() == QAudio.StoppedState: qWarning("status: Stopped, resume()") self.m_audioOutput.resume() self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) elif self.m_audioOutput.state() == QAudio.IdleState: qWarning("status: IdleState") stateMap = { QAudio.ActiveState: "ActiveState", QAudio.SuspendedState: "SuspendedState", QAudio.StoppedState: "StoppedState", QAudio.IdleState: "IdleState"} def handleStateChanged(self, state): qWarning("state = " + self.stateMap.get(state, "Unknown"))
def __init__(self): super(IpInformation, self).__init__() # Use language settings self.ml = ManageLng() main_layout = QGridLayout() self.setLayout(main_layout) # Prefix-mask-conversion group box self.prefix_mask_box = QGroupBox( self.ml.get_tr_text("tab_ip_information_prefix_mask_conv")) self.prefix_mask_box.setMaximumHeight(90) main_layout.addWidget(self.prefix_mask_box, 0, 0) prefix_mask_box_layout = QGridLayout() prefix_mask_box_layout.setContentsMargins(200, 20, 200, 20) prefix_mask_box_layout.setHorizontalSpacing(30) self.prefix_mask_box.setLayout(prefix_mask_box_layout) self.prefix_input = QLineEdit() self.prefix_input.setMaxLength(3) self.prefix_input.setAlignment(Qt.AlignCenter) self.prefix_input.setPlaceholderText( self.ml.get_tr_text("tab_ip_information_prefix_ptext")) prefix_mask_box_layout.addWidget(self.prefix_input, 0, 0) self.mask_input = QLineEdit() self.mask_input.setMaxLength(15) self.mask_input.setAlignment(Qt.AlignCenter) self.mask_input.setPlaceholderText( self.ml.get_tr_text("tab_ip_information_mask_ptext")) prefix_mask_box_layout.addWidget(self.mask_input, 0, 1) self.convert_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_conv_btn")) self.convert_btn.setIcon(QIcon("static/images/exchange.png")) self.convert_btn.clicked.connect(self.convert_action) self.prefix_input.returnPressed.connect(self.convert_action) self.mask_input.returnPressed.connect(self.convert_action) prefix_mask_box_layout.addWidget(self.convert_btn, 0, 2, alignment=Qt.AlignLeft) # IP information group box self.ip_information_box = QGroupBox( self.ml.get_tr_text("tab_ip_information_ipinfo_gbox")) main_layout.addWidget(self.ip_information_box, 1, 0) ip_information_box_layout = QGridLayout() ip_information_box_layout.setContentsMargins(80, 80, 80, 80) ip_information_box_layout.setHorizontalSpacing(30) ip_information_box_layout.setVerticalSpacing(15) self.ip_information_box.setLayout(ip_information_box_layout) self.ip_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_ipadd_lab")) ip_information_box_layout.addWidget(self.ip_address_label, 0, 0, alignment=Qt.AlignCenter) self.ip_address_textfield = QLineEdit() self.ip_address_textfield.setPlaceholderText("192.168.1.100/24") self.ip_address_textfield.setAlignment(Qt.AlignCenter) self.ip_address_textfield.setMaxLength(18) ip_information_box_layout.addWidget(self.ip_address_textfield, 0, 1) self.get_info_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_getinfo_btn")) self.get_info_btn.setIcon(QIcon("static/images/get_info.png")) self.get_info_btn.clicked.connect(self.get_info_action) self.ip_address_textfield.returnPressed.connect(self.get_info_action) ip_information_box_layout.addWidget(self.get_info_btn, 0, 2) self.ip_class_label = QLabel( self.ml.get_tr_text("tab_ip_information_ipclass_lab")) ip_information_box_layout.addWidget(self.ip_class_label, 1, 0, alignment=Qt.AlignCenter) self.ip_class_textfield = QLineEdit() self.ip_class_textfield.setReadOnly(True) self.ip_class_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.ip_class_textfield, 1, 1) self.ip_class_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.ip_class_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.ip_class_copy_btn.clicked.connect( lambda: copy_action(self.ip_class_textfield.text())) ip_information_box_layout.addWidget(self.ip_class_copy_btn, 1, 2) self.ip_type_label = QLabel( self.ml.get_tr_text("tab_ip_information_iptype_lab")) ip_information_box_layout.addWidget(self.ip_type_label, 2, 0, alignment=Qt.AlignCenter) self.ip_type_textfield = QLineEdit() self.ip_type_textfield.setReadOnly(True) self.ip_type_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.ip_type_textfield, 2, 1) self.ip_type_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.ip_type_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.ip_type_copy_btn.clicked.connect( lambda: copy_action(self.ip_type_textfield.text())) ip_information_box_layout.addWidget(self.ip_type_copy_btn, 2, 2) self.network_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_netadd_lab")) ip_information_box_layout.addWidget(self.network_address_label, 3, 0, alignment=Qt.AlignCenter) self.network_address_textfield = QLineEdit() self.network_address_textfield.setReadOnly(True) self.network_address_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.network_address_textfield, 3, 1) self.network_address_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.network_address_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.network_address_copy_btn.clicked.connect( lambda: copy_action(self.network_address_textfield.text())) ip_information_box_layout.addWidget(self.network_address_copy_btn, 3, 2) self.subnet_mask_label = QLabel( self.ml.get_tr_text("tab_ip_information_mask_lab")) ip_information_box_layout.addWidget(self.subnet_mask_label, 4, 0, alignment=Qt.AlignCenter) self.subnet_mask_textfield = QLineEdit() self.subnet_mask_textfield.setReadOnly(True) self.subnet_mask_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.subnet_mask_textfield, 4, 1) self.subnet_mask_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.subnet_mask_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.subnet_mask_copy_btn.clicked.connect( lambda: copy_action(self.subnet_mask_textfield.text())) ip_information_box_layout.addWidget(self.subnet_mask_copy_btn, 4, 2) self.first_addressable_ip_label = QLabel( self.ml.get_tr_text("tab_ip_information_firstip_lab")) ip_information_box_layout.addWidget(self.first_addressable_ip_label, 5, 0, alignment=Qt.AlignCenter) self.first_addressable_ip_textfield = QLineEdit() self.first_addressable_ip_textfield.setReadOnly(True) self.first_addressable_ip_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget( self.first_addressable_ip_textfield, 5, 1) self.first_addressable_ip_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.first_addressable_ip_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.first_addressable_ip_copy_btn.clicked.connect( lambda: copy_action(self.first_addressable_ip_textfield.text())) ip_information_box_layout.addWidget(self.first_addressable_ip_copy_btn, 5, 2) self.last_addressable_ip_label = QLabel( self.ml.get_tr_text("tab_ip_information_lastip_lab")) ip_information_box_layout.addWidget(self.last_addressable_ip_label, 6, 0, alignment=Qt.AlignCenter) self.last_addressable_ip_textfield = QLineEdit() self.last_addressable_ip_textfield.setReadOnly(True) self.last_addressable_ip_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.last_addressable_ip_textfield, 6, 1) self.last_addressable_ip_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.last_addressable_ip_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.last_addressable_ip_copy_btn.clicked.connect( lambda: copy_action(self.last_addressable_ip_textfield.text())) ip_information_box_layout.addWidget(self.last_addressable_ip_copy_btn, 6, 2) self.broadcast_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_bcastip_lab")) ip_information_box_layout.addWidget(self.broadcast_address_label, 7, 0, alignment=Qt.AlignCenter) self.broadcast_address_textfield = QLineEdit() self.broadcast_address_textfield.setReadOnly(True) self.broadcast_address_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.broadcast_address_textfield, 7, 1) self.broadcast_address_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.broadcast_address_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.broadcast_address_copy_btn.clicked.connect( lambda: copy_action(self.broadcast_address_textfield.text())) ip_information_box_layout.addWidget(self.broadcast_address_copy_btn, 7, 2) self.next_network_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_nextnetip_lab")) ip_information_box_layout.addWidget(self.next_network_address_label, 8, 0, alignment=Qt.AlignCenter) self.next_network_address_textfield = QLineEdit() self.next_network_address_textfield.setReadOnly(True) self.next_network_address_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget( self.next_network_address_textfield, 8, 1) self.next_network_address_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.next_network_address_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.next_network_address_copy_btn.clicked.connect( lambda: copy_action(self.next_network_address_textfield.text())) ip_information_box_layout.addWidget(self.next_network_address_copy_btn, 8, 2) self.max_endpoint_label = QLabel( self.ml.get_tr_text("tab_ip_information_maxend_lab")) ip_information_box_layout.addWidget(self.max_endpoint_label, 9, 0, alignment=Qt.AlignCenter) self.max_endpoint_textfield = QLineEdit() self.max_endpoint_textfield.setReadOnly(True) self.max_endpoint_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.max_endpoint_textfield, 9, 1) self.max_endpoint_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.max_endpoint_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.max_endpoint_copy_btn.clicked.connect( lambda: copy_action(self.max_endpoint_textfield.text())) ip_information_box_layout.addWidget(self.max_endpoint_copy_btn, 9, 2)
class BlockingClient(QWidget): def __init__(self, parent=None): super(BlockingClient, self).__init__(parent) self.thread = FortuneThread() self.currentFortune = '' hostLabel = QLabel("&Server name:") portLabel = QLabel("S&erver port:") for ipAddress in QNetworkInterface.allAddresses(): if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0: break else: ipAddress = QHostAddress(QHostAddress.LocalHost) ipAddress = ipAddress.toString() self.hostLineEdit = QLineEdit(ipAddress) self.portLineEdit = QLineEdit() self.portLineEdit.setValidator(QIntValidator(1, 65535, self)) hostLabel.setBuddy(self.hostLineEdit) portLabel.setBuddy(self.portLineEdit) self.statusLabel = QLabel( "This example requires that you run the Fortune Server example as well.") self.statusLabel.setWordWrap(True) self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) self.getFortuneButton.setEnabled(False) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) self.thread.newFortune.connect(self.showFortune) self.thread.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostLineEdit, 0, 1) mainLayout.addWidget(portLabel, 1, 0) mainLayout.addWidget(self.portLineEdit, 1, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Blocking Fortune Client") self.portLineEdit.setFocus() def requestNewFortune(self): self.getFortuneButton.setEnabled(False) self.thread.requestNewFortune(self.hostLineEdit.text(), int(self.portLineEdit.text())) def showFortune(self, nextFortune): if nextFortune == self.currentFortune: self.requestNewFortune() return self.currentFortune = nextFortune self.statusLabel.setText(self.currentFortune) self.getFortuneButton.setEnabled(True) def displayError(self, socketError, message): if socketError == QAbstractSocket.HostNotFoundError: QMessageBox.information(self, "Blocking Fortune Client", "The host was not found. Please check the host and port " "settings.") elif socketError == QAbstractSocket.ConnectionRefusedError: QMessageBox.information(self, "Blocking Fortune Client", "The connection was refused by the peer. Make sure the " "fortune server is running, and check that the host name " "and port settings are correct.") else: QMessageBox.information(self, "Blocking Fortune Client", "The following error occurred: %s." % message) self.getFortuneButton.setEnabled(True) def enableGetFortuneButton(self): self.getFortuneButton.setEnabled(self.hostLineEdit.text() != '' and self.portLineEdit.text() != '')
def __init__(self, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowModality(Qt.ApplicationModal) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("Save")) self.closeButton = QPushButton(self.tr("Close")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) self.newFolderButton = QPushButton("New Folder") self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") self.edit = QPlainTextEdit() self.edit.setPlaceholderText("python code") self.resetting = False self.columns = 3 self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetDescription.setPlaceholderText("optional description") #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopWidth(4 * font.width(' ')) #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode( x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.closeButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addLayout(description) vlayout.addWidget(self.edit) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" #Because you can't trust QT to do the right thing here if (sys.platform == "darwin"): self.settings = QSettings("Vector35", "Snippet Editor") else: self.settings = QSettings("Vector 35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry( self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.closeButton.clicked.connect(self.close) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) self.newFolderButton.clicked.connect(self.newFolder) if self.settings.contains("ui/snippeteditor/selected"): selectedName = self.settings.value("ui/snippeteditor/selected") self.tree.selectionModel().select( self.files.index(selectedName), QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) if self.tree.selectionModel().hasSelection(): self.selectFile(self.tree.selectionModel().selection(), None) self.edit.setFocus() cursor = self.edit.textCursor() cursor.setPosition(self.edit.document().characterCount() - 1) self.edit.setTextCursor(cursor) else: self.readOnly(True) else: self.readOnly(True)
def _setup_ui(self): self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) layout = QHBoxLayout(self) self.setLayout(layout) layout.setMargin(1) layout.setSpacing(1) adv_widget = QWidget(self) layout.addWidget(adv_widget) adv_layout = QVBoxLayout(adv_widget) adv_layout.addSpacing(15) l = QLabel('ADV\nS', adv_widget) l.setAlignment(Qt.AlignCenter) font = l.font() font.setPointSize(7) font.setBold(True) l.setFont(font) adv_layout.addWidget(l) b = QPushButton(adv_widget) b.setFixedSize(20, 20) b.pressed.connect(lambda: self._usbif.send(um.WriteControlAdvanceS())) adv_layout.addWidget(b) adv_layout.setAlignment(b, Qt.AlignCenter) l = QLabel('CRS\nPARITY', adv_widget) l.setFont(font) l.setAlignment(Qt.AlignCenter) adv_layout.addWidget(l, Qt.AlignCenter) b1, b2, b3, s1, s2, s3 = self._create_switch_group( layout, 'LOAD', 'PRESET\nCHAN', ['ODD', 'EVEN'], ['S1', 'S2'], ['S1', 'S2']) b1.pressed.connect(lambda: self._usbif.send(um.WriteControlLoadS())) b2.pressed.connect( lambda: self._usbif.send(um.WriteControlLoadPreset())) b3.pressed.connect(lambda: self._usbif.send(um.WriteControlLoadChan())) self._s1_s2_switches['load_preset'] = s2 self._s1_s2_switches['load_chan'] = s3 s2.toggled.connect(self._update_s1_s2_switches) s3.toggled.connect(self._update_s1_s2_switches) b1, b2, b3, s1, s2, s3 = self._create_switch_group( layout, 'READ', 'PRESET\nCHAN', None, ['S1', 'S2'], ['S1', 'S2']) b1.pressed.connect(lambda: self._usbif.send(um.WriteControlReadS())) b2.pressed.connect( lambda: self._usbif.send(um.WriteControlReadPreset())) b3.pressed.connect(lambda: self._usbif.send(um.WriteControlReadChan())) self._s1_s2_switches['read_preset'] = s2 self._s1_s2_switches['read_chan'] = s3 s2.toggled.connect(self._update_s1_s2_switches) s3.toggled.connect(self._update_s1_s2_switches) b1, b2, b3, s1, s2, s3 = self._create_switch_group( layout, 'START', '\nRESTART', None, ['S1', 'S2'], None) b1.pressed.connect(lambda: self._usbif.send(um.WriteControlStartS())) b2.pressed.connect( lambda: self._usbif.send(um.WriteControlStartPreset())) b3.pressed.connect(lambda: self._usbif.send(um.WriteControlStart())) self._s1_s2_switches['start_preset'] = s2 s2.toggled.connect(self._update_s1_s2_switches) pro_widget = QWidget(self) layout.addWidget(pro_widget) pro_layout = QVBoxLayout(pro_widget) pro_layout.addSpacing(15) l = QLabel('PROCEED', pro_widget) l.setAlignment(Qt.AlignCenter) l.setFont(font) pro_layout.addWidget(l) b = QPushButton(pro_widget) b.setFixedSize(20, 20) pro_layout.addWidget(b) pro_layout.setAlignment(b, Qt.AlignCenter | Qt.AlignTop) b.pressed.connect(lambda: self._usbif.send(um.WriteControlProceed())) l = QLabel('RESET\nERROR', pro_widget) l.setAlignment(Qt.AlignCenter) l.setFont(font) pro_layout.addWidget(l) b = QPushButton(pro_widget) b.setFixedSize(20, 20) pro_layout.addWidget(b) pro_layout.setAlignment(b, Qt.AlignCenter | Qt.AlignTop)
def _add_process(self): process_groupbox = QGroupBox("Process") process_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) process_layout = QVBoxLayout() process_layout.setSpacing(0) process_groupbox.setLayout(process_layout) pbar_frame = QFrame() pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) pbar_hbox = QHBoxLayout() pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) pbar_hbox.setSpacing(16) # Run and stop buttons hbox = QHBoxLayout() hbox.setSpacing(8) self.run_button = QPushButton() # is only enabled when validation passes self.run_button.setEnabled(False) self.run_button.setText("Run") self.run_button.setToolTip("Start check execution") self.run_button.setFixedWidth(100) run_icon = qta.icon('fa.play', color='green') self.run_button.setIcon(run_icon) self.run_button.clicked.connect(self._click_run) hbox.addWidget(self.run_button) self.stop_button = QPushButton() self.stop_button.setEnabled(False) self.stop_button.setText("Stop") self.stop_button.setToolTip("Stop check execution") self.stop_button.setFixedWidth(100) stop_icon = qta.icon('fa.stop', color='red') self.stop_button.setIcon(stop_icon) self.stop_button.clicked.connect(self._click_stop) hbox.addWidget(self.stop_button) self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAlignment(QtCore.Qt.AlignCenter) self.progress_bar.setValue(0) self.progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) pbar_hbox.addLayout(hbox) pbar_hbox.addWidget(self.progress_bar) pbar_frame.setLayout(pbar_hbox) process_layout.addWidget(pbar_frame) vbox = QVBoxLayout() vbox.setSpacing(8) vbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) process_layout.addLayout(vbox) hbox = QHBoxLayout() vbox.addLayout(hbox) check_name_label = QLabel("Check:") check_name_label.setFixedWidth(80) hbox.addWidget(check_name_label) self.check_name_text_label = QLabel("n/a") hbox.addWidget(self.check_name_text_label) hbox = QHBoxLayout() vbox.addLayout(hbox) status_name_label = QLabel("Status:") status_name_label.setFixedWidth(80) hbox.addWidget(status_name_label) self.status_name_text_label = QLabel("Not started") hbox.addWidget(self.status_name_text_label) self.warning_frame = QFrame() self.warning_frame.setVisible(False) self.warning_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() warning_icon_widget = qta.IconWidget('fa.warning', color='red') warning_icon_widget.setIconSize(QtCore.QSize(48, 48)) warning_icon_widget.update() hbox.addWidget(warning_icon_widget) warning_label = QLabel( "Grid Transformer did not complete successfully. Please refer to " "log output.") warning_label.setStyleSheet("QLabel { color: red; }") warning_label.setWordWrap(True) warning_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(warning_label) self.warning_frame.setLayout(hbox) process_layout.addWidget(self.warning_frame) self.success_frame = QFrame() self.success_frame.setVisible(False) self.success_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() success_icon_widget = qta.IconWidget('fa.check', color='green') success_icon_widget.setIconSize(QtCore.QSize(48, 48)) success_icon_widget.update() hbox.addWidget(success_icon_widget) success_label = QLabel("All checks completed successfully.") success_label.setStyleSheet("QLabel { color: green; }") success_label.setWordWrap(True) success_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(success_label) self.success_frame.setLayout(hbox) process_layout.addWidget(self.success_frame) log_layout = QVBoxLayout() log_layout.setSpacing(4) log_label = QLabel("Log messages") log_label.setStyleSheet("QLabel { color: grey; }") log_layout.addWidget(log_label) self.log_messages = QPlainTextEdit() log_font = QFont("monospace") log_font.setStyleHint(QFont.TypeWriter) self.log_messages.setFont(log_font) self.log_messages.setReadOnly(True) self.log_messages.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) log_layout.addWidget(self.log_messages) process_layout.addLayout(log_layout) self.vbox.addWidget(process_groupbox)
def __init__(self, app, parent=None): super(MainWindow, self).__init__(parent) self.imagesDir = app.dir + '/images/' self.setWindowIcon(QIcon(self.imagesDir + 'icon.png')) self.path = '' self.settings = QSettings() self.lastDir = self.settings.value('lastDir', '') self.setMinimumWidth(540) self.supportedFormats = [] for f in QImageReader.supportedImageFormats(): self.supportedFormats.append(str(f.data(), encoding="utf-8")) self.fileWatcher = QFileSystemWatcher() self.fileWatcher.fileChanged.connect(self.fileChanged) # widgets self.showPixmapWidget = None self.tileWidthSpinBox = QSpinBox() self.tileWidthSpinBox.setValue(16) self.tileWidthSpinBox.setFixedWidth(50) self.tileWidthSpinBox.setMinimum(1) self.tileHeightSpinBox = QSpinBox() self.tileHeightSpinBox.setValue(16) self.tileHeightSpinBox.setFixedWidth(50) self.tileHeightSpinBox.setMinimum(1) self.paddingSpinBox = QSpinBox() self.paddingSpinBox.setFixedWidth(50) self.paddingSpinBox.setMinimum(1) self.transparentCheckbox = QCheckBox("Transparent") self.transparentCheckbox.setChecked(True) self.transparentCheckbox.stateChanged.connect(self.transparentChanged) self.backgroundColorEdit = ColorEdit() self.backgroundColorEdit.setEnabled(False) self.backgroundColorLabel = QLabel("Background color:") self.backgroundColorLabel.setEnabled(False) self.forcePotCheckBox = QCheckBox("Force PoT") self.forcePotCheckBox.setChecked(True) self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged) self.reorderTilesCheckBox = QCheckBox("Reorder tiles") self.generateAndExportButton = QPushButton("Generate and export") self.generateAndExportButton.setFixedHeight(32) self.generateAndExportButton.clicked.connect(self.generateAndExportClicked) self.generateAndExportButton.setEnabled(False) self.pixmapWidget = PixmapWidget() self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.pixmapWidget.setPixmap(self.createDropTextPixmap()) self.pixmapWidget.dropSignal.connect(self.fileDropped) self.pixmapWidget.setMinimumHeight(300) # load settings self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16))) self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16))) self.paddingSpinBox.setValue(int(self.settings.value('padding', 1))) self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False) self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False) self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False) self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF'))) self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry'))) self.restoreState(QByteArray(self.settings.value('MainWindow/windowState'))) # layout hl1 = QHBoxLayout() hl1.setContentsMargins(5, 5, 5, 5) hl1.addWidget(QLabel("Tile width:")) hl1.addSpacing(5) hl1.addWidget(self.tileWidthSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Tile height:")) hl1.addSpacing(5) hl1.addWidget(self.tileHeightSpinBox) hl1.addSpacing(15) hl1.addWidget(QLabel("Padding:")) hl1.addSpacing(5) hl1.addWidget(self.paddingSpinBox) hl1.addSpacing(15) hl1.addWidget(self.forcePotCheckBox) hl1.addSpacing(15) hl1.addWidget(self.reorderTilesCheckBox) hl1.addStretch() hl2 = QHBoxLayout() hl2.setContentsMargins(5, 5, 5, 5) hl2.addWidget(self.transparentCheckbox) hl2.addSpacing(15) hl2.addWidget(self.backgroundColorLabel) hl2.addSpacing(5) hl2.addWidget(self.backgroundColorEdit) hl2.addStretch() hl3 = QHBoxLayout() hl3.setContentsMargins(5, 5, 5, 5) hl3.addWidget(self.generateAndExportButton) vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) vl.setSpacing(0) vl.addLayout(hl1) vl.addLayout(hl2) vl.addWidget(self.pixmapWidget) vl.addLayout(hl3) w = QWidget() w.setLayout(vl) self.setCentralWidget(w) self.setTitle()
class RunTab(QtWidgets.QWidget): run_checks = QtCore.Signal() def __init__(self, prj: QAXProject): super(RunTab, self).__init__() self.prj = prj self.check_executor = None self.vbox = QtWidgets.QVBoxLayout() self.setLayout(self.vbox) self._add_check_outputs() self._add_process() # final setup self.set_run_stop_buttons_enabled(False) def _add_check_outputs(self): co_groupbox = QGroupBox("Check outputs") co_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) co_layout = QVBoxLayout() co_layout.setSpacing(16) co_groupbox.setLayout(co_layout) self.qajson_spatial_checkbox = QCheckBox( "Include summary spatial output in QAJSON. " "Supports QAX visualisation.") self.qajson_spatial_checkbox.setCheckState( QtCore.Qt.CheckState.Checked) co_layout.addWidget(self.qajson_spatial_checkbox) export_layout = QVBoxLayout() export_layout.setSpacing(4) self.export_spatial_checkbox = QCheckBox( "Export detailed spatial outputs to file. " "Supports visualisation in other geospatial applications.") self.export_spatial_checkbox.stateChanged.connect( self._on_export_spatial_changed) export_layout.addWidget(self.export_spatial_checkbox) output_folder_layout = QHBoxLayout() output_folder_layout.setSpacing(4) output_folder_layout.addSpacerItem(QtWidgets.QSpacerItem(37, 20)) self.output_folder_label = QLabel( "Detailed spatial output folder location:") output_folder_layout.addWidget(self.output_folder_label) self.output_folder_input = QLineEdit() self.output_folder_input.setText( GuiSettings.settings().value("spatial_outputs")) self.output_folder_input.setMinimumWidth(300) self.output_folder_input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) output_folder_layout.addWidget(self.output_folder_input) self.open_output_folder_button = QPushButton() output_folder_layout.addWidget(self.open_output_folder_button) self.open_output_folder_button.setIcon(qta.icon('fa.folder-open')) self.open_output_folder_button.setToolTip( f"Select file containing data") self.open_output_folder_button.clicked.connect( self._click_open_spatial_export_folder) export_layout.addLayout(output_folder_layout) co_layout.addLayout(export_layout) self._on_export_spatial_changed() self.vbox.addWidget(co_groupbox) def _click_open_spatial_export_folder(self): output_folder = QFileDialog.getExistingDirectory( self, f"Select folder for spatial outputs", GuiSettings.settings().value("spatial_outputs"), QFileDialog.ShowDirsOnly) if os.path.exists(output_folder): GuiSettings.settings().setValue("spatial_outputs", output_folder) self.output_folder_input.setText(output_folder) def _on_export_spatial_changed(self): is_export = self.export_spatial_checkbox.isChecked() self.output_folder_label.setEnabled(is_export) self.output_folder_input.setEnabled(is_export) self.open_output_folder_button.setEnabled(is_export) def _add_process(self): process_groupbox = QGroupBox("Process") process_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) process_layout = QVBoxLayout() process_layout.setSpacing(0) process_groupbox.setLayout(process_layout) pbar_frame = QFrame() pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) pbar_hbox = QHBoxLayout() pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) pbar_hbox.setSpacing(16) # Run and stop buttons hbox = QHBoxLayout() hbox.setSpacing(8) self.run_button = QPushButton() # is only enabled when validation passes self.run_button.setEnabled(False) self.run_button.setText("Run") self.run_button.setToolTip("Start check execution") self.run_button.setFixedWidth(100) run_icon = qta.icon('fa.play', color='green') self.run_button.setIcon(run_icon) self.run_button.clicked.connect(self._click_run) hbox.addWidget(self.run_button) self.stop_button = QPushButton() self.stop_button.setEnabled(False) self.stop_button.setText("Stop") self.stop_button.setToolTip("Stop check execution") self.stop_button.setFixedWidth(100) stop_icon = qta.icon('fa.stop', color='red') self.stop_button.setIcon(stop_icon) self.stop_button.clicked.connect(self._click_stop) hbox.addWidget(self.stop_button) self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAlignment(QtCore.Qt.AlignCenter) self.progress_bar.setValue(0) self.progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) pbar_hbox.addLayout(hbox) pbar_hbox.addWidget(self.progress_bar) pbar_frame.setLayout(pbar_hbox) process_layout.addWidget(pbar_frame) vbox = QVBoxLayout() vbox.setSpacing(8) vbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) process_layout.addLayout(vbox) hbox = QHBoxLayout() vbox.addLayout(hbox) check_name_label = QLabel("Check:") check_name_label.setFixedWidth(80) hbox.addWidget(check_name_label) self.check_name_text_label = QLabel("n/a") hbox.addWidget(self.check_name_text_label) hbox = QHBoxLayout() vbox.addLayout(hbox) status_name_label = QLabel("Status:") status_name_label.setFixedWidth(80) hbox.addWidget(status_name_label) self.status_name_text_label = QLabel("Not started") hbox.addWidget(self.status_name_text_label) self.warning_frame = QFrame() self.warning_frame.setVisible(False) self.warning_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() warning_icon_widget = qta.IconWidget('fa.warning', color='red') warning_icon_widget.setIconSize(QtCore.QSize(48, 48)) warning_icon_widget.update() hbox.addWidget(warning_icon_widget) warning_label = QLabel( "Grid Transformer did not complete successfully. Please refer to " "log output.") warning_label.setStyleSheet("QLabel { color: red; }") warning_label.setWordWrap(True) warning_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(warning_label) self.warning_frame.setLayout(hbox) process_layout.addWidget(self.warning_frame) self.success_frame = QFrame() self.success_frame.setVisible(False) self.success_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() success_icon_widget = qta.IconWidget('fa.check', color='green') success_icon_widget.setIconSize(QtCore.QSize(48, 48)) success_icon_widget.update() hbox.addWidget(success_icon_widget) success_label = QLabel("All checks completed successfully.") success_label.setStyleSheet("QLabel { color: green; }") success_label.setWordWrap(True) success_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(success_label) self.success_frame.setLayout(hbox) process_layout.addWidget(self.success_frame) log_layout = QVBoxLayout() log_layout.setSpacing(4) log_label = QLabel("Log messages") log_label.setStyleSheet("QLabel { color: grey; }") log_layout.addWidget(log_label) self.log_messages = QPlainTextEdit() log_font = QFont("monospace") log_font.setStyleHint(QFont.TypeWriter) self.log_messages.setFont(log_font) self.log_messages.setReadOnly(True) self.log_messages.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) log_layout.addWidget(self.log_messages) process_layout.addLayout(log_layout) self.vbox.addWidget(process_groupbox) def set_run_stop_buttons_enabled(self, is_running: bool) -> NoReturn: if is_running: self.run_button.setEnabled(False) self.stop_button.setEnabled(True) else: self.run_button.setEnabled(True) self.stop_button.setEnabled(False) def _log_message(self, message): self.log_messages.appendPlainText(message) def run_executor(self, check_executor: QtCheckExecutorThread): # we pass the check_executor into the run tab as this is where the UI # components are that will display the execution status. self.set_run_stop_buttons_enabled(True) self._log_message("Check execution started") self.start_time = time.perf_counter() self.check_executor = check_executor self.check_executor.options = self.get_options() self.check_executor.check_tool_started.connect( self._on_check_tool_started) self.check_executor.progress.connect(self._on_progress) self.check_executor.qajson_updated.connect(self._on_qajson_update) self.check_executor.checks_complete.connect(self._on_checks_complete) self.check_executor.status_changed.connect(self._on_status_change) self.check_executor.start() def get_options(self) -> Dict: ''' Gets a list of options based on user entered data. eg; the spatial output specifications. ''' return { CheckOption.spatial_output_qajson: self.qajson_spatial_checkbox.isChecked(), CheckOption.spatial_output_export: self.export_spatial_checkbox.isChecked(), CheckOption.spatial_output_export_location: self.output_folder_input.text() } def _click_run(self): self.run_checks.emit() def _click_stop(self): if self.check_executor is None: logger.warn("Check executor does not exist, cannot stop") return self._log_message("Stopping check execution") self.check_executor.stop() @QtCore.Slot(float) def _on_progress(self, progress): self.progress_bar.setValue(int(progress * 100)) @QtCore.Slot() def _on_qajson_update(self): self.prj.qa_json = self.check_executor.qa_json @QtCore.Slot(object) def _on_check_tool_started(self, tpl): check_tool_name, check_number, total_check_count = tpl self.check_name_text_label.setText("{} ({}/{})".format( check_tool_name, check_number, total_check_count)) @QtCore.Slot() def _on_checks_complete(self): run_time = time.perf_counter() - self.start_time self._log_message( f"Execution time for all checks = {run_time:.2f} sec") self._log_message("\n\n") self.set_run_stop_buttons_enabled(False) self.prj.qa_json = self.check_executor.qa_json @QtCore.Slot(str) def _on_status_change(self, status): self.status_name_text_label.setText(status)
def initDrawButtons(self, flags): self.drawButtonGroup = QButtonGroup(self) # draw action buttons if flags & constant.RECT: self.rectButton = QPushButton(self) self.rectButton.setIcon(QIcon(":/resource/icon/rect.png")) self.rectButton.setFixedSize(self.iconWidth, self.iconHeight) self.rectButton.setCheckable(True) self.drawButtonGroup.addButton(self.rectButton) self.hlayout.addWidget(self.rectButton) self.button_list.append(self.rectButton) if flags & constant.ELLIPSE: self.ellipseButton = QPushButton(self) self.ellipseButton.setIcon(QIcon(":/resource/icon/ellipse.png")) self.ellipseButton.setFixedSize(self.iconWidth, self.iconHeight) self.ellipseButton.setCheckable(True) self.drawButtonGroup.addButton(self.ellipseButton) self.hlayout.addWidget(self.ellipseButton) self.button_list.append(self.ellipseButton) if flags & constant.ARROW: self.arrowButton = QPushButton(self) self.arrowButton.setIcon(QIcon(":/resource/icon/arrow.png")) self.arrowButton.setFixedSize(self.iconWidth, self.iconHeight) self.arrowButton.setCheckable(True) self.drawButtonGroup.addButton(self.arrowButton) self.hlayout.addWidget(self.arrowButton) self.button_list.append(self.arrowButton) if flags & constant.LINE: self.lineButton = QPushButton(self) self.lineButton.setIcon(QIcon(":/resource/icon/line.png")) self.lineButton.setFixedSize(self.iconWidth, self.iconHeight) self.lineButton.setCheckable(True) self.drawButtonGroup.addButton(self.lineButton) self.hlayout.addWidget(self.lineButton) self.button_list.append(self.lineButton) if flags & constant.FREEPEN: self.freePenButton = QPushButton(self) self.freePenButton.setIcon(QIcon(":/resource/icon/pen.png")) self.freePenButton.setFixedSize(self.iconWidth, self.iconHeight) self.freePenButton.setCheckable(True) self.drawButtonGroup.addButton(self.freePenButton) self.hlayout.addWidget(self.freePenButton) self.button_list.append(self.freePenButton) if flags & constant.TEXT: self.textButton = QPushButton(self) self.textButton.setIcon(QIcon(":/resource/icon/text.png")) self.textButton.setFixedSize(self.iconWidth, self.iconHeight) self.textButton.setCheckable(True) self.drawButtonGroup.addButton(self.textButton) self.hlayout.addWidget(self.textButton) self.button_list.append(self.textButton) self.drawButtonGroup.buttonClicked.connect(self.buttonToggled)
def __init__(self): super().__init__() btn = QPushButton("Dialog") btn.clicked.connect(self.on_click) self.setCentralWidget(btn)
def __init__(self): super().__init__() self.button = QPushButton("Push for Window") self.button.clicked.connect(self.show_new_window) self.setCentralWidget(self.button)
class QNotesWindow(QDialog): def __init__(self, game: Game): super(QNotesWindow, self).__init__() self.game = game self.setWindowTitle("Notes") self.setWindowIcon(CONST.ICONS["Notes"]) self.setMinimumSize(400, 100) self.resize(600, 450) self.vbox = QVBoxLayout() self.setLayout(self.vbox) self.vbox.addWidget( QLabel("Saved notes are available as a page in your kneeboard.") ) self.textbox = QPlainTextEdit(self) try: self.textbox.setPlainText(self.game.notes) self.textbox.moveCursor(QTextCursor.End) except AttributeError: # old save may not have game.notes pass self.textbox.move(10, 10) self.textbox.resize(600, 450) self.textbox.setStyleSheet("background: #1D2731;") self.vbox.addWidget(self.textbox) self.button_row = QHBoxLayout() self.vbox.addLayout(self.button_row) self.clear_button = QPushButton(self) self.clear_button.setText("CLEAR") self.clear_button.setProperty("style", "btn-primary") self.clear_button.clicked.connect(self.clearNotes) self.button_row.addWidget(self.clear_button) self.save_button = QPushButton(self) self.save_button.setText("SAVE") self.save_button.setProperty("style", "btn-success") self.save_button.clicked.connect(self.saveNotes) self.button_row.addWidget(self.save_button) def clearNotes(self) -> None: self.textbox.setPlainText("") def saveNotes(self) -> None: self.game.notes = self.textbox.toPlainText() self.save_button.setText("SAVED") QTimer.singleShot(5000, lambda: self.save_button.setText("SAVE"))
import sys from PySide2.QtWidgets import QApplication, QPushButton from PySide2.QtCore import Slot @Slot() def on_btn_click(): print('Button clicked') #print(sender()) #print(self.ui.plainTextEdit.toPlainText()) #print(self.my_text.toPlainText()) if __name__ == '__main__': app = QApplication( []) # can use sys.argv in place of [] for command line arguments button = QPushButton('Click me') button.clicked.connect(on_btn_click) button.show() sys.exit(app.exec_()) # run the app until closed
class IpInformation(QWidget): def __init__(self): super(IpInformation, self).__init__() # Use language settings self.ml = ManageLng() main_layout = QGridLayout() self.setLayout(main_layout) # Prefix-mask-conversion group box self.prefix_mask_box = QGroupBox( self.ml.get_tr_text("tab_ip_information_prefix_mask_conv")) self.prefix_mask_box.setMaximumHeight(90) main_layout.addWidget(self.prefix_mask_box, 0, 0) prefix_mask_box_layout = QGridLayout() prefix_mask_box_layout.setContentsMargins(200, 20, 200, 20) prefix_mask_box_layout.setHorizontalSpacing(30) self.prefix_mask_box.setLayout(prefix_mask_box_layout) self.prefix_input = QLineEdit() self.prefix_input.setMaxLength(3) self.prefix_input.setAlignment(Qt.AlignCenter) self.prefix_input.setPlaceholderText( self.ml.get_tr_text("tab_ip_information_prefix_ptext")) prefix_mask_box_layout.addWidget(self.prefix_input, 0, 0) self.mask_input = QLineEdit() self.mask_input.setMaxLength(15) self.mask_input.setAlignment(Qt.AlignCenter) self.mask_input.setPlaceholderText( self.ml.get_tr_text("tab_ip_information_mask_ptext")) prefix_mask_box_layout.addWidget(self.mask_input, 0, 1) self.convert_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_conv_btn")) self.convert_btn.setIcon(QIcon("static/images/exchange.png")) self.convert_btn.clicked.connect(self.convert_action) self.prefix_input.returnPressed.connect(self.convert_action) self.mask_input.returnPressed.connect(self.convert_action) prefix_mask_box_layout.addWidget(self.convert_btn, 0, 2, alignment=Qt.AlignLeft) # IP information group box self.ip_information_box = QGroupBox( self.ml.get_tr_text("tab_ip_information_ipinfo_gbox")) main_layout.addWidget(self.ip_information_box, 1, 0) ip_information_box_layout = QGridLayout() ip_information_box_layout.setContentsMargins(80, 80, 80, 80) ip_information_box_layout.setHorizontalSpacing(30) ip_information_box_layout.setVerticalSpacing(15) self.ip_information_box.setLayout(ip_information_box_layout) self.ip_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_ipadd_lab")) ip_information_box_layout.addWidget(self.ip_address_label, 0, 0, alignment=Qt.AlignCenter) self.ip_address_textfield = QLineEdit() self.ip_address_textfield.setPlaceholderText("192.168.1.100/24") self.ip_address_textfield.setAlignment(Qt.AlignCenter) self.ip_address_textfield.setMaxLength(18) ip_information_box_layout.addWidget(self.ip_address_textfield, 0, 1) self.get_info_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_getinfo_btn")) self.get_info_btn.setIcon(QIcon("static/images/get_info.png")) self.get_info_btn.clicked.connect(self.get_info_action) self.ip_address_textfield.returnPressed.connect(self.get_info_action) ip_information_box_layout.addWidget(self.get_info_btn, 0, 2) self.ip_class_label = QLabel( self.ml.get_tr_text("tab_ip_information_ipclass_lab")) ip_information_box_layout.addWidget(self.ip_class_label, 1, 0, alignment=Qt.AlignCenter) self.ip_class_textfield = QLineEdit() self.ip_class_textfield.setReadOnly(True) self.ip_class_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.ip_class_textfield, 1, 1) self.ip_class_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.ip_class_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.ip_class_copy_btn.clicked.connect( lambda: copy_action(self.ip_class_textfield.text())) ip_information_box_layout.addWidget(self.ip_class_copy_btn, 1, 2) self.ip_type_label = QLabel( self.ml.get_tr_text("tab_ip_information_iptype_lab")) ip_information_box_layout.addWidget(self.ip_type_label, 2, 0, alignment=Qt.AlignCenter) self.ip_type_textfield = QLineEdit() self.ip_type_textfield.setReadOnly(True) self.ip_type_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.ip_type_textfield, 2, 1) self.ip_type_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.ip_type_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.ip_type_copy_btn.clicked.connect( lambda: copy_action(self.ip_type_textfield.text())) ip_information_box_layout.addWidget(self.ip_type_copy_btn, 2, 2) self.network_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_netadd_lab")) ip_information_box_layout.addWidget(self.network_address_label, 3, 0, alignment=Qt.AlignCenter) self.network_address_textfield = QLineEdit() self.network_address_textfield.setReadOnly(True) self.network_address_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.network_address_textfield, 3, 1) self.network_address_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.network_address_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.network_address_copy_btn.clicked.connect( lambda: copy_action(self.network_address_textfield.text())) ip_information_box_layout.addWidget(self.network_address_copy_btn, 3, 2) self.subnet_mask_label = QLabel( self.ml.get_tr_text("tab_ip_information_mask_lab")) ip_information_box_layout.addWidget(self.subnet_mask_label, 4, 0, alignment=Qt.AlignCenter) self.subnet_mask_textfield = QLineEdit() self.subnet_mask_textfield.setReadOnly(True) self.subnet_mask_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.subnet_mask_textfield, 4, 1) self.subnet_mask_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.subnet_mask_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.subnet_mask_copy_btn.clicked.connect( lambda: copy_action(self.subnet_mask_textfield.text())) ip_information_box_layout.addWidget(self.subnet_mask_copy_btn, 4, 2) self.first_addressable_ip_label = QLabel( self.ml.get_tr_text("tab_ip_information_firstip_lab")) ip_information_box_layout.addWidget(self.first_addressable_ip_label, 5, 0, alignment=Qt.AlignCenter) self.first_addressable_ip_textfield = QLineEdit() self.first_addressable_ip_textfield.setReadOnly(True) self.first_addressable_ip_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget( self.first_addressable_ip_textfield, 5, 1) self.first_addressable_ip_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.first_addressable_ip_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.first_addressable_ip_copy_btn.clicked.connect( lambda: copy_action(self.first_addressable_ip_textfield.text())) ip_information_box_layout.addWidget(self.first_addressable_ip_copy_btn, 5, 2) self.last_addressable_ip_label = QLabel( self.ml.get_tr_text("tab_ip_information_lastip_lab")) ip_information_box_layout.addWidget(self.last_addressable_ip_label, 6, 0, alignment=Qt.AlignCenter) self.last_addressable_ip_textfield = QLineEdit() self.last_addressable_ip_textfield.setReadOnly(True) self.last_addressable_ip_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.last_addressable_ip_textfield, 6, 1) self.last_addressable_ip_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.last_addressable_ip_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.last_addressable_ip_copy_btn.clicked.connect( lambda: copy_action(self.last_addressable_ip_textfield.text())) ip_information_box_layout.addWidget(self.last_addressable_ip_copy_btn, 6, 2) self.broadcast_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_bcastip_lab")) ip_information_box_layout.addWidget(self.broadcast_address_label, 7, 0, alignment=Qt.AlignCenter) self.broadcast_address_textfield = QLineEdit() self.broadcast_address_textfield.setReadOnly(True) self.broadcast_address_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.broadcast_address_textfield, 7, 1) self.broadcast_address_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.broadcast_address_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.broadcast_address_copy_btn.clicked.connect( lambda: copy_action(self.broadcast_address_textfield.text())) ip_information_box_layout.addWidget(self.broadcast_address_copy_btn, 7, 2) self.next_network_address_label = QLabel( self.ml.get_tr_text("tab_ip_information_nextnetip_lab")) ip_information_box_layout.addWidget(self.next_network_address_label, 8, 0, alignment=Qt.AlignCenter) self.next_network_address_textfield = QLineEdit() self.next_network_address_textfield.setReadOnly(True) self.next_network_address_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget( self.next_network_address_textfield, 8, 1) self.next_network_address_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.next_network_address_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.next_network_address_copy_btn.clicked.connect( lambda: copy_action(self.next_network_address_textfield.text())) ip_information_box_layout.addWidget(self.next_network_address_copy_btn, 8, 2) self.max_endpoint_label = QLabel( self.ml.get_tr_text("tab_ip_information_maxend_lab")) ip_information_box_layout.addWidget(self.max_endpoint_label, 9, 0, alignment=Qt.AlignCenter) self.max_endpoint_textfield = QLineEdit() self.max_endpoint_textfield.setReadOnly(True) self.max_endpoint_textfield.setAlignment(Qt.AlignCenter) ip_information_box_layout.addWidget(self.max_endpoint_textfield, 9, 1) self.max_endpoint_copy_btn = QPushButton( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.max_endpoint_copy_btn.setIcon( QIcon("static/images/copy_clipboard.png")) self.max_endpoint_copy_btn.clicked.connect( lambda: copy_action(self.max_endpoint_textfield.text())) ip_information_box_layout.addWidget(self.max_endpoint_copy_btn, 9, 2) def convert_action(self): if is_empty(self.prefix_input.text()) and \ is_empty(self.mask_input.text()): PopupWindow("warning", self.ml.get_tr_text("tab_ip_information_warning01"), self.prefix_input) elif not is_empty(self.prefix_input.text()) and \ not is_empty(self.mask_input.text()): if is_correct_prefix(self.prefix_input.text()): prefix_corrected = self.prefix_input.text().replace( "/", "").replace("\\", "") self.mask_input.setText(get_mask_from_prefix(prefix_corrected)) else: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning02"), self.prefix_input) else: if self.prefix_input.text(): if is_correct_prefix(self.prefix_input.text()): prefix_corrected = self.prefix_input.text().replace( "/", "").replace("\\", "") self.mask_input.setText( get_mask_from_prefix(prefix_corrected)) else: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning02"), self.prefix_input) else: if is_correct_mask(self.mask_input.text()): self.prefix_input.setText( f"/{get_prefix_from_mask(self.mask_input.text())}") else: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning03"), self.mask_input) def get_info_action(self): if is_empty(self.ip_address_textfield.text()): PopupWindow("warning", self.ml.get_tr_text("tab_ip_information_warning04"), self.ip_address_textfield) elif is_correct_ip_with_prefix(self.ip_address_textfield.text()): ip = self.ip_address_textfield.text().split("/")[0] ip_first_octet = int(str(ip).split(".")[0]) prefix = self.ip_address_textfield.text().split("/")[1] if ip_first_octet == 127: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning05"), self.ip_address_textfield) elif 224 <= ip_first_octet <= 239: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning06"), self.ip_address_textfield) elif 240 <= ip_first_octet <= 254: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning07"), self.ip_address_textfield) elif ip_first_octet == 255: PopupWindow( "warning", self.ml.get_tr_text("tab_ip_information_warning08"), self.ip_address_textfield) else: self.ip_class_textfield.setText( self.ml.get_tr_text(get_ip_class(ip))) self.ip_type_textfield.setText( self.ml.get_tr_text(get_ip_type(ip, prefix))) self.network_address_textfield.setText( get_network_address(ip, prefix)) self.subnet_mask_textfield.setText( get_mask_from_prefix(prefix)) self.first_addressable_ip_textfield.setText( get_first_addressable_ip(ip, prefix)) self.last_addressable_ip_textfield.setText( get_last_addressable_ip(ip, prefix)) self.broadcast_address_textfield.setText( get_broadcast_ip(ip, prefix)) self.next_network_address_textfield.setText( get_next_network_ip(ip, prefix)) self.max_endpoint_textfield.setText( get_max_endpoint_formatted(prefix)) else: PopupWindow("warning", self.ml.get_tr_text("tab_ip_information_warning09"), self.ip_address_textfield) def re_translate_ui(self, lang): self.ml = ManageLng(lang) if self.ip_address_textfield.text(): ip = self.ip_address_textfield.text().split("/")[0] prefix = self.ip_address_textfield.text().split("/")[1] else: ip = None prefix = None self.prefix_mask_box.setTitle( self.ml.get_tr_text("tab_ip_information_prefix_mask_conv")) self.prefix_input.setPlaceholderText( self.ml.get_tr_text("tab_ip_information_prefix_ptext")) self.mask_input.setPlaceholderText( self.ml.get_tr_text("tab_ip_information_mask_ptext")) self.convert_btn.setText( self.ml.get_tr_text("tab_ip_information_conv_btn")) self.ip_information_box.setTitle( self.ml.get_tr_text("tab_ip_information_ipinfo_gbox")) self.ip_address_label.setText( self.ml.get_tr_text("tab_ip_information_ipadd_lab")) self.get_info_btn.setText( self.ml.get_tr_text("tab_ip_information_getinfo_btn")) self.ip_class_label.setText( self.ml.get_tr_text("tab_ip_information_ipclass_lab")) self.ip_class_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.ip_type_label.setText( self.ml.get_tr_text("tab_ip_information_iptype_lab")) self.ip_type_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.network_address_label.setText( self.ml.get_tr_text("tab_ip_information_netadd_lab")) self.network_address_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.subnet_mask_label.setText( self.ml.get_tr_text("tab_ip_information_mask_lab")) self.subnet_mask_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.first_addressable_ip_label.setText( self.ml.get_tr_text("tab_ip_information_firstip_lab")) self.first_addressable_ip_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.last_addressable_ip_label.setText( self.ml.get_tr_text("tab_ip_information_lastip_lab")) self.last_addressable_ip_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.broadcast_address_label.setText( self.ml.get_tr_text("tab_ip_information_bcastip_lab")) self.broadcast_address_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.next_network_address_label.setText( self.ml.get_tr_text("tab_ip_information_nextnetip_lab")) self.next_network_address_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) self.max_endpoint_label.setText( self.ml.get_tr_text("tab_ip_information_maxend_lab")) self.max_endpoint_copy_btn.setText( self.ml.get_tr_text("tab_ip_information_copy_btn")) if self.ip_class_textfield.text() and self.ip_type_textfield.text(): self.ip_class_textfield.setText( self.ml.get_tr_text(get_ip_class(ip))) self.ip_type_textfield.setText( self.ml.get_tr_text(get_ip_type(ip, prefix)))
class ToolBox(QVBoxLayout): sig = QtCore.Signal(object) listThread = None groupBoxThreadInfo = None threadvbox = None mode = None def __init__(self, mode, parentQWidget = None): QVBoxLayout.__init__(self) self.sig.connect(self.addThreadList) self.mode = mode self.sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) self.groupBoxSearch = QGroupBox() self.groupBoxSearch.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 4px; };") vboxSearch = QVBoxLayout() self.searchTitle = QLabel("Search Messages") vboxSearch.addWidget(self.searchTitle) self.searchHLayout = QHBoxLayout() self.editTextSearch = QTextEdit('') self.editTextSearch.setFixedSize(200,30) self.buttonSearch = QPushButton('Search') self.buttonSearch.setFixedSize(100,30) self.buttonSearch.clicked.connect(self.searchMsg) vboxSearch.addWidget(self.editTextSearch) self.searchHLayout.addWidget(self.buttonSearch) self.searchCursor = QLabel() self.searchHLayout.addWidget(self.searchCursor) vboxSearch.addLayout(self.searchHLayout) self.browseHLayout = QHBoxLayout() self.buttonLookUp = QPushButton('\u21e7') #Arrow up self.buttonLookUp.setFixedWidth(100) self.buttonLookUp.clicked.connect(self.moveToPrev) self.buttonLookDown = QPushButton('\u21e9') #Arrow down self.buttonLookDown.setFixedWidth(100) self.buttonLookDown.clicked.connect(self.moveToNext) self.browseHLayout.addWidget(self.buttonLookUp) self.browseHLayout.addWidget(self.buttonLookDown) vboxSearch.addLayout(self.browseHLayout) self.groupBoxSearch.setLayout(vboxSearch) self.addWidget(self.groupBoxSearch) self.groupBoxSearch.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.buttonHiddenLifelines = QPushButton('Show hidden life-lines') self.buttonHiddenLifelines.setFixedWidth(200) self.buttonHiddenLifelines.clicked.connect(self.showHiddenLifelines) self.addWidget(self.buttonHiddenLifelines) self.buttonHiddenMessages = QPushButton('Show hidden Messages') self.buttonHiddenMessages.setFixedWidth(200) self.buttonHiddenMessages.clicked.connect(self.showHiddenMessages) self.addWidget(self.buttonHiddenMessages) if const.mode_interactive == mode: self.buttonCapture = QPushButton('Capture') self.buttonCapture.setFixedWidth(200) self.buttonCapture.clicked.connect(self.notifyCapture) self.addWidget(self.buttonCapture) self.msgRcv = [] self.msgInfo = QLabel("Message Info.") self.groupBoxMessageInfo = QGroupBox() self.groupBoxMessageInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;") vbox = QVBoxLayout() vbox.addWidget(self.msgInfo) self.tableTime = QTableWidget(3,2) self.tableTime.setHorizontalHeaderLabels(['-','time']) self.tableTime.setColumnWidth(0,80) self.tableTime.setColumnWidth(1,150) vwidth = self.tableTime.verticalHeader().length() hwidth = self.tableTime.horizontalHeader().height() fwidth = self.tableTime.frameWidth() * 2 self.tableTime.setFixedHeight(vwidth + hwidth + fwidth) self.tableTime.horizontalHeader().setStretchLastSection(True) self.tableTime.setItem(0,0,QTableWidgetItem('begin')) self.tableTime.setItem(0,1,QTableWidgetItem(' - ')) self.tableTime.setItem(1,0,QTableWidgetItem('end')) self.tableTime.setItem(1,1,QTableWidgetItem(' - ')) self.tableTime.setItem(2,0,QTableWidgetItem('duration')) self.tableTime.setItem(2,1,QTableWidgetItem(' - ')) vbox.addWidget(self.tableTime) self.titleArg = QLabel('Argument List') vbox.addWidget(self.titleArg) max_arg_num = 10 self.tableArgs = QTableWidget(max_arg_num,2) self.tableArgs.setHorizontalHeaderLabels(['type','value']) for idx in range(0,max_arg_num): self.tableArgs.setItem(idx,0,QTableWidgetItem()) self.tableArgs.setItem(idx,1,QTableWidgetItem()) self.tableArgs.horizontalHeader().setStretchLastSection(True) vbox.addWidget(self.tableArgs) self.titleArg = QLabel('Return Value List') vbox.addWidget(self.titleArg) max_ret_num = 4 self.tableRet = QTableWidget(max_ret_num,2) self.tableRet.setHorizontalHeaderLabels(['type','value']) for idx in range(0,max_ret_num): self.tableRet.setItem(idx,0,QTableWidgetItem()) self.tableRet.setItem(idx,1,QTableWidgetItem()) self.tableRet.horizontalHeader().setStretchLastSection(True) vwidth = self.tableRet.verticalHeader().length() hwidth = self.tableRet.horizontalHeader().height() fwidth = self.tableRet.frameWidth() * 2 self.tableRet.setFixedHeight(vwidth + hwidth + fwidth) vbox.addWidget(self.tableRet) self.buttonSrcView = QPushButton('view code') self.buttonSrcView.setFixedWidth(200) self.buttonSrcView.clicked.connect(self.openSourceViewer) self.buttonHide = QPushButton('Hide') self.buttonHide.setFixedWidth(200) self.buttonHide.clicked.connect(self.notifyHide) self.buttonHideAllMsg = QPushButton('Hide All') self.buttonHideAllMsg.setFixedWidth(200) self.buttonHideAllMsg.clicked.connect(self.hideAllMsgNamedAsSelected) self.groupBoxMessageInfo.setLayout(vbox) self.checkHideCircular = QCheckBox('Hide Circular Messages') self.checkHideCircular.setCheckState(QtCore.Qt.Unchecked) self.checkHideCircular.stateChanged.connect(self.changeHideCircularMessage) self.addWidget(self.checkHideCircular) self.addWidget(self.groupBoxMessageInfo) self.groupBoxMessageInfo.setSizePolicy(self.sizePolicy) def reset(self): for idx in reversed(range(0,self.listThread.count())): self.listThread.takeItem(idx) def setMsgInfoMessage(self,msg): self.strMessage = msg def changeHideCircularMessage(self,state): if state == QtCore.Qt.Unchecked: self.diagramView.hideCircularChanged(False) elif state == QtCore.Qt.Checked: self.diagramView.hideCircularChanged(True) def setMsgInfoModule(self,module): self.strModule = module def updateSearchStatus(self,curr,number): self.searchCursor.setText("%d/%d" % (curr,number)) def connectSourceViewer(self,viewer): self.srcViewer = viewer def openSourceViewer(self): self.srcViewer.openViewer(self.strModule,self.strMessage) def setMessageInfoTime(self,begin,end,duration): self.tableTime.item(0,1).setText(begin) self.tableTime.item(1,1).setText(end) self.tableTime.item(2,1).setText(duration + ' msec') def setMessageInfoArg(self,listParam,listArg): # Clear the contents in the table max_arg_num = 10 for idx in range(0,max_arg_num): self.tableArgs.item(idx,0).setText('') self.tableArgs.item(idx,1).setText('') if listArg: for idx, text in enumerate(listArg): self.tableArgs.item(idx,1).setText(text) for idx, text in enumerate(listParam): self.tableArgs.item(idx,0).setText(text) else: for idx in range(0,self.tableArgs.rowCount()): self.tableArgs.item(idx,1).setText('') self.tableArgs.item(idx,0).setText('') def setMessageInfoRet(self,listRet): if listRet: for idx, text in enumerate(listRet): self.tableRet.item(idx,1).setText(text) else: for idx in range(0,self.tableRet.rowCount()): self.tableRet.item(idx,1).setText('') self.tableRet.item(idx,0).setText('') def notifyInteractiveStateChanged(self,state): if const.mode_interactive != self.mode: return if const.STATE_INTERACTIVE_CAPTURING == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Stop Capture') if const.STATE_INTERACTIVE_PROCESSING == state: self.buttonCapture.setEnabled(False) if const.STATE_INTERACTIVE_IDLE == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') if const.STATE_INTERACTIVE_RESET == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') elif const.STATE_INTERACTIVE_ACTIVE == state: self.buttonCapture.setEnabled(True) self.buttonCapture.setText('Capture') def setMessageInfo(self,info): self.msgInfo.setText(info) def setAvailable(self,threads): self.sig.emit(threads) def toggleThreadDisplay(self,item): print(self.listThread.currentRow()) #if item.isSelected(): # print(item.text() + " is selected") #else: # print(item.text() + " is not selected") self.diagramView.showThread(self.listThread.currentRow(),item.isSelected()) def hideAllMsgNamedAsSelected(self): self.diagramView.hideAllMessageSelected() def addThreadList(self,threads): if not self.groupBoxThreadInfo: self.groupBoxThreadInfo = QGroupBox() self.threadInfo = QLabel("Thread Info.") self.groupBoxThreadInfo.setStyleSheet("QGroupBox {border: 1px solid gray; border-radius: 9px; margin-top: 0.5em} QGroupBox::title {subcontrol-origin: margin; left: 10px; padding: 0 3px 0 3px;") if not self.threadvbox: self.threadvbox = QVBoxLayout() if not self.listThread: self.listThread = QListWidget() self.listThread.setFixedWidth(200) self.listThread.setSelectionMode(QAbstractItemView.MultiSelection) QtCore.QObject.connect(self.listThread, QtCore.SIGNAL("itemClicked(QListWidgetItem *)"), self.toggleThreadDisplay) self.threadvbox.addWidget(self.threadInfo) self.threadvbox.addWidget(self.listThread) self.groupBoxThreadInfo.setLayout(self.threadvbox) self.addWidget(self.groupBoxThreadInfo) self.groupBoxThreadInfo.setSizePolicy(self.sizePolicy) for id in threads: item = QListWidgetItem(id) self.listThread.addItem(item) def connectController(self,controller): self.controller = controller self.connect(controller,QtCore.SIGNAL('setAvailable()'),self.setAvailable) def connectDiagramView(self,view): self.diagramView = view def disconnectMsgRcv(self,receiver): print("Implement this method !!! disconnectMsgRcv") def connectMsgRcv(self,receiver): self.msgRcv.append(receiver) def notifyHide(self): for rcv in self.msgRcv: rcv.activateHide(True) def showHiddenLifelines(self): response, selected_items = HiddenDialog.HiddenDialog.getSelectedItems(self.diagramView.getHiddenLifeLines()) if response: self.diagramView.showLifelines(selected_items) def showHiddenMessages(self): response, selected_items = HiddenMessageDialog.HiddenMessageDialog.getSelectedItems(self.diagramView.getHiddenMessages(),self.diagramView.getHiddenLifeLines()) if response: if selected_items[3] in self.diagramView.getHiddenLifeLines(): confirmation = ShowLifeLineDialog.ShowLifeLineDialog.confirmToShowLifeLine(selected_items[3]) if confirmation: self.diagramView.showLifelines([selected_items[3]]) self.diagramView.showMessages(selected_items) else: self.diagramView.showMessages(selected_items) def notifyCapture(self): for rcv in self.msgRcv: rcv.activateCapture(True) def moveToPrev(self): for rcv in self.msgRcv: rcv.moveToPrev() def moveToNext(self): for rcv in self.msgRcv: rcv.moveToNext() def searchMsg(self): str = self.editTextSearch.toPlainText() for rcv in self.msgRcv: rcv.searchMessage(str)
info = textEdit.toPlainText() salary_above_20k = '' salary_below_20k = '' for line in info.splitlines(): if not line.strip(): continue parts = line.split(' ') name, salary, age = parts app = QApplication([]) window = QMainWindow() window.resize(500, 400) window.move(300, 310) window.setWindowTitle("薪资统计") textEdit = QPlainTextEdit(window) textEdit.setPlaceholderText("请输入薪资表") textEdit.move(10, 25) textEdit.resize(300, 340) button = QPushButton('统计', window) button.move(360, 160) # Slot button.clicked.connect(handCalc()) window.show() app.exec_()
def __init__(self, parent=None): QPushButton.__init__(self, parent) self._painted = False
class MyToolBar(QWidget): """ ToolBar widget """ # signal trigger = Signal(int) def __init__(self, flags, parent=None): super(MyToolBar, self).__init__(parent) self.setWindowFlags(Qt.ToolTip) self.paddingX = 5 self.paddingY = 2 self.iconWidth = self.iconHeight = 28 self.setFixedHeight(self.iconHeight + 2 * self.paddingY) # self.setFixedWidth(300) self.rectButton = None self.ellipseButton = None self.arrowButton = None self.lineButton = None self.freePenButton = None self.textButton = None self.undoButton = None self.cancelButton = None self.okButton = None self.saveButton = None self.button_list = [] self.initWindow(flags) def initDrawButtons(self, flags): self.drawButtonGroup = QButtonGroup(self) # draw action buttons if flags & constant.RECT: self.rectButton = QPushButton(self) self.rectButton.setIcon(QIcon(":/resource/icon/rect.png")) self.rectButton.setFixedSize(self.iconWidth, self.iconHeight) self.rectButton.setCheckable(True) self.drawButtonGroup.addButton(self.rectButton) self.hlayout.addWidget(self.rectButton) self.button_list.append(self.rectButton) if flags & constant.ELLIPSE: self.ellipseButton = QPushButton(self) self.ellipseButton.setIcon(QIcon(":/resource/icon/ellipse.png")) self.ellipseButton.setFixedSize(self.iconWidth, self.iconHeight) self.ellipseButton.setCheckable(True) self.drawButtonGroup.addButton(self.ellipseButton) self.hlayout.addWidget(self.ellipseButton) self.button_list.append(self.ellipseButton) if flags & constant.ARROW: self.arrowButton = QPushButton(self) self.arrowButton.setIcon(QIcon(":/resource/icon/arrow.png")) self.arrowButton.setFixedSize(self.iconWidth, self.iconHeight) self.arrowButton.setCheckable(True) self.drawButtonGroup.addButton(self.arrowButton) self.hlayout.addWidget(self.arrowButton) self.button_list.append(self.arrowButton) if flags & constant.LINE: self.lineButton = QPushButton(self) self.lineButton.setIcon(QIcon(":/resource/icon/line.png")) self.lineButton.setFixedSize(self.iconWidth, self.iconHeight) self.lineButton.setCheckable(True) self.drawButtonGroup.addButton(self.lineButton) self.hlayout.addWidget(self.lineButton) self.button_list.append(self.lineButton) if flags & constant.FREEPEN: self.freePenButton = QPushButton(self) self.freePenButton.setIcon(QIcon(":/resource/icon/pen.png")) self.freePenButton.setFixedSize(self.iconWidth, self.iconHeight) self.freePenButton.setCheckable(True) self.drawButtonGroup.addButton(self.freePenButton) self.hlayout.addWidget(self.freePenButton) self.button_list.append(self.freePenButton) if flags & constant.TEXT: self.textButton = QPushButton(self) self.textButton.setIcon(QIcon(":/resource/icon/text.png")) self.textButton.setFixedSize(self.iconWidth, self.iconHeight) self.textButton.setCheckable(True) self.drawButtonGroup.addButton(self.textButton) self.hlayout.addWidget(self.textButton) self.button_list.append(self.textButton) self.drawButtonGroup.buttonClicked.connect(self.buttonToggled) def initOtherButtons(self, flags): # other action buttons if len(self.button_list) != 0: self.separator1 = QFrame(self) self.separator1.setFrameShape(QFrame.VLine) self.separator1.setFrameShadow(QFrame.Sunken) self.hlayout.addWidget(self.separator1) self.undoButton = QPushButton(self) self.undoButton.setIcon(QIcon(":/resource/icon/undo.png")) self.undoButton.setFixedSize(self.iconWidth, self.iconWidth) self.undoButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.undoButton) if flags & constant.SAVE_TO_FILE: self.saveButton = QPushButton(self) self.saveButton.setIcon(QIcon(":/resource/icon/save.png")) self.saveButton.setFixedSize(self.iconWidth, self.iconHeight) self.saveButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.saveButton) self.separator2 = QFrame(self) self.separator2.setFrameShape(QFrame.VLine) self.separator2.setFrameShadow(QFrame.Sunken) self.hlayout.addWidget(self.separator2) self.cancelButton = QPushButton(self) self.cancelButton.setIcon(QIcon(":/resource/icon/close.png")) self.cancelButton.setFixedSize(self.iconWidth, self.iconHeight) self.cancelButton.clicked.connect(self.otherButtonsClicked) if flags & constant.CLIPBOARD: self.okButton = QPushButton(self) self.okButton.setIcon(QIcon(":/resource/icon/check.png")) self.okButton.setFixedSize(self.iconWidth, self.iconHeight) self.okButton.clicked.connect(self.otherButtonsClicked) self.hlayout.addWidget(self.okButton) self.hlayout.addWidget(self.cancelButton) def initWindow(self, flags): self.hlayout = QHBoxLayout() self.hlayout.setSpacing(2) self.hlayout.setContentsMargins(10, 2, 10, 2) self.setLayout(self.hlayout) self.initDrawButtons(flags) self.initOtherButtons(flags) # slots def buttonToggled(self, button): """ :type button: QPushButton :param button: :return: """ if button == self.rectButton: self.trigger.emit(ACTION_RECT) elif button == self.ellipseButton: self.trigger.emit(ACTION_ELLIPSE) elif button == self.arrowButton: self.trigger.emit(ACTION_ARROW) elif button == self.lineButton: self.trigger.emit(ACTION_LINE) elif button == self.freePenButton: self.trigger.emit(ACTION_FREEPEN) elif button == self.textButton: self.trigger.emit(ACTION_TEXT) else: pass def otherButtonsClicked(self): if self.sender() == self.undoButton: self.trigger.emit(ACTION_UNDO) elif self.sender() == self.cancelButton: self.trigger.emit(ACTION_CANCEL) elif self.sender() == self.okButton: self.trigger.emit(ACTION_SURE) elif self.sender() == self.saveButton: self.trigger.emit(ACTION_SAVE)