def load_ui(self): loader = QUiLoader() path = os.fspath(Path(__file__).resolve().parent / "form.ui") ui_file = QFile(path) ui_file.open(QFile.ReadOnly) loader.load(ui_file, self) ui_file.close()
def __init__(self): self.operator = "" self.text = "" self.text2 = "" self.op2 = "" self.text3 = "" super(main, self).__init__() loader = QUiLoader() self.ui = loader.load('GraphicCalculator.ui', None) self.ui.show() self.ui.label.setText("") self.ui.pushButton.clicked.connect(partial(self.method_num, "1")) self.ui.pushButton_2.clicked.connect(partial(self.method_num, "2")) self.ui.pushButton_3.clicked.connect(partial(self.method_num, "3")) self.ui.pushButton_4.clicked.connect(partial(self.method_num, "4")) self.ui.pushButton_5.clicked.connect(partial(self.method_num, "5")) self.ui.pushButton_6.clicked.connect(partial(self.method_num, "6")) self.ui.pushButton_7.clicked.connect(partial(self.method_num, "7")) self.ui.pushButton_8.clicked.connect(partial(self.method_num, "8")) self.ui.pushButton_9.clicked.connect(partial(self.method_num, "9")) self.ui.pushButton_zero.clicked.connect(partial(self.method_num, "0")) self.ui.pushButton_dot.clicked.connect(partial(self.method_num, ".")) self.ui.pushButton_answer.clicked.connect(self.method_answer) self.ui.pushButton_pluse.clicked.connect(partial(self.method_op, "+")) self.ui.pushButton_minus.clicked.connect(partial(self.method_op, "-")) self.ui.pushButton_multiple.clicked.connect( partial(self.method_op, "*")) self.ui.pushButton_devide.clicked.connect(partial(self.method_op, "/")) self.ui.pushButton_power.clicked.connect(partial(self.method_op, "**")) self.ui.pushButton_sin.clicked.connect(self.method_sin) self.ui.pushButton_cos.clicked.connect(self.method_cos) self.ui.pushButton_tan.clicked.connect(self.method_tan) self.ui.pushButton_clear.clicked.connect(self.method_clear) self.ui.pushButton_del.clicked.connect(self.method_delete)
def __init__(self): super(Main, self).__init__() loader = QUiLoader() self.ui = loader.load('Assignment19/Alarms and Clock/form.ui') self.ui.setWindowIcon(QtGui.QIcon('Assignment19/Alarms and Clock/assets/img/icon.png')) self.ui.show() #----------------------------------- STOP WATCH UI -------------------------------------- self.ui.btn_stopwatch_start.clicked.connect(self.startStopWatch) self.ui.btn_stopwatch_save.clicked.connect(self.saveStopWatch) self.ui.btn_stopwatch_stop.clicked.connect(self.stopStopWatch) self.ui.btn_add_timer.clicked.connect(self.addTimer) self.ui.btn_add_timer.setIcon(QIcon('Assignment19/Alarms and Clock/assets/img/add.png')) self.ui.btn_stopwatch_start.setIcon(QIcon('Assignment19/Alarms and Clock/assets/img/play.png')) self.ui.btn_stopwatch_stop.setIcon(QIcon('Assignment19/Alarms and Clock/assets/img/pause.png')) self.ui.btn_stopwatch_save.setIcon(QIcon('Assignment19/Alarms and Clock/assets/img/flag.png')) self.stopwatch = Stopwatch() self.length_stw = 0 #-------------------------------------- TIMER UI ---------------------------------------- self.ui.timer_btn_start.clicked.connect(self.resumeTimer) self.ui.timer_btn_pause.clicked.connect(self.pauseTimer) self.ui.timer_btn_del.clicked.connect(self.stopTimer) self.ui.timer_btn_start.setIcon(QIcon('Assignment19/Alarms and Clock/assets/img/play.png')) self.ui.timer_btn_pause.setIcon(QIcon('Assignment19/Alarms and Clock/assets/img/pause.png')) self.ui.timer_btn_del.setText('×') #-------------------------------------- ALARM UI ---------------------------------------- self.ui.btn_alarm_set.clicked.connect(self.setAlarm) self.alarmOn = False
def __init__(self): super(mainwindow, self).__init__() loader = QUiLoader() self.ui = loader.load('form.ui') self.ui.show() self.a = '' self.b = '' self.op = '' self.op2 = '' self.ui.sum.clicked.connect(self.sum) self.ui.sub.clicked.connect(self.sub) self.ui.mul.clicked.connect(self.mul) self.ui.div.clicked.connect(self.div) self.ui.equal.clicked.connect(self.equal) self.ui.clear.clicked.connect(self.clear) self.ui.btn_dot.clicked.connect(self.dot) self.ui.negative.clicked.connect(self.negative) self.ui.percent.clicked.connect(self.percent) self.ui.btn_1.clicked.connect(self.num1) self.ui.btn_2.clicked.connect(self.num2) self.ui.btn_3.clicked.connect(self.num3) self.ui.btn_4.clicked.connect(self.num4) self.ui.btn_5.clicked.connect(self.num5) self.ui.btn_6.clicked.connect(self.num6) self.ui.btn_7.clicked.connect(self.num7) self.ui.btn_8.clicked.connect(self.num8) self.ui.btn_9.clicked.connect(self.num9) self.ui.btn_0.clicked.connect(self.num0)
def __init__(self): super(Main, self).__init__() loader = QUiLoader() self.ui = loader.load('Assignment16/RemoveLineBreaks/form.ui') self.ui.show() self.ui.btn_remove.clicked.connect(self.removeLineBreaks) self.ui.btn_reset.clicked.connect(self.reset)
def __init__(self): super(MainWindow, self).__init__() loader = QUiLoader() self.ui = loader.load('dialog.ui') self.ui.show() #Operators self.ui.btn_sub.clicked.connect(self.sub) self.ui.btn_sum.clicked.connect(self.sum) self.ui.btn_mul.clicked.connect(self.mul) self.ui.btn_div.clicked.connect(self.div) self.ui.btn_power.clicked.connect(self.power) self.ui.btn_point.clicked.connect(self.point) self.ui.btn_clear.clicked.connect(self.clear) self.ui.btn_percent.clicked.connect(self.percent) self.ui.btn.clicked.connect(self.btn) self.ui.btn_equal.clicked.connect(self.equal) #numbers self.ui.number1.clicked.connect(self.number_1) self.ui.number2.clicked.connect(self.number_2) self.ui.number3.clicked.connect(self.number_3) self.ui.number4.clicked.connect(self.number_4) self.ui.number5.clicked.connect(self.number_5) self.ui.number6.clicked.connect(self.number_6) self.ui.number7.clicked.connect(self.number_7) self.ui.number8.clicked.connect(self.number_8) self.ui.number9.clicked.connect(self.number_9) self.ui.number0.clicked.connect(self.number_0)
def __init__(self): super(Main, self).__init__() loader = QUiLoader() self.ui = loader.load('Assignment16/RandomPasswordGenerator/form.ui') self.ui.show() self.ui.btn_generate.clicked.connect(self.GeneratePass) self.string = ''
def __init__(self): super(Main, self).__init__() loader = QUiLoader() self.ui = loader.load('Assignment17/Downloader/form.ui') self.ui.show() self.ui.btn_download.clicked.connect(self.download) self.ui.btn_browse.clicked.connect(self.browse_file)
def load_ui(ui_file, parent=None): loader = QUiLoader() file = QFile(ui_file) file.open(QFile.ReadOnly) myWidget = loader.load(file, None) myWidget.show() file.close() myWidget.show() return myWidget
def __init__(self): super(Main, self).__init__() loader = QUiLoader() self.ui = loader.load('Assignment16/GuessNumber/form.ui') self.ui.show() self.ui.btn_guess.clicked.connect(self.guess) self.ui.btn_new.clicked.connect(self.new_game) self.number = random.randint(1, 20) self.score = 5 self.ui.lbl_joon.setText(str(self.score)) print(self.number)
def load_ui(name, custom_widgets=[], parent=None): loader = QUiLoader() for cw in custom_widgets: loader.registerCustomWidget(cw) path = resource_path(posixpath.join("ui", name)) ui_file = QFile(path) if not ui_file.open(QFile.ReadOnly): logger.error("Cannot open {}: {}".format(path, ui_file.errorString())) sys.exit(-1) ui = loader.load(ui_file, parent) ui_file.close() return ui
def load_ui(name, custom_widgets=[], parent=None): loader = QUiLoader() for cw in custom_widgets: loader.registerCustomWidget(cw) path = os.path.join(os.path.dirname(__file__), "ui", name) ui_file = QFile(path) if not ui_file.open(QFile.ReadOnly): logging.critical("Cannot open {}: {}".format(path, ui_file.errorString())) sys.exit(-1) ui = loader.load(ui_file, parent) ui_file.close() return ui
def __init__(self, parent=None): #load ui ui_file = QFile("mainwindow.ui") ui_file.open(QFile.ReadOnly) loader = QUiLoader() self.window = loader.load(ui_file) #init game self.gameInit() self.window.actionrule.triggered.connect(self.helpText) self.window.btnCheck.clicked.connect(self.CheckNum) self.window.btnRetry.clicked.connect(self.gameInit) self.window.show()
def __init__(self): super(Main, self).__init__() loader = QUiLoader() self.ui = loader.load('Assignment18/MessageBox/form.ui') self.ui.show() self.lightTheme = True self.ui.setWindowIcon(QtGui.QIcon('Assignment18/MessageBox/assets/img/icon.png')) self.ui.btn_light.setIcon(QIcon('Assignment18/MessageBox/assets/img/light_mode.png')) self.ui.btn_del_all.setIcon(QIcon('Assignment18/MessageBox/assets/img/delete.png')) self.ui.btn_send.clicked.connect(self.addNewMessage) self.ui.btn_del_all.clicked.connect(self.deleteAllMessage) self.ui.btn_light.clicked.connect(self.changeTheme) self.messages = self.readMessages() self.length = len(self.messages) self.ui.txt_message.installEventFilter(self)
def __init__(self): super().__init__() self.setGeometry(50, 50, 200, 200) self.setWindowTitle('Awesome File Manager') ui_file = QFile("mainwindow.ui") ui_file.open(QFile.ReadOnly) loader = QUiLoader() self.window = loader.load(ui_file) self.window.comboBox.setItemText(0, 'first filter') files = QFileDialog.getOpenFileNames(self) btn_file = QPushButton('Open', self) for file in files[0]: btn_file.clicked.connect(main(file))
def initUI(self, uiname, mode): # release mode # TODO: convert .ui to py code app = QApplication(sys.argv) # debug mode if mode == 'debug': ui_file_name = uiname ui_file = QFile(ui_file_name) if not ui_file.open(QIODevice.ReadOnly): print(f"Cannot open {ui_file_name}: {ui_file.errorString()}") sys.exit(-1) loader = QUiLoader() window = loader.load(ui_file) ui_file.close() if not window: print(loader.errorString()) sys.exit(-1) window.show() return app, window
def btnAboutSelected(self): ui_file = QtCore.QFile( os.path.join(self.data_folder, "ui", "winAbout.ui")) ui_file.open(QtCore.QFile.ReadOnly) loader = QUiLoader() dlgAbout = loader.load(ui_file, parentWidget=self) ui_file.close() dlgAbout.setWindowFlags(QtCore.Qt.Popup) dlgAbout.lblDescription.setText(Information.LongDescription) dlgAbout.lblRepoWebsite.setText(Information.RepoWebsite) dlgAbout.lblCopyright.setText(Information.Copyright) dlgAbout.lblVersion.setText("<b>Version:</b> " + Information.Version) dlgAbout.lblPyLotROReference.setText(Information.PyLotROReference) dlgAbout.lblCLIReference.setText(Information.CLIReference) dlgAbout.lblLotROLinuxReference.setText( Information.LotROLinuxReference) dlgAbout.exec_() self.resetFocus()
def __init__(self): super(MainWindow, self).__init__() loader = QUiLoader() path = os.path.join(os.path.dirname(__file__), "main_window.ui") ui_file = QFile(path) ui_file.open(QFile.ReadOnly) self.window = loader.load(ui_file, self) ui_file.close() self.week = 1 self.sel_block = (-1, -1) self.group = 'WCY18IJ5S1' self.blocks = list() self.loading_widget = None self.main_widget = self.window.findChild(QWidget, 'college_schedule') self.table_widget = self.window.findChild(QTableWidget, 'table_widget') self.next_week = self.window.findChild(QPushButton, 'next_week') self.previous_week = self.window.findChild(QPushButton, 'previous_week') self.save_note_button = self.window.findChild(QPushButton, 'save_note') self.group_box = self.window.findChild(QComboBox, 'group_box') self.download_button = self.window.findChild(QPushButton, 'download_data') self.note = self.window.findChild(QTextEdit, 'note') self.next_week.clicked.connect(lambda: self.get_week_click(self.week + 1)) self.previous_week.clicked.connect(lambda: self.get_week_click(self.week - 1)) self.save_note_button.clicked.connect(self.save_note_click) self.download_button.clicked.connect(lambda: self.load_data(True)) self.table_widget.cellClicked.connect(self.block_click) self.table_widget.cellDoubleClicked.connect(self.block_double_click) self.group_box.currentTextChanged.connect(self.group_change) self.loading_signal.connect(self.loading_slot) self.set_blocks_signal.connect(self.set_blocks_slot) self.scraper = Scraper() t = threading.Thread(target=lambda: self.scraper.start(self, self.group)) t.start()
def __init__(self): QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts) app = QApplication(sys.argv) app.setStyle(QStyleFactory.create('Fusion')) ui_file_name = '%s.ui' % Path(__file__).stem ui_file = QFile(ui_file_name) if not ui_file.open(QIODevice.ReadOnly): print('Cannot open %s: %s' % (ui_file_name, ui_file.errorString())) sys.exit(-1) loader = QUiLoader() self.window = loader.load(ui_file) ui_file.close() if not self.window: print(loader.errorString()) sys.exit(-1) self.connect() self.setting() self.window.show() sys.exit(app.exec())
class StepsData(QWidget): ui: QWidget loader: QUiLoader addStepsBtn: QPushButton removeStepBtn: QPushButton stepUpBtn: QPushButton stepDownBtn: QPushButton def __init__(self, parent: None | QWidget = None): super(StepsData, self).__init__(parent) self.load_ui() self.setup_ui() def load_ui(self): self.loader = QUiLoader(self) uifile = QFile(os.path.dirname(__file__) / Path("steps.ui")) self.ui = self.loader.load(uifile, parentWidget=self) uifile.close() self.setup_ui() def load_data(self): self.widgets: List[str] = self.loader.availableWidgets() self.layouts: List[str] = self.loader.availableLayouts() for widgetName in self.loader.availableWidgets(): self.loader.createWidget(widgetName, parent=self, name="") def setup_ui(self): if not self.objectName(): self.setObjectName(u"stepsListView") self.resize(400, 300) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setObjectName(u"verticalLayout") self.opsTabs = QTabWidget(self) self.opsTabs.setObjectName(u"opsTabs") self.opsTabs.setEnabled(True) self.opsTabs.setMaximumSize(QSize(410, 16777215)) self.stepsTab = QWidget() self.stepsTab.setObjectName(u"stepsTab") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.stepsTab.sizePolicy().hasHeightForWidth()) self.stepsTab.setSizePolicy(sizePolicy) self.stepsTab.setMinimumSize(QSize(200, 278)) self.stepsTab.setAutoFillBackground(False) self.verticalLayout_2 = QVBoxLayout(self.stepsTab) self.verticalLayout_2.setObjectName(u"verticalLayout_2") self.verticalLayout_2.setContentsMargins(-1, 11, -1, -1) self.stepsTreeWidget = QTreeWidget(self.stepsTab) self.stepsTreeWidget.setObjectName(u"stepsTreeWidget") self.verticalLayout_2.addWidget(self.stepsTreeWidget) self.horizontalLayout_3 = QHBoxLayout() self.horizontalLayout_3.setObjectName(u"horizontalLayout_3") self.stepDownBtn = QPushButton(self.stepsTab) self.stepDownBtn.setObjectName(u"stepDownBtn") self.horizontalLayout_3.addWidget(self.stepDownBtn) self.stepUpBtn = QPushButton(self.stepsTab) self.stepUpBtn.setObjectName(u"stepUpBtn") self.horizontalLayout_3.addWidget(self.stepUpBtn) self.removeStepBtn = QPushButton(self.stepsTab) self.removeStepBtn.setObjectName(u"removeStepBtn") self.horizontalLayout_3.addWidget(self.removeStepBtn) self.addStepBtn = QPushButton(self.stepsTab) self.addStepBtn.setObjectName(u"addStepBtn") self.horizontalLayout_3.addWidget(self.addStepBtn) self.runBtn = QPushButton(self.stepsTab) self.runBtn.setObjectName(u"runBtn") sizePolicy1 = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) sizePolicy1.setHorizontalStretch(0) sizePolicy1.setVerticalStretch(0) sizePolicy1.setHeightForWidth(self.runBtn.sizePolicy().hasHeightForWidth()) self.runBtn.setSizePolicy(sizePolicy1) self.runBtn.setMinimumSize(QSize(0, 0)) font = QFont() font.setBold(False) self.runBtn.setFont(font) self.runBtn.setCheckable(False) self.runBtn.setFlat(False) self.horizontalLayout_3.addWidget(self.runBtn) self.verticalLayout_2.addLayout(self.horizontalLayout_3) self.opsTabs.addTab(self.stepsTab, "") self.optionsTab = QWidget() self.optionsTab.setObjectName(u"optionsTab") self.optionsTab.setAutoFillBackground(True) self.verticalLayout_17 = QVBoxLayout(self.optionsTab) self.verticalLayout_17.setObjectName(u"verticalLayout_17") self.stepOptionsTreeWidget = QTreeWidget(self.optionsTab) __qtreewidgetitem = QTreeWidgetItem() __qtreewidgetitem.setText(0, r"1") self.stepOptionsTreeWidget.setHeaderItem(__qtreewidgetitem) self.stepOptionsTreeWidget.setObjectName(u"stepOptionsTreeWidget") self.verticalLayout_17.addWidget(self.stepOptionsTreeWidget) self.opsTabs.addTab(self.optionsTab, "") self.templatesTab = QWidget() self.templatesTab.setObjectName(u"templatesTab") self.verticalLayout_19 = QVBoxLayout(self.templatesTab) self.verticalLayout_19.setObjectName(u"verticalLayout_19") self.treeWidget = QTreeWidget(self.templatesTab) __qtreewidgetitem1 = QTreeWidgetItem() __qtreewidgetitem1.setText(0, r"1") self.treeWidget.setHeaderItem(__qtreewidgetitem1) self.treeWidget.setObjectName(u"treeWidget") self.verticalLayout_19.addWidget(self.treeWidget) self.opsTabs.addTab(self.templatesTab, "") self.verticalLayout.addWidget(self.opsTabs) # self.retranslateUi() self.opsTabs.setCurrentIndex(0) self.setWindowTitle("stepsListView") QMetaObject.connectSlotsByName(self) self.stepUpBtn.setText("Up") self.stepDownBtn.setText("Down")
def load_ui(ui_file): global loader if loader is None: loader = QUiLoader() return loader.load(ui_file, None)
def __init__(self, homeDir, osType, data_folder, QGuiApplication): self.homeDir = homeDir self.osType = osType ui_file = QtCore.QFile( os.path.join(data_folder, "ui", "winSetupWizard.ui") ) ui_file.open(QtCore.QFile.ReadOnly) loader = QUiLoader() self.winSetupWizard = loader.load(ui_file) ui_file.close() self.winSetupWizard.setWindowFlags(QtCore.Qt.Dialog) self.winSetupWizard.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.winSetupWizard.setWindowTitle("Setup Wizard") qr = self.winSetupWizard.frameGeometry() cp = QGuiApplication.primaryScreen().availableGeometry().center() qr.moveCenter(cp) self.winSetupWizard.move(qr.topLeft()) self.winSetupWizard.btnFindMenu = QtWidgets.QMenu() self.winSetupWizard.btnFindMenu.addAction( self.winSetupWizard.actionShowTest ) self.winSetupWizard.btnFindMenu.addAction( self.winSetupWizard.actionShowNormal ) self.winSetupWizard.actionShowTest.triggered.connect( self.actionShowTestSelected ) self.winSetupWizard.actionShowNormal.triggered.connect( self.actionShowNormalSelected ) self.winSetupWizard.btnFind.setMenu(self.winSetupWizard.btnFindMenu) self.winSetupWizard.btnFind_2.setMenu(self.winSetupWizard.btnFindMenu) self.winSetupWizard.btnFind.clicked.connect(self.btnFindClicked) self.winSetupWizard.btnFind_2.clicked.connect(self.btnFindClicked) self.winSetupWizard.btnGameDirLOTRO.clicked.connect( self.btnGameDirLOTROClicked ) self.winSetupWizard.btnGameDirDDO.clicked.connect( self.btnGameDirDDOClicked ) self.winSetupWizard.btnGameDirLOTROTest.clicked.connect( self.btnGameDirLOTROTestClicked ) self.winSetupWizard.btnGameDirDDOTest.clicked.connect( self.btnGameDirDDOTestClicked ) self.winSetupWizard.btnBoxIntro.rejected.connect(self.btnBoxRejected) self.winSetupWizard.btnBoxOptions.rejected.connect(self.btnBoxRejected) self.winSetupWizard.btnBoxOptions_2.rejected.connect( self.btnBoxRejected ) self.winSetupWizard.btnBoxIntro.accepted.connect( self.btnBoxIntroAccepted ) self.winSetupWizard.btnBoxOptions.button( QtWidgets.QDialogButtonBox.Apply ).clicked.connect(self.btnBoxOptionsApplied) self.winSetupWizard.btnBoxOptions_2.button( QtWidgets.QDialogButtonBox.Apply ).clicked.connect(self.btnBoxOptionsApplied)
def __init__(self): super().__init__() if getattr(sys, "frozen", False): # The application is frozen self.data_folder = os.path.dirname(sys.executable) else: self.data_folder = os.path.dirname(__file__) # Set default timeout used by urllib socket.setdefaulttimeout(6) ui_file = QtCore.QFile( os.path.join(self.data_folder, "ui", "winMain.ui")) # Create the main window and set all text so that translations are handled via gettext ui_file.open(QtCore.QFile.ReadOnly) loader = QUiLoader() self.winMain = loader.load(ui_file, parentWidget=self) ui_file.close() self.winMain.setWindowFlags(QtCore.Qt.Dialog) self.winMain.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.setWindowFlags(QtCore.Qt.FramelessWindowHint) self.setFixedSize(790, 470) # Set window style self.app.setStyleSheet(qdarkstyle.load_stylesheet_pyside2()) # Set font size explicitly to stop OS text size options from # breaking the UI. font = QtGui.QFont() font.setPointSize(10) self.app.setFont(font) # Temporary fix for qdarkstyle dropdown issue. # See https://github.com/ColinDuquesnoy/QDarkStyleSheet/issues/200 self.setStyleSheet(""" QComboBox::item:checked { height: 12px; border: 1px solid #32414B; margin-top: 0px; margin-bottom: 0px; padding: 4px; padding-left: 0px; } """) # center window on screen self.center() # Sets some widgets to WA_NoMousePropagation to avoid window dragging issues mouse_ignore_list = [ self.winMain.btnAbout, self.winMain.btnExit, self.winMain.btnLogin, self.winMain.btnMinimize, self.winMain.btnOptions, self.winMain.btnAddonManager, self.winMain.btnSwitchGame, self.winMain.cboWorld, self.winMain.chkSaveSettings, ] for widget in mouse_ignore_list: widget.setAttribute(QtCore.Qt.WA_NoMousePropagation) # Connect signals to functions self.winMain.btnLogin.clicked.connect(self.btnLoginClicked) self.winMain.cboAccount.textActivated.connect(self.cboAccountChanged) self.winMain.txtPassword.returnPressed.connect(self.txtPasswordEnter) self.winMain.btnExit.clicked.connect(self.close) self.winMain.btnMinimize.clicked.connect(self.showMinimized) self.winMain.btnAbout.clicked.connect(self.btnAboutSelected) self.winMain.btnLoginMenu = QtWidgets.QMenu() self.winMain.btnLoginMenu.addAction(self.winMain.actionPatch) self.winMain.actionPatch.triggered.connect(self.actionPatchSelected) self.winMain.btnLogin.setMenu(self.winMain.btnLoginMenu) self.winMain.btnOptions.setIcon( QtGui.QIcon( os.path.join(self.data_folder, "images", "SettingsGear.png"))) self.winMain.btnOptions.clicked.connect(self.btnOptionsSelected) self.winMain.btnAddonManager.setIcon( QtGui.QIcon( os.path.join(self.data_folder, "images", "AddonManager.png"))) self.winMain.btnAddonManager.clicked.connect( self.btnAddonManagerSelected) self.winMain.btnSwitchGame.clicked.connect(self.btnSwitchGameClicked) self.winMain.btnSwitchGameMenu = QtWidgets.QMenu() self.winMain.btnSwitchGameMenu.addAction(self.winMain.actionLOTROTest) self.winMain.actionLOTROTest.triggered.connect(self.SwitchToLOTROTest) self.winMain.btnSwitchGameMenu.addAction(self.winMain.actionDDOTest) self.winMain.actionDDOTest.triggered.connect(self.SwitchToDDOTest) self.winMain.btnSwitchGameMenu.addAction(self.winMain.actionLOTRO) self.winMain.actionLOTRO.triggered.connect(self.SwitchToLOTRO) self.winMain.btnSwitchGameMenu.addAction(self.winMain.actionDDO) self.winMain.actionDDO.triggered.connect(self.SwitchToDDO) self.winMain.btnSwitchGame.setMenu(self.winMain.btnSwitchGameMenu) self.ReturnLog = self.ReturnLog self.ReturnLog.connect(self.AddLog) self.ReturnBaseConfig = self.ReturnBaseConfig self.ReturnBaseConfig.connect(self.GetBaseConfig) self.ReturnGLSDataCenter = self.ReturnGLSDataCenter self.ReturnGLSDataCenter.connect(self.GetGLSDataCenter) self.ReturnWorldQueueConfig = self.ReturnWorldQueueConfig self.ReturnWorldQueueConfig.connect(self.GetWorldQueueConfig) self.ReturnNews = self.ReturnNews self.ReturnNews.connect(self.GetNews) # Disable login and save settings buttons self.winMain.btnLogin.setEnabled(False) self.winMain.chkSaveSettings.setEnabled(False) # Initialise variables self.settings = None self.osType = DetermineOS() self.gameType = DetermineGame() self.configFile = "" self.currentGame = None self.configureKeyring() self.InitialSetup(first_setup=True)
def AuthAccount(self): self.AddLog("Checking account details...") # Force a small display to ensure message above is displayed # as program can look like it is not responding while validating for _ in range(4): self.app.processEvents() self.account = AuthenticateUser( self.dataCenter.authServer, self.winMain.cboAccount.currentText(), self.winMain.txtPassword.text(), self.baseConfig.gameName, self.valHomeDir, self.osType, ) # don't keep password longer in memory than required if not self.winMain.chkSavePassword.isChecked(): self.winMain.txtPassword.clear() if self.account.authSuccess: self.AddLog("Account authenticated") if self.winMain.chkSaveSettings.isChecked(): current_account = self.winMain.cboAccount.currentText() # Test servers only have one world and shouldn't # overwrite world setting on normal servers if self.settings.currentGame.endswith(".Test"): world = self.settings.accountsDictionary[current_account][ 0] else: world = self.winMain.cboWorld.currentText() # Account is deleted first, because accounts are in order of # the most recently played at the end. try: del self.settings.accountsDictionary[current_account] except KeyError: pass self.settings.accountsDictionary[current_account] = [world] self.settings.SaveSettings( saveAccountDetails=self.winMain.chkSaveSettings.isChecked( ), savePassword=self.winMain.chkSavePassword.isChecked(), ) if self.winMain.chkSavePassword.isChecked(): if self.settings.currentGame.startswith("DDO"): keyring.set_password( "OneLauncherDDO", self.winMain.cboAccount.currentText(), self.winMain.txtPassword.text(), ) else: keyring.set_password( "OneLauncherLOTRO", self.winMain.cboAccount.currentText(), self.winMain.txtPassword.text(), ) else: try: if self.settings.currentGame.startswith("DDO"): keyring.delete_password( "OneLauncherDDO", self.winMain.cboAccount.currentText(), ) else: keyring.delete_password( "OneLauncherLOTRO", self.winMain.cboAccount.currentText(), ) except keyring.errors.PasswordDeleteError: pass tempWorld = "" if len(self.account.gameList) > 1: ui_file = QtCore.QFile( os.path.join(self.data_folder, "ui", "winSelectAccount.ui")) ui_file.open(QtCore.QFile.ReadOnly) loader = QUiLoader() dlgChooseAccount = loader.load(ui_file, parentWidget=self) ui_file.close() dlgChooseAccount.setWindowFlags(QtCore.Qt.Popup) dlgChooseAccount.lblMessage.setText( "Multiple game accounts found\n\nPlease select the required game" ) for game in self.account.gameList: dlgChooseAccount.comboBox.addItem(game.description) if dlgChooseAccount.exec_() == QtWidgets.QDialog.Accepted: self.accNumber = self.account.gameList[ dlgChooseAccount.comboBox.currentIndex()].name self.resetFocus() else: self.resetFocus() self.AddLog("No game selected - aborting") return else: self.accNumber = self.account.gameList[0].name tempWorld = self.dataCenter.worldList[ self.winMain.cboWorld.currentIndex()] tempWorld.CheckWorld(self.valHomeDir, self.osType) if tempWorld.worldAvailable: self.urlChatServer = tempWorld.urlChatServer self.urlLoginServer = tempWorld.loginServer if tempWorld.queueURL == "": self.LaunchGame() else: self.EnterWorldQueue(tempWorld.queueURL) else: self.AddLog( "[E10] Error getting world status. You may want to check " "the news feed for a scheduled down time.") else: self.AddLog(self.account.messError)
def create_dot_graph(root_ast, basic=False, scene=None, view=None, is_root=True, config=None): ''' Return a dot.AGraph item, from an ogAST.Process or child entry Set basic=True to generate a simple graph with at most one edge between two states and no diamond nodes is_root is set to False for nested diagrams ''' graph = dotgraph.AGraph(strict=False, directed=True) ret = {'graph': graph, 'children': {}, 'config': {}} diamond = 0 # Define the list of input signals including timers if is_root: input_signals = {sig['name'].lower() for sig in root_ast.input_signals} for each in root_ast.timers: input_signals.add(each) else: # set by recursive caller: input_signals = root_ast.all_signals # Add the Connect parts below nested states, and continuous signals for each in root_ast.content.states: for connect in each.connects: input_signals |= set(connect.connect_list) for cs in each.continuous_signals: LOG.debug("Continuous signal: " + cs.trigger.inputString) input_signals.add("[" + cs.trigger.inputString.strip() + "]") # valid_inputs: list of messages to be displayed in the statecharts # user can remove them from the file to make cleaner diagrams # config_params can be set to tune the call to graphviz valid_inputs = set() config_params = {} identifier = getattr(root_ast, "statename", root_ast.processName) #LOG.info("Statechart: rendering scene " + identifier) #LOG.info("Input signals from model: " + str (input_signals)) try: if not is_root: # Read config file only for the top-level diagram config_params = config # Adjust edge len for inner states. 1 is too small config_params["-Elen"] = "1.5" raise IOError with open(identifier + ".cfg", "r") as cfg_file: all_lines = (line.strip() for line in cfg_file.readlines()) for each in all_lines: split = each.split() if len(split) == 3 and split[0] == "cfg": config_params[split[1]] = split[2] elif each: valid_inputs.add(each.lower()) except IOError: valid_inputs = input_signals config_params = config_params or { "-Nfontsize": "14", "-Efontsize": "8", "-Gsplines": "curved", "-Gsep": "0.3", "-Gdpi": "72", "-Gstart": "random10", "-Goverlap": "scale", "-Nstyle": "rounded", "-Nshape": "record", "-Elen": "1" } LOG.info("... valid signals: " + ", ".join(valid_inputs)) else: LOG.info("Statechart settings read from " + identifier + ".cfg") LOG.info("... using signals: " + ", ".join(valid_inputs)) #LOG.debug(str(config_params)) if scene and view: # Load and display a table for the user to filter out messages that # are not relevant to display on the statechart - and make it lighter # Do not repeat for substates (view is None and no cfg is saved) lock() def right(leftList, rightList): for each in leftList.selectedItems(): item = leftList.takeItem(leftList.row(each)) rightList.addItem(item) def left(leftList, rightList): for each in rightList.selectedItems(): item = rightList.takeItem(rightList.row(each)) leftList.addItem(item) loader = QUiLoader() ui_file = QFile(":/statechart_cfg.ui") ui_file.open(QFile.ReadOnly) dialog = loader.load(ui_file) dialog.setParent(view, Qt.Dialog) okButton = dialog.findChild(QPushButton, "okButton") rightButton = dialog.findChild(QToolButton, "toRight") leftButton = dialog.findChild(QToolButton, "toLeft") rightList = dialog.findChild(QListWidget, "rightList") leftList = dialog.findChild(QListWidget, "leftList") okButton.pressed.connect(dialog.accept) rightButton.pressed.connect(partial(right, leftList, rightList)) leftButton.pressed.connect(partial(left, leftList, rightList)) ui_file.close() rightList.addItems(list(valid_inputs)) leftList.addItems(list(input_signals - valid_inputs)) go = dialog.exec() valid_inputs.clear() for idx in range(rightList.count()): valid_inputs.add(rightList.item(idx).text()) unlock() inputs_to_save = set(valid_inputs) for state in root_ast.mapping.keys(): # create a new node for each state (including nested states) if state.endswith('START'): if len(state) > 5: label = state[0:-6] else: label = '' graph.add_node(state, label=label, shape='point', fixedsize='true', width=10.0 / 72.0) else: # Find the path to the state, this is needed to be able to # highlight properly the parallel states in simulation for s in root_ast.content.states: if s.inputString.lower() == state.lower(): path = s.path break else: # Should never happen path = [] path_str = ".".join(elem.split()[1] for elem in path + [f"S {state}"] if not elem.startswith("PROCESS")) graph.add_node(state, label=state, comment=path_str, shape='record', style='rounded') for each in [ term for term in root_ast.terminators if term.kind == 'return' ]: # create a new node for each RETURN statement (in nested states) ident = each.inputString.lower() or ' ' graph.add_node( ident, label='X', #ident, (no, otherwise size isn't ok) shape='square', width=1.0 / 72.0) # the AST does not contain a mapping the Connect parts below a state # Create it here on the spot connect_mapping = defaultdict(list) for each in root_ast.content.states: for stateName in each.statelist: connect_mapping[stateName.lower()].extend(each.connects) for state, inputs in chain(root_ast.mapping.items(), root_ast.cs_mapping.items(), connect_mapping.items()): # Add edges transitions = \ inputs if not state.endswith('START') \ else [root_ast.transitions[inputs]] # Allow simplified graph, without diamonds and with at most one # transition from a given state to another target_states = defaultdict(set) for trans in transitions: source = state # transition label - there can be several inputs try: # Keep only message name, remove params and newlines # (newlines are not supported by graphviz) LOG.debug("Transition trigger: " + trans.inputString.strip()) is_cs = "[" + trans.inputString.split(';')[0].strip() + "]" if is_cs in valid_inputs: # Make sure continuous signal strings are not filtered # split on semicolon because of the "priority" statement label = is_cs #"[" + trans.inputString.strip() + "]" else: label, = re.match(r'([^(]+)', trans.inputString).groups() label = label.strip().replace('\n', ' ') except AttributeError as err: LOG.debug("Start transition: " + str(err)) # START transition may have no inputString for each in root_ast.content.named_start: # each is of type ogAST.Start if each.transition == trans: label = each.inputString[:-6] break else: label = '' def find_terminators(trans): ''' Recursively find all NEXTSTATES and RETURN nodes ''' next_states = [ term for term in trans.terminators if term.kind in ('next_state', 'return') ] joins = [ term for term in trans.terminators if term.kind == 'join' ] for join in joins: # JOIN - Find corresponding label try: corr_label, = [ lab for lab in root_ast.content.floating_labels + root_ast.labels if lab.inputString.lower() == join.inputString.lower() ] except ValueError: LOG.error('Missing label: ' + join.inputString) else: # Don't recurse forever in case of livelock try: if corr_label.inputString != trans.inputString: next_states.extend( find_terminators(corr_label)) except AttributeError: # START transition -> no inputString pass return set(next_states) # Determine the list of terminators in this transition next_states = find_terminators(trans) if len(next_states) > 1 and not basic: # more than one terminator - add intermediate node graph.add_node(str(diamond), shape='diamond', fixedsize='true', width=15.0 / 72.0, height=15.0 / 72.0, label='') if label.lower() in valid_inputs or not label.strip(): graph.add_edge(source, str(diamond), label=label) inputs_to_save.add(label.lower()) source = str(diamond) label = '' diamond += 1 for term in next_states: if term.inputString.strip() in ('-', '-*'): target = state else: target = term.inputString.lower() or ' ' if basic: target_states[target] |= set(label.split(',')) else: labs = set(lab.strip() for lab in label.split(',') if lab.strip().lower() in valid_inputs | {""}) actual = ',\n'.join(labs) graph.add_edge(source, target, label=actual) inputs_to_save |= set(lab.lower() for lab in labs) for target, labels in target_states.items(): # Here we add the label if in valid_inputs. sublab = [ lab.strip() for lab in labels if lab.strip().lower() in valid_inputs | {""} ] # Basic mode if sublab: label = ',\n'.join(sublab) inputs_to_save |= set(lab.lower() for lab in sublab) else: label = '' graph.add_edge(source, target, label=label) # Uncomment for debugging the generated dot graph: #with open('statechart.dot', 'w') as output: # output.write(graph.to_string()) #return graph if is_root: with open(identifier + ".cfg", "w") as cfg_file: for name, value in config_params.items(): cfg_file.write("cfg {} {}\n".format(name, value)) for each in inputs_to_save: cfg_file.write(each + "\n") ret['config'] = config_params for each in root_ast.composite_states: LOG.debug("Recursive generation of statechart: " + each.statename) # Recursively generate the graphs for nested states # Inherit from the list of signals from the higer level state #each.input_signals = root_ast.input_signals each.all_signals = valid_inputs ret['children'][each.statename] = create_dot_graph( each, basic, scene, is_root=False, config=config_params) return ret
import sys from PySide6.QtUiTools import QUiLoader from PySide6.QtWidgets import QApplication, QMainWindow from PySide6.QtCore import QFile, QIODevice app = QApplication(sys.argv) ui_file_name = "file_manager_design_1.ui" ui_file = QFile(ui_file_name) loader = QUiLoader() window = loader.load(ui_file) class Window(QMainWindow): def __init__(self): super().__init__() print(window) window.btn_load.clicked.connect(self.check()) window.btn_file.clicked.connect(self.check()) window.box_filters.setItemText(0, 'box_filters works') def setup(self): pass def check(self): print('btn_load works') print('btn_file works')
def __init__( self, hiRes, wineProg, wineDebug, patchClient, winePrefix, gameDir, homeDir, osType, settings, LanguageConfig, parent, data_folder, ): self.homeDir = homeDir self.osType = osType self.winePrefix = winePrefix self.settings = settings self.LanguageConfig = LanguageConfig ui_file = QtCore.QFile( os.path.join(data_folder, "ui", "winSettings.ui")) ui_file.open(QtCore.QFile.ReadOnly) loader = QUiLoader() self.winSettings = loader.load(ui_file, parentWidget=parent) ui_file.close() self.winSettings.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.FramelessWindowHint) if not self.osType.usingWindows: self.winSettings.txtPrefix.setText(winePrefix) self.winSettings.txtDebug.setText(wineDebug) self.winSettings.txtProgram.setText(wineProg) self.winSettings.txtProgram.setVisible(False) self.winSettings.lblProgram.setVisible(False) self.winSettings.txtPrefix.setVisible(False) self.winSettings.lblPrefix.setVisible(False) self.winSettings.btnPrefixDir.setVisible(False) else: self.winSettings.tabWidget.removeTab(1) self.winSettings.txtGameDir.setText(gameDir) self.winSettings.cboGraphics.addItem("Enabled") self.winSettings.cboGraphics.addItem("Disabled") self.winSettings.cboClient.addItem("32-bit") self.winSettings.cboClient.addItem("32-bit Legacy") self.winSettings.chkAdvanced.setChecked(False) self.winSettings.txtPatchClient.setText(patchClient) self.winSettings.txtPatchClient.setVisible(False) self.winSettings.lblPatchClient.setVisible(False) if hiRes: self.winSettings.cboGraphics.setCurrentIndex(0) else: self.winSettings.cboGraphics.setCurrentIndex(1) # Only adds 64-bit option if 64-bit client is available if settings.checkGameClient64(): self.winSettings.cboClient.addItem("64-bit") if settings.client == "WIN32": self.winSettings.cboClient.setCurrentIndex(0) elif settings.client == "WIN32Legacy": self.winSettings.cboClient.setCurrentIndex(1) elif settings.client == "WIN64": self.winSettings.cboClient.setCurrentIndex(2) self.winSettings.btnEN.setIcon( QtGui.QIcon(os.path.join(data_folder, "images", "EN-US.png"))) self.winSettings.btnDE.setIcon( QtGui.QIcon(os.path.join(data_folder, "images", "DE.png"))) self.winSettings.btnFR.setIcon( QtGui.QIcon(os.path.join(data_folder, "images", "FR.png"))) self.setLanguageButtons() self.winSettings.btnSetupWizard.clicked.connect( self.btnSetupWizardClicked) self.start_setup_wizard = False self.winSettings.btnGameDir.clicked.connect(self.btnGameDirClicked) self.winSettings.txtGameDir.textChanged.connect(self.txtGameDirChanged) self.winSettings.chkAdvanced.clicked.connect(self.chkAdvancedClicked) if not self.osType.usingWindows: self.winSettings.btnPrefixDir.clicked.connect( self.btnPrefixDirClicked) self.winSettings.txtPrefix.textChanged.connect( self.txtPrefixChanged)
def __init__(self, parent=None): super().__init__(parent) self.cfg = read_config(Path(BASE_PATH, "config.json")) ui_file_name = str(Path(BASE_PATH, "resources", "gui.ui")) ui_file = QtCore.QFile(ui_file_name) if not ui_file.open(QtCore.QIODevice.ReadOnly): print(f"Cannot open {ui_file_name}: {ui_file.errorString()}") sys.exit(-1) loader = QUiLoader() window = loader.load(ui_file) ui_file.close() if not window: print(loader.errorString()) sys.exit(-1) self.ui = window self.current_folder = self.cfg.default_album_folder self.slider_start_position = self.cfg.default_channel_volume self.player_status = None self.albums = [] self.current_album = None self.used_channels = [] self.ui.setWindowTitle(WindowProp.TITLE) self.ui.setWindowIcon( QtGui.QIcon( str(Path(BASE_PATH, self.cfg.svg_path, self.cfg.svg_app_icon)))) self.ui.setGeometry(WindowProp.LEFT, WindowProp.TOP, WindowProp.WIDTH, WindowProp.HEIGHT) self.center() self.sliders_reset() self.sliders_disable() self.ui.vertical_slider_0a.valueChanged.connect( lambda position, channel=0: self.sliders_change(position, channel)) self.ui.vertical_slider_1a.valueChanged.connect( lambda position, channel=1: self.sliders_change(position, channel)) self.ui.vertical_slider_2a.valueChanged.connect( lambda position, channel=2: self.sliders_change(position, channel)) self.ui.vertical_slider_3a.valueChanged.connect( lambda position, channel=3: self.sliders_change(position, channel)) self.ui.vertical_slider_4a.valueChanged.connect( lambda position, channel=4: self.sliders_change(position, channel)) self.ui.vertical_slider_5a.valueChanged.connect( lambda position, channel=5: self.sliders_change(position, channel)) self.ui.vertical_slider_6a.valueChanged.connect( lambda position, channel=6: self.sliders_change(position, channel)) self.ui.vertical_slider_7a.valueChanged.connect( lambda position, channel=7: self.sliders_change(position, channel)) self.ui.vertical_slider_8a.valueChanged.connect( lambda position, channel=8: self.sliders_change(position, channel)) self.ui.vertical_slider_9a.valueChanged.connect( lambda position, channel=9: self.sliders_change(position, channel)) self.combobox_populate() self.ui.btn_pause_play.clicked.connect(self.player_play) self.ui.btn_pause_play.setIcon( QtGui.QIcon( str(Path(BASE_PATH, self.cfg.svg_path, self.cfg.svg_btn_play)))) self.ui.btn_stop.clicked.connect(self.player_stop) self.ui.btn_stop.setIcon( QtGui.QIcon( str(Path(BASE_PATH, self.cfg.svg_path, self.cfg.svg_btn_stop)))) self.ui.btn_reset.clicked.connect(self.sliders_reset) self.ui.btn_all_up_volume.clicked.connect(self.sliders_up) self.ui.btn_all_down_volume.clicked.connect(self.sliders_down) self.ui.btn_random.clicked.connect(self.sliders_random) self.ui.select_album.currentIndexChanged.connect( self.combobox_on_change) self.ui.show() if self.cfg.auto_play: self.player_play()
print('mp4_command: ' + mp4_command) os.system(mp4_command) os.system('rm *wavuntagged.wav') os.system('{} {}'.format(soundfile_editor, master_filename)) print("") except: traceback.print_exc() application = QApplication(sys.argv) ui_file = QFile(piece_ui_filepath) if not ui_file.open(QIODevice.ReadOnly): print(f"Cannot open {ui_file_name}: {ui_file.errorString()}") sys.exit(-1) ui_loader = QUiLoader() main_window = ui_loader.load(ui_file) print("main_window: {} {}".format(main_window, type(main_window))) ui_file.close() if not main_window: print(loader.errorString()) sys.exit(-1) ''' Each instance of this class encapsulates one Csound control channel along with the Qt Widget that manages it. The methods of this class should have cases for handling different types of Csound channels (strings or numbers), and different types of Qt Widgets. The Qt Widget types and corresponding signals handled here are (from less to more abstract): 1. AbstractSlider and subclasses: valueChanged.
class QtFrontend(ViewSBFrontend): """ Qt Frontend that consumes packets for display. """ UI_NAME = 'qt' UI_DESCRIPTION = 'unstable GUI in Qt' # So, Qt's tree widgets require that column 0 have the expand arrow, but you _can_ change # where column 0 is displayed. # We want the summary column to have the expand arrow, so we'll swap it # with the timestamp column in __init__(). COLUMN_TIMESTAMP = 5 COLUMN_DEVICE = 1 COLUMN_ENDPOINT = 2 COLUMN_DIRECTION = 3 COLUMN_LENGTH = 4 COLUMN_SUMMARY = 0 COLUMN_STATUS = 6 COLUMN_DATA = 7 @staticmethod def reason_to_be_disabled(): try: import PySide6 except (ImportError, ModuleNotFoundError): return "PySide6 (Qt library) not available." return None @staticmethod def _stringify_list(lst): """ Tiny helper than runs the str constructor on every item in a list, but specifically handles two cases: 1) the object in question is None, which we instead want to display as an empty string, 2) the resulting string contains a null character, which Qt doesn't like, so we'll represent it to the user as, literally, \0. """ return [ str(x).replace('\0', r'\0') if x is not None else '' for x in lst ] def _create_item_for_packet(self, viewsb_packet): """ Creates a QTreeWidgetItem for a given ViewSBPacket. Args: viewsb_packet -- The ViewSBPacket to create the QTreeWidgetItem from. Returns a QTreeWidgetItem. """ def get_packet_string_array(viewsb_packet): """ Tiny helper to return and stringify the common fields used for the columns of tree items. """ direction = viewsb_packet.direction.name if viewsb_packet.direction is not None else '' length = len( viewsb_packet.data) if viewsb_packet.data is not None else '' return self._stringify_list([ viewsb_packet.summarize(), viewsb_packet.device_address, viewsb_packet.endpoint_number, direction, length, viewsb_packet.timestamp, viewsb_packet.summarize_status(), viewsb_packet.summarize_data() ]) + [viewsb_packet] item = QTreeWidgetItem(get_packet_string_array(viewsb_packet)) # Give the item a reference to the original packet object. item.setData(0, QtCore.Qt.UserRole, viewsb_packet) return item def _recursively_walk_packet(self, viewsb_packet): """ Recursively walks packet subordinates, batching QTreeWidgetItem.addChildren as much as possible. Args: viewsb_packet -- The top-level packet (as far as the caller's context is concerned). """ packet_item = self._create_item_for_packet(viewsb_packet) packet_children_list = [] for sub_packet in viewsb_packet.subordinate_packets: # Create the item for this packet, and recursively fill its children. packet_children_list.append( self._recursively_walk_packet(sub_packet)) packet_item.addChildren(packet_children_list) return packet_item def __init__(self): """ Sets up the Qt UI. """ QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_ShareOpenGLContexts) signal.signal( signal.SIGINT, signal.SIG_DFL) # fix SIGINT handling - cleanly exit on ctrl+c self.app = QApplication.instance() or QApplication([]) try: import qt_material qt_material.apply_stylesheet(self.app, 'light_blue.xml') except ImportError: pass self.ui_file = QtCore.QFile( os.path.dirname(os.path.realpath(__file__)) + '/qt.ui') self.loader = QUiLoader() self.loader.registerCustomWidget(ViewSBQTreeWidget) self.loader.registerCustomWidget(ViewSBHexView) self.window = self.loader.load(self.ui_file) # type: QMainWindow # Swap columns 0 and 5 to put the expand arrow on the summary column. self.window.usb_tree_widget.header().swapSections(0, 5) self.window.usb_tree_widget.header().setSectionResizeMode( QHeaderView.ResizeToContents) self.window.update_timer = QtCore.QTimer() self.window.update_timer.timeout.connect(self._update) self.window.usb_tree_widget.currentItemChanged.connect( self._tree_current_item_changed) self.window.usb_tree_widget = self.window.usb_tree_widget self.window.usb_tree_widget.sortByColumn(0, Qt.SortOrder.AscendingOrder) def ready(self): """ Called when the backend is ready to stream. """ self.window.showMaximized() def _update(self): """ Called by the QTimer `update_timer`; collects packets the queue and adds them to the tree view. We use this instead of calling `handle_communications` and defining `handle_incoming_packet`, because adding items one at a time as we receive them is slower than batching them. Note: Since this is called via a QTimer signal, this method runs in the UI thread. """ # Handle exceptions if self._exception_conn.poll(): self.handle_exception(*self._exception_conn.recv()) # TODO: overide handle_exception to show a Qt dialog message # If the process manager told us to stop (which might happen if e.g. the backend exits), # then stop and exit. if self.termination_event.is_set(): self.app.closeAllWindows() packet_list = [] try: # Get as many packets as we can as quick as we can. while True: packet = self.data_queue.get_nowait() packet_list.append(packet) # But the instant it's empty, don't wait for any more; just send them to be processed. except multiprocessing.queues.Empty: pass finally: self.add_packets(packet_list) def _tree_current_item_changed(self, current_item, _previous_item): """ Handler for the QTreeWidget.currentItemChanged() signal that populates the side panels with detail fields and a hex representation of the current packet. """ # Clear the details widget. self.window.usb_details_tree_widget.clear() current_packet = current_item.data(0, QtCore.Qt.UserRole) # A list of 2-tuples: first element is a table title, and the second is usually a string:string dict. detail_fields = current_packet.get_detail_fields() if detail_fields: self.update_detail_fields(detail_fields) self.window.usb_hex_view.populate(current_packet.get_raw_data()) def update_detail_fields(self, detail_fields): """ Populates the detail view with the relevant fields for the selected packet. """ # Each table will have a root item in the details view. root_items = [] for table in detail_fields: title = table[0] root = QTreeWidgetItem([title]) children = [] fields = table[1] # The usual case: a str:str dict. if isinstance(fields, dict): for key, value in fields.items(): children.append( QTreeWidgetItem(self._stringify_list([key, value]))) # Sometimes it'll just be a 1-column list. elif isinstance(fields, list): for item in fields: children.append( QTreeWidgetItem(self._stringify_list([item]))) # Sometimes it'll just be a string, or a `bytes` instance. else: children.append(QTreeWidgetItem(self._stringify_list([fields ]))) root.addChildren(children) # Add an empty "item" between each table. root_items.extend([root, QTreeWidgetItem([])]) self.window.usb_details_tree_widget.addTopLevelItems(root_items) self.window.usb_details_tree_widget.expandAll() self.window.usb_details_tree_widget.resizeColumnToContents(0) self.window.usb_details_tree_widget.resizeColumnToContents(1) def add_packets(self, viewsb_packets): """ Adds a list of top-level ViewSB packets to the tree. We're in the UI thread; every bit of overhead counts, so let's batch as much as possible. """ top_level_items_list = [] for viewsb_packet in viewsb_packets: # Create the item for this packet, and recursively fill its children. top_level_items_list.append( self._recursively_walk_packet(viewsb_packet)) self.window.usb_tree_widget.addTopLevelItems(top_level_items_list) def run(self): """ Overrides ViewSBFrontend.run(). """ self.wait_for_backend_ready() # TODO: is there a better value than 100 ms? Should it be configurable by the Analyzer? self.window.update_timer.start(100) self.app.exec_() self.stop() def stop(self): self.app.closeAllWindows() self.termination_event.set()