class ToggleButton: def __init__(self, frame_text: str, checkbox_text: str = 'Default'): self.box = QVBoxLayout() self.lbl = QLabel(frame_text) self.checkbox = QCheckBox(checkbox_text) self.checkbox.setCheckState(Qt.Unchecked) self.numeric = QSpinBox() self.numeric.setValue(-1) self.box.addWidget(self.lbl) self.box.addWidget(self.numeric) self.box.addWidget(self.checkbox) self.checkbox.stateChanged.connect(self.checkbox_toggle) self.numeric.valueChanged.connect(self.numeric_change) self.use_default = False self.value = -1 @Slot() def checkbox_toggle(self, checked): self.use_default = self.checkbox.checkState() == Qt.Checked self.numeric.setDisabled(self.use_default) @Slot() def numeric_change(self, checked): self.value = self.numeric.value()
class SecondaryFilters(QWidget, ListenerNode): def __init__(self, listeners_pool, *args, **kwargs): super(SecondaryFilters, self).__init__(*args, **kwargs) ListenerNode.__init__(self, 'secondary-filters', listeners_pool) self.group_by_month = QCheckBox('Por mes') self.group_by_type = QCheckBox('Por tipo de gasto') layout = QVBoxLayout() self.setLayout(layout) inner_layout = QHBoxLayout() inner_layout.addWidget(self.group_by_month) inner_layout.addWidget(self.group_by_type) group_box = QGroupBox('Agrupaciones') group_box.setLayout(inner_layout) layout.addWidget(group_box) self.group_by_month.stateChanged.connect(self.grouping_changed) self.group_by_type.stateChanged.connect(self.grouping_changed) def grouping_changed(self): month_status = self.group_by_month.checkState() type_status = self.group_by_type.checkState() if month_status == QtCore.Qt.CheckState.Unchecked and type_status == QtCore.Qt.CheckState.Unchecked: criteria = 'expenses_raw' elif month_status == QtCore.Qt.CheckState.Unchecked and type_status == QtCore.Qt.CheckState.Checked: criteria = 'expenses_by_type' elif month_status == QtCore.Qt.CheckState.Checked and type_status == QtCore.Qt.CheckState.Unchecked: criteria = 'expenses_by_month' elif month_status == QtCore.Qt.CheckState.Checked and type_status == QtCore.Qt.CheckState.Checked: criteria = 'expenses_by_type_and_month' self.send_event('view-expenses-screen', 'add_table', criteria)
def show_commit_session_prompt(self): """Shows the commit session message box.""" config = self._data_store._toolbox._config commit_at_exit = config.get("settings", "commit_at_exit") if commit_at_exit == "0": # Don't commit session and don't show message box return elif commit_at_exit == "1": # Default # Show message box msg = QMessageBox(self) msg.setIcon(QMessageBox.Question) msg.setWindowTitle("Commit pending changes") msg.setText( "The current session has uncommitted changes. Do you want to commit them now?" ) msg.setInformativeText( "WARNING: If you choose not to commit, all changes will be lost." ) msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No) chkbox = QCheckBox() chkbox.setText("Do not ask me again") msg.setCheckBox(chkbox) answer = msg.exec_() chk = chkbox.checkState() if answer == QMessageBox.Yes: self.show_commit_session_dialog() if chk == 2: # Save preference into config file config.set("settings", "commit_at_exit", "2") else: if chk == 2: # Save preference into config file config.set("settings", "commit_at_exit", "0") elif commit_at_exit == "2": # Commit session and don't show message box self.show_commit_session_dialog() else: config.set("settings", "commit_at_exit", "1") return
class MainWidget(QWidget): format_dict = { "JPEG(jpg)": "jpeg", "WebP": "webp", "Gif": "gif", "PNG": "png" } def __init__(self, parent): super().__init__() self.par = parent self.InitUI() def InitUI(self): self.selected_dir = str() self.option_array = [1, 0, 0, 0] self.main_layout = QVBoxLayout() self.make_dir_groupbox() self.make_func_groupbox() self.make_sys_layout() self.status_bar = QStatusBar() self.setEnabled(True) self.setLayout(self.main_layout) def make_dir_groupbox(self): dir_groupbox = QGroupBox("Select Directory") dir_layout = QVBoxLayout() self.loaded_dir_label = QLabel(self.selected_dir) self.loaded_dir_label.setStyleSheet("max-height: 24px;" "background-color: #FFFFFF;" "border-style: solid;" "border-width: 1px;" "border-color: #000000") dir_layout.addWidget(self.loaded_dir_label) self.load_dir_button = QPushButton("Load Directory", self) self.load_dir_button.clicked.connect(self.load_dir) dir_layout.addWidget(self.load_dir_button) dir_groupbox.setLayout(dir_layout) self.main_layout.addWidget(dir_groupbox) def make_func_groupbox(self): func_layout = QHBoxLayout() self.encode_widget = RadioBox(encode_dict) encode_layout = self.encode_widget.make_radio_box("UTF-8 with BOM") self.encode_groupbox = QGroupBox("Encode to: ") self.encode_groupbox.setLayout(encode_layout) self.encode_groupbox.setCheckable(True) self.encode_groupbox.clicked.connect(self.option_set) func_layout.addWidget(self.encode_groupbox) self.fmt_groupbox = QGroupBox("Convert image format") fmt_hbox = QHBoxLayout() self.format_widget_from = RadioBox(self.format_dict) format_layout_from = self.format_widget_from.make_radio_box("WebP") fmt_from_groupbox = QGroupBox("Convert image from: ") fmt_from_groupbox.setLayout(format_layout_from) fmt_hbox.addWidget(fmt_from_groupbox) self.format_widget_to = RadioBox(self.format_dict) format_layout_to = self.format_widget_to.make_radio_box("PNG") fmt_to_groupbox = QGroupBox("Convert image to: ") fmt_to_groupbox.setLayout(format_layout_to) fmt_hbox.addWidget(fmt_to_groupbox) self.fmt_groupbox.setLayout(fmt_hbox) self.fmt_groupbox.setCheckable(True) func_layout.addWidget(self.fmt_groupbox) option_groupbox = QGroupBox("OPTION: ") option_layout = QVBoxLayout() self.change_txt_yn = QCheckBox("Change image ext in CSV/ERB", self) self.change_txt_yn.toggle() self.change_txt_yn.clicked.connect(self.option_set) self.backup_yn = QCheckBox("Place files in Result directory", self) self.backup_yn.clicked.connect(self.option_set) option_layout.addWidget(self.change_txt_yn) option_layout.addWidget(self.backup_yn) option_groupbox.setLayout(option_layout) func_layout.addWidget(option_groupbox) self.main_layout.addLayout(func_layout) def make_sys_layout(self): sys_layout = QHBoxLayout() self.run_button = QPushButton("RUN", self) self.run_button.setEnabled(False) self.run_button.clicked.connect(self.run_process) self.prog_bar = QProgressBar() self.prog_bar.setMinimum(0) sys_layout.addWidget(self.prog_bar) sys_layout.stretch(1) sys_layout.addWidget(self.run_button) self.main_layout.addLayout(sys_layout) def load_dir(self): f_dialog = QFileDialog(self, "불러올 폴더를 선택하세요.", os.path.curdir) f_dialog.setFileMode(QFileDialog.DirectoryOnly) self.selected_dir = f_dialog.getExistingDirectory( self, "불러올 폴더를 선택하세요.") if not self.selected_dir: self.selected_dir = str() self.run_button.setEnabled(False) else: self.run_button.setEnabled(True) self.loaded_dir_label.setText(self.selected_dir) return self.selected_dir def option_set(self): if not self.encode_groupbox.isChecked(): self.change_txt_yn.setEnabled(False) else: self.change_txt_yn.setEnabled(True) self.option_array[0] = self.change_txt_yn.checkState() self.option_array[1] = self.backup_yn.checkState() self.option_array[2] = self.encode_groupbox.isChecked() self.option_array[3] = self.fmt_groupbox.isChecked() return self.option_array def run_process(self): self.option_set() self.setEnabled(False) target_array = ( self.encode_widget.result, self.format_widget_from.result, self.format_widget_to.result, self.selected_dir, ) bar_array = (self.prog_bar, self.status_bar) self.threadclass = MyThread(target_array, bar_array, self.option_array, self) self.work_started = 0 self.threadclass.processed.connect(self.progbar_set) self.threadclass.finished.connect(self.donebox) self.threadclass.start() def open_result(self): if self.option_array[1]: result_path = "Result\\" else: result_path = self.selected_dir os.startfile(result_path) @Slot(int) def progbar_set(self, progress_stat): if not self.work_started: self.prog_bar.setMaximum(progress_stat) self.work_started += 1 else: self.prog_bar.setValue(progress_stat) @Slot(bool) def donebox(self): msgbox = QMessageBox( QMessageBox.Warning, "Done!", "Do you want to quit?", buttons=QMessageBox.Yes | QMessageBox.No, parent=self, ) open_result = msgbox.addButton("Open Result Folder", QMessageBox.AcceptRole) msgbox.setDefaultButton(QMessageBox.Yes) close_yn = msgbox.exec_() if close_yn == QMessageBox.No: self.threadclass.wait() # debugpy.debug_this_thread() self.close() self.par.intiGUI() else: if close_yn == QMessageBox.AcceptRole: self.open_result() QCoreApplication.instance().quit()
class daemon(confStack): def __init_stack__(self): self.dbg=True self._debug("daemon load") self.description=(_("Openmeetings daemon setup")) self.menu_description=(_("Conifgure openmeetings service setup")) self.icon=('openmeetings') self.tooltip=(_("Start/stop the service or launch at boot")) self.index=2 self.enabled=True self.level='system' self.n4d=n4d() # self.hideControlButtons() self.setStyleSheet(self._setCss()) #def __init__ def _load_screen(self): box=QGridLayout() self.btn_service=QPushButton() self.btn_service.setCheckable(True) self.btn_service.toggled.connect(self._ctrlRun) box.addWidget(self.btn_service,0,0,1,1,Qt.AlignCenter) self.chk_startup=QCheckBox(_("Launch at startup")) self.chk_startup.setTristate(False) box.addWidget(self.chk_startup,1,0,1,1,Qt.AlignTop) self.chk_kurento=QCheckBox(_("Disable videconference (remove webcam and microphone support)")) self.chk_kurento.setTristate(False) box.addWidget(self.chk_kurento,2,0,1,1,Qt.AlignTop) self.setLayout(box) self.updateScreen() return(self) #def _load_screen def _check_isRunning(self): cmd=["/usr/sbin/lliurex-openmeetings-service","status"] a=subprocess.check_output(cmd).decode().strip() if a=="STOPPED": return False else: return True #def _check_isRunning def _ctrlRun(self,*args): if self._check_isRunning(): self.n4d.n4dQuery("LliurexOpenmeetings","remote_service_stop") else: self.n4d.n4dQuery("LliurexOpenmeetings","remote_service_start") self.updateScreen() #def _ctrlRun def _getServiceStatus(self): if os.path.isfile("/etc/systemd/system/lliurex-openmeetings.service"): return True else: return False #def _getStatus def _ctrlService(self,*args): self.updateScreen() #def _ctrlService def updateScreen(self): if self._check_isRunning(): self.btn_service.setText(_("Stop service")) self.btn_service.setStyleSheet("background:red;color:white") else: self.btn_service.setText(_("Start service")) self.btn_service.setStyleSheet("background:green;color:black") self.chk_startup.setChecked(False) if self._getServiceStatus(): self.chk_startup.setChecked(True) return True #def _udpate_screen def writeConfig(self): if self.chk_startup.checkState(): cmd=["/bin/systemctl","enable","lliurex-openmeetings"] else: cmd=["/bin/systemctl","disable","lliurex-openmeetings"] subprocess.run(cmd) if self.chk_kurento.checkState(): cmd=["/bin/systemctl","disable","kurento-media-server"] else: cmd=["/bin/systemctl","enable","kurento-media-server"] subprocess.run(cmd) return True #def writeConfig def _setCss(self): css=""" #error{ color:white; }""" return(css)
class MemDumpWindow(QWidget): kill_signal = Signal(bool) def __init__(self, qmp, base=0, max=constants['block_size']): super().__init__() self.flag = False self.threshold = 2048 # number of resident bytes self.qmp = qmp self.init_ui() self.baseAddress = base self.maxAddress = self.baseAddress self.delta = 4 # adds a small buffer area for scrolling action to happen self.sem = QSemaphore(1) # semaphore for controlling access to the enabling / disabling of the scroll listening self.pos = self.chr_display.verticalScrollBar().value() self.highlight_sem = QSemaphore(1) # semaphore for controlling access to highlighting state self.is_highlighted = False self.highlight_addr = 0 self.endian = Endian.little self.endian_sem = QSemaphore(1) self.hash = randint(0, 0xfffffffffffffff) icon = QIcon('package/icons/nasa.png') self.setWindowIcon(icon) self.max_size = 0xfffffffffffffff self.qmp.pmem.connect(self.update_text) self.grab_data(val=self.baseAddress, size=min(max, constants['block_size'] + base)-self.baseAddress) self.t = MyThread(self) self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True)) self.qmp.stateChanged.connect(self.t.halt) self.t.running = self.qmp.running self.t.start() self.show() def init_ui(self): self.hbox = QHBoxLayout() # holds widgets for refresh button, desired address, and size to grab self.vbox = QVBoxLayout() # main container self.lower_hbox = QSplitter() # holds memory views self.lower_container = QHBoxLayout() # holds lower_hbox and the endian_vbox self.endian_vbox = QVBoxLayout() self.hbox.addWidget(QLabel('Address:')) self.address = QLineEdit() self.hbox.addWidget(self.address) self.hbox.addWidget(QLabel('Size:')) self.size = QLineEdit() self.hbox.addWidget(self.size) self.hbox.addWidget(QLabel('Grouping:')) self.grouping = QComboBox() self.grouping.addItems(['1','2','4','8']) self.hbox.addWidget(self.grouping) self.search = QPushButton('Search') self.search.clicked.connect(lambda:self.find(self.address.text(), constants['block_size'])) self.hbox.addWidget(self.search) self.refresh = QPushButton('Refresh') self.refresh.clicked.connect(lambda:self.grab_data(val=self.address.text(), size=self.size.text(), grouping=self.grouping.currentText(), refresh=True)) self.hbox.addWidget(self.refresh) self.save = QPushButton('Save') self.save.clicked.connect(lambda: self.save_to_file()) self.disable_save(self.qmp.running) self.qmp.stateChanged.connect(self.disable_save) self.hbox.addWidget(self.save) self.auto_refresh = QCheckBox('Auto Refresh') self.auto_refresh.setCheckState(Qt.CheckState.Checked) self.auto_refresh.stateChanged.connect(self.auto_refresh_check) self.hbox.addWidget(self.auto_refresh) self.vbox.addLayout(self.hbox) # textbox for addresses self.addresses = QTextEdit() self.addresses.setReadOnly(True) self.addresses.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.addresses.setLineWrapMode(QTextEdit.NoWrap) self.addresses.setCurrentFont(QFont('Courier New')) self.addresses.setGeometry(0,0,150,500) self.lower_hbox.addWidget(self.addresses) # textbox for hex display of memory self.mem_display = QTextEdit() self.mem_display.setReadOnly(True) self.mem_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.mem_display.setLineWrapMode(QTextEdit.NoWrap) self.mem_display.setCurrentFont(QFont('Courier New')) self.mem_display.setGeometry(0,0,600,500) self.lower_hbox.addWidget(self.mem_display) # textbox for char display of memory self.chr_display = QTextEdit() self.chr_display.setReadOnly(True) self.chr_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.chr_display.setLineWrapMode(QTextEdit.NoWrap) self.chr_display.setCurrentFont(QFont('Courier New')) self.mem_display.setGeometry(0,0,400,500) self.lower_hbox.addWidget(self.chr_display) self.lower_container.addWidget(self.lower_hbox) self.mem_display.verticalScrollBar().valueChanged.connect(self.addresses.verticalScrollBar().setValue) #synchronizes addresses's scroll bar to mem_display's self.addresses.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue) #synchronizes mem_display's scroll to addresses's, allowing for searching for addresses to scrol mem_display to the desired point self.chr_display.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue) self.mem_display.verticalScrollBar().valueChanged.connect(self.chr_display.verticalScrollBar().setValue) self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll) # allows us to do scrolling # setting up endiannes selection buttons self.little = QRadioButton("Little Endian") self.little.click() self.little.clicked.connect(lambda:self.change_endian(Endian.little)) self.big = QRadioButton("Big Endian") self.big.clicked.connect(lambda:self.change_endian(Endian.big)) self.endian_vbox.addWidget(self.little) self.endian_vbox.addWidget(self.big) self.endian_vbox.addSpacing(400) self.lower_container.addLayout(self.endian_vbox) self.vbox.addLayout(self.lower_container) self.vbox.setSpacing(10) self.setLayout(self.vbox) self.setWindowTitle("Memory Dump") self.setGeometry(100, 100, 1550, 500) def disable_save(self, val): self.save.setEnabled(not val) def save_to_file(self): try: filename = QFileDialog().getSaveFileName(self, 'Save', '.', options=QFileDialog.DontUseNativeDialog) except Exception as e: return if filename[0] == '': return args = { 'val': self.baseAddress, 'size': self.maxAddress - self.baseAddress, 'filename': filename[0] } self.qmp.command('pmemsave', args=args) def auto_refresh_check(self, value): if self.auto_refresh.checkState() == Qt.CheckState.Checked and not self.t.isRunning(): self.t = MyThread(self) self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True)) self.t.start() elif self.auto_refresh.checkState() == Qt.CheckState.Unchecked: self.kill_signal.emit(True) def closeEvent(self, event): self.kill_signal.emit(True) self.qmp.pmem.disconnect(self.update_text) while True: if self.sem.tryAcquire(1, 1): break self.sem.release(10) event.accept() def update_text(self, value): if not value or value['hash'] != self.hash: # semaphore must be held before entering this function return byte = value['vals'] if self.refresh: self.clear_highlight() self.addresses.clear() # clearing to refresh data, other regions will be refilled through scrolling self.mem_display.clear() self.chr_display.clear() s = [''] * ceil((len(byte) / (16))) # hex representation of memory addresses = '' # addresses count = self.baseAddress # keeps track of each 16 addresses if self.pos == self.max: # scrolling down count = self.maxAddress self.maxAddress = max(count + (len(byte)), self.maxAddress) first = True chars = [''] * len(s) # char represenation of memory index = 0 self.endian_sem.acquire() nums = '' for tup in byte: b = tup['val'] if count % 16 == 0: if first: addresses += f'0x{count:08x}' first = False else: addresses += f'\n0x{count:08x}' index += 1 count += 1 if self.endian == Endian.big: if tup['ismapped']: nums = f'{b:02x}' + nums chars[index] += f'{char_convert(b):3}' else: nums = '**' + nums chars[index] += f'{".":3}' elif self.endian == Endian.little: if tup['ismapped']: nums += f'{b:02x}' chars[index] = f'{char_convert(b):3}' + chars[index] else: nums = '**' + nums chars[index] = f'{".":3}' + chars[index] if count % self.group == 0: if self.endian == Endian.big: s[index] += nums + ' ' elif self.endian == Endian.little: s[index] = nums + ' ' + s[index] nums = '' #print(f'"{s[index]}"') self.endian_sem.release() s = '\n'.join(s) chars = '\n'.join(chars) scroll_goto = self.pos if self.pos > self.max - self.delta: # scrolling down self.addresses.append(addresses) self.mem_display.append(s) self.chr_display.append(chars) if self.flag: self.flag = False scroll_goto = (1 - constants['block_size'] / self.threshold) * self.max else: scroll_goto = self.max elif self.pos < self.min + self.delta: # scrolling up addr_cur = self.addresses.textCursor() mem_cur = self.mem_display.textCursor() chr_cur = self.chr_display.textCursor() addr_cur.setPosition(0) mem_cur.setPosition(0) chr_cur.setPosition(0) self.addresses.setTextCursor(addr_cur) self.mem_display.setTextCursor(mem_cur) self.chr_display.setTextCursor(chr_cur) self.addresses.insertPlainText(addresses + '\n') self.mem_display.insertPlainText(s + '\n') self.chr_display.insertPlainText(chars + '\n') if self.flag: self.flag = False scroll_goto = (constants['block_size'] / self.threshold) * self.max else: scroll_goto = self.chr_display.verticalScrollBar().maximum() - self.max else: self.addresses.setPlainText(addresses) self.mem_display.setPlainText(s) self.chr_display.setPlainText(chars) self.highlight_sem.acquire() if self.is_highlighted: self.highlight_sem.release() self.highlight(self.highlight_addr, self.group) else: self.highlight_sem.release() self.chr_display.verticalScrollBar().setValue(scroll_goto) self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll) self.sem.release() def grab_data(self, val=0, size=constants['block_size'], grouping=1, refresh=False): if val == None: val = 0 if size == None: size = 1024 if type(val) == str: try: val = int(val, 0) except Exception: val = 0 if type(size) == str: try: size = int(size, 0) except Exception: size = constants['block_size'] if type(grouping) == str: try: grouping = int(grouping, 0) except: grouping = 1 if grouping not in [1, 2, 4, 8]: grouping = 1 if val < 0: val = 0 if val >= self.max_size: return if size < 0: size = constants['block_size'] if size > self.threshold: size = self.threshold self.sem.acquire() val = val - (val % 16) if val < self.baseAddress or refresh: self.baseAddress = val if size % 16 != 0: size = size + (16 - (size % 16)) if val + size > self.max_size: size = self.max_size - val try: self.chr_display.verticalScrollBar().valueChanged.disconnect(self.handle_scroll) except: pass self.pos = self.chr_display.verticalScrollBar().value() self.max = self.chr_display.verticalScrollBar().maximum() self.min = self.chr_display.verticalScrollBar().minimum() self.group = grouping self.refresh = refresh if refresh: self.maxAddress = self.baseAddress self.highlight_sem.acquire() if self.is_highlighted and self.highlight_addr not in range(val, val + size): self.is_highlighted = False self.pos = 0 self.highlight_sem.release() args = { 'addr': val, 'size': size, 'hash': self.hash, 'grouping': 1 } self.qmp.command('get-pmem', args=args) def find(self, addr, size): try: addr = int(addr, 0) except ValueError as e: print(e) return if self.baseAddress <= addr and addr <= self.maxAddress: group = self.grouping.currentText() try: group = int(group, 0) if group not in [1, 2, 4, 8]: group = 1 except: group = 1 self.highlight(addr, group) else: self.highlight_sem.acquire() self.is_highlighted = True self.highlight_addr = addr self.highlight_sem.release() self.grab_data(val=addr, size=size, refresh=True ) def clear_highlight(self): fmt = QTextCharFormat() fmt.setFont('Courier New') # clearing past highlights addr_cur = self.addresses.textCursor() # getting cursors mem_cur = self.mem_display.textCursor() chr_cur = self.chr_display.textCursor() addr_cur.select(QTextCursor.Document) # selecting entire document mem_cur.select(QTextCursor.Document) chr_cur.select(QTextCursor.Document) addr_cur.setCharFormat(fmt) # adding format mem_cur.setCharFormat(fmt) chr_cur.setCharFormat(fmt) def highlight(self, addr, group): self.clear_highlight() # adding new highlights fmt = QTextCharFormat() fmt.setBackground(Qt.cyan) fmt.setFont('Courier New') addr_block = self.addresses.document().findBlockByLineNumber((addr - self.baseAddress) // 16) # gets linenos mem_block = self.mem_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16) chr_block = self.chr_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16) addr_cur = self.addresses.textCursor() # getting cursors mem_cur = self.mem_display.textCursor() chr_cur = self.chr_display.textCursor() char_offset = 0 mem_offset = 0 self.endian_sem.acquire() if self.endian == Endian.big: mem_offset = ((addr % 16) // group) * (2 * group + 1) char_offset = (addr % 16) * 3 elif self.endian == Endian.little: mem_offset = (((16 / group) - 1 )* (2 * group + 1)) - ((addr % 16) // group) * (2 * group + 1) char_offset = (15*3) - ((addr % 16) * 3) self.endian_sem.release() addr_cur.setPosition(addr_block.position()) # getting positions mem_cur.setPosition(mem_block.position() + mem_offset) # gives character offset within 16 byte line chr_cur.setPosition(chr_block.position() + char_offset) # sets position of char chr_text = self.chr_display.toPlainText() if chr_text[chr_cur.position()] == '\\' and chr_cur.position() + 1 < len(chr_text) and chr_text[chr_cur.position() + 1] in ['0', 'n', 't']: chr_cur.setPosition(chr_cur.position() + 2, mode=QTextCursor.KeepAnchor) else: chr_cur.setPosition(chr_cur.position() + 1, mode=QTextCursor.KeepAnchor) addr_cur.select(QTextCursor.LineUnderCursor) # selects whole line mem_cur.select(QTextCursor.WordUnderCursor) # selects just one word addr_cur.setCharFormat(fmt) # setting format mem_cur.setCharFormat(fmt) chr_cur.setCharFormat(fmt) self.addresses.setTextCursor(addr_cur) self.mem_display.setTextCursor(mem_cur) self.chr_display.setTextCursor(chr_cur) self.highlight_sem.acquire() self.is_highlighted = True self.highlight_addr = addr self.highlight_sem.release() def handle_scroll(self): if self.baseAddress > 0 and self.chr_display.verticalScrollBar().value() < self.chr_display.verticalScrollBar().minimum() + self.delta: size = constants['block_size'] if self.maxAddress - self.baseAddress >= self.threshold: self.flag = True self.grab_data(val=self.baseAddress - constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText()) return if self.baseAddress < size: size = self.baseAddress self.grab_data(val=self.baseAddress-size, size=size, grouping=self.grouping.currentText()) elif self.chr_display.verticalScrollBar().value() > self.chr_display.verticalScrollBar().maximum() - self.delta and self.maxAddress <= self.max_size: if self.maxAddress - self.baseAddress >= self.threshold: self.flag = True self.grab_data(val=self.baseAddress + constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText()) else: self.grab_data(val=self.maxAddress, grouping=self.grouping.currentText()) def change_endian(self, endian): self.endian_sem.acquire() if endian == Endian.little: self.endian = endian elif endian == Endian.big: self.endian = endian self.endian_sem.release()
class AudioInfoDialog(QDialog): def __init__(self, audios_name, audios_delay, audios_language, audios_track_name, audios_set_default, audios_set_forced, audios_default_value_delay, audios_default_value_language, audios_default_value_track_name, audios_default_value_set_default, audios_default_value_set_forced, audio_set_default_disabled=False, audio_set_forced_disabled=False, disable_edit=False, parent=None): super().__init__(parent) self.window_title = "Audio Info" self.state = "no" self.audios_count = len(audios_delay) self.messageIcon = QLabel() self.audio_tab_comboBox = InfoCellDialogTabComboBox( hint="Audios Groups") for i in range(self.audios_count): self.audio_tab_comboBox.addItem("Audio #" + str(i + 1)) self.audio_tab_comboBox.setCurrentIndex(0) self.audio_tab_comboBox.currentIndexChanged.connect( self.update_current_audio_index) self.current_audio_index = 0 self.disable_edit = disable_edit self.current_audio_name = audios_name self.current_audio_language = audios_language self.current_audio_delay = audios_delay self.current_audio_track_name = audios_track_name self.current_audio_set_default = audios_set_default self.current_audio_set_forced = audios_set_forced self.default_audio_language = audios_default_value_language self.default_audio_delay = audios_default_value_delay self.default_audio_track_name = audios_default_value_track_name self.default_audio_set_default = audios_default_value_set_default self.default_audio_set_forced = audios_default_value_set_forced self.audio_set_default_disabled = audio_set_default_disabled self.audio_set_forced_disabled = audio_set_forced_disabled self.audio_name_label = QLabel("Audio Name:") self.audio_name_value = QLabel( str(self.current_audio_name[self.current_audio_index])) width_to_be_fixed = 0 for i in range(len(self.current_audio_name)): width_to_be_fixed = max( width_to_be_fixed, self.audio_name_value.fontMetrics().boundingRect( self.current_audio_name[i]).width()) self.audio_name_value.setFixedWidth(width_to_be_fixed + 10) self.audio_delay_label = QLabel("Audio Delay:") self.audio_delay_spin = QDoubleSpinBox() self.setup_audio_delay_spin() self.audio_language_label = QLabel("Audio Language:") self.audio_language_comboBox = QComboBox() self.setup_audio_language_comboBox() self.audio_track_name_label = QLabel("Audio Track Name:") self.audio_track_name_lineEdit = QLineEdit() self.setup_audio_track_name_lineEdit() self.audio_set_forced_label = QLabel("Audio Forced State:") self.audio_set_forced_checkBox = QCheckBox() self.setup_audio_set_forced_checkBox() self.audio_set_default_label = QLabel("Audio Default State:") self.audio_set_default_checkBox = QCheckBox() self.setup_audio_set_default_checkBox() self.yes_button = QPushButton("OK") self.no_button = QPushButton("Cancel") self.reset_button = QPushButton("Reset To Default") self.buttons_layout = QHBoxLayout() self.audio_delay_layout = QHBoxLayout() self.audio_language_layout = QHBoxLayout() self.audio_track_name_layout = QHBoxLayout() self.audio_set_default_layout = QHBoxLayout() self.audio_set_forced_layout = QHBoxLayout() self.buttons_layout.addWidget(QLabel(""), stretch=3) self.buttons_layout.addWidget(self.reset_button, stretch=2) self.buttons_layout.addWidget(self.yes_button, stretch=2) self.buttons_layout.addWidget(self.no_button, stretch=2) self.buttons_layout.addWidget(QLabel(""), stretch=3) self.audio_setting_layout = QGridLayout() self.audio_editable_setting_layout = QFormLayout() self.audio_editable_setting_layout.addRow(self.audio_name_label, self.audio_name_value) self.audio_editable_setting_layout.addRow( self.audio_track_name_label, self.audio_track_name_lineEdit) self.audio_editable_setting_layout.addRow(self.audio_language_label, self.audio_language_comboBox) self.audio_editable_setting_layout.addRow(self.audio_delay_label, self.audio_delay_spin) self.audio_editable_setting_layout.addRow( self.audio_set_default_label, self.audio_set_default_checkBox) self.audio_editable_setting_layout.addRow( self.audio_set_forced_label, self.audio_set_forced_checkBox) self.audio_setting_layout.addWidget(self.audio_tab_comboBox, 0, 0) self.audio_setting_layout.addLayout(self.audio_editable_setting_layout, 1, 0, 5, 2) self.audio_setting_layout.addWidget(self.messageIcon, 1, 3, 5, -1) self.main_layout = QGridLayout() self.main_layout.addLayout(self.audio_setting_layout, 0, 0, 2, 3) self.main_layout.addLayout(self.buttons_layout, 2, 0, 1, -1) self.main_layout.setContentsMargins(20, 20, 20, 20) self.setLayout(self.main_layout) self.setup_ui() self.signal_connect() def setup_ui(self): self.disable_question_mark_window() self.messageIcon.setPixmap( QtGui.QPixmap(GlobalFiles.AudioIconPath).scaledToHeight(100)) self.set_dialog_values() self.set_default_buttons() if self.audio_set_default_disabled: self.audio_set_default_disable() if self.audio_set_forced_disabled: self.audio_set_forced_disable() if self.disable_edit: self.audio_track_name_lineEdit.setEnabled(False) self.audio_language_comboBox.setEnabled(False) self.audio_delay_spin.setEnabled(False) self.audio_set_default_checkBox.setEnabled(False) self.audio_set_forced_checkBox.setEnabled(False) self.reset_button.setEnabled(False) self.setup_tool_tip_hint_audio_set_default() self.setup_tool_tip_hint_audio_set_forced() def signal_connect(self): self.audio_track_name_lineEdit.textEdited.connect( self.update_current_audio_track_name) self.audio_delay_spin.editingFinished.connect( self.update_current_audio_delay) self.audio_language_comboBox.currentTextChanged.connect( self.update_current_audio_language) self.audio_set_default_checkBox.stateChanged.connect( self.update_current_audio_set_default) self.audio_set_forced_checkBox.stateChanged.connect( self.update_current_audio_set_forced) self.yes_button.clicked.connect(self.click_yes) self.no_button.clicked.connect(self.click_no) self.reset_button.clicked.connect(self.reset_audio_setting) def click_yes(self): self.state = "yes" self.close() def click_no(self): self.state = "no" self.close() def set_dialog_values(self): self.setWindowTitle(self.window_title) self.setWindowIcon(GlobalFiles.InfoSettingIcon) def disable_question_mark_window(self): self.setWindowFlag(Qt.WindowContextHelpButtonHint, on=False) def increase_message_font_size(self, value): message_font = self.message.font() message_font.setPointSize(self.message.fontInfo().pointSize() + value) self.message.setFont(message_font) def set_default_buttons(self): self.yes_button.setDefault(True) self.yes_button.setFocus() def showEvent(self, a0: QtGui.QShowEvent) -> None: super().showEvent(a0) self.setFixedSize(self.size()) def setup_audio_track_name_lineEdit(self): self.audio_track_name_lineEdit.setClearButtonEnabled(True) self.audio_track_name_lineEdit.setText( self.current_audio_track_name[self.current_audio_index]) def setup_audio_language_comboBox(self): self.audio_language_comboBox.addItems(AllAudiosLanguages) self.audio_language_comboBox.setCurrentIndex( AllAudiosLanguages.index( self.current_audio_language[self.current_audio_index])) self.audio_language_comboBox.setMaxVisibleItems(8) self.audio_language_comboBox.setStyleSheet( "QComboBox { combobox-popup: 0; }") def setup_audio_delay_spin(self): # self.audio_delay_spin.setMaximumWidth(screen_size.width() // 16) self.audio_delay_spin.setDecimals(3) self.audio_delay_spin.setMinimum(-9999.0) self.audio_delay_spin.setMaximum(9999.0) self.audio_delay_spin.setSingleStep(0.5) self.audio_delay_spin.setValue( float(self.current_audio_delay[self.current_audio_index])) def setup_audio_set_default_checkBox(self): self.audio_set_default_checkBox.setText("Set Default") self.audio_set_default_checkBox.setChecked( bool(self.current_audio_set_default[self.current_audio_index])) def setup_audio_set_forced_checkBox(self): self.audio_set_forced_checkBox.setText("Set Forced") self.audio_set_forced_checkBox.setChecked( bool(self.current_audio_set_forced[self.current_audio_index])) def update_current_audio_track_name(self): self.current_audio_track_name[self.current_audio_index] = str( self.audio_track_name_lineEdit.text()) def update_current_audio_delay(self): self.current_audio_delay[self.current_audio_index] = round( self.audio_delay_spin.value(), 5) def update_current_audio_language(self): self.current_audio_language[self.current_audio_index] = str( self.audio_language_comboBox.currentText()) def update_current_audio_set_default(self): new_state = self.audio_set_default_checkBox.checkState() == Qt.Checked self.current_audio_set_default[self.current_audio_index] = new_state if new_state: for i in range(len(self.current_audio_set_default)): if i != self.current_audio_index: self.current_audio_set_default[i] = False def update_current_audio_set_forced(self): new_state = self.audio_set_forced_checkBox.checkState() == Qt.Checked self.current_audio_set_forced[self.current_audio_index] = new_state if new_state: for i in range(len(self.current_audio_set_forced)): if i != self.current_audio_index: self.current_audio_set_forced[i] = False def reset_audio_setting(self): self.current_audio_language[ self.current_audio_index] = self.default_audio_language[ self.current_audio_index] self.current_audio_delay[ self.current_audio_index] = self.default_audio_delay[ self.current_audio_index] self.current_audio_track_name[ self.current_audio_index] = self.default_audio_track_name[ self.current_audio_index] self.current_audio_set_default[ self.current_audio_index] = self.default_audio_set_default[ self.current_audio_index] self.current_audio_set_forced[ self.current_audio_index] = self.default_audio_set_forced[ self.current_audio_index] self.audio_language_comboBox.setCurrentIndex( AllAudiosLanguages.index( self.current_audio_language[self.current_audio_index])) self.audio_delay_spin.setValue( float(self.current_audio_delay[self.current_audio_index])) self.audio_track_name_lineEdit.setText( self.current_audio_track_name[self.current_audio_index]) self.audio_set_default_checkBox.setChecked( bool(self.current_audio_set_default[self.current_audio_index])) self.audio_set_forced_checkBox.setChecked( bool(self.current_audio_set_forced[self.current_audio_index])) def audio_set_default_disable(self): self.audio_set_default_checkBox.setDisabled(True) def audio_set_forced_disable(self): self.audio_set_forced_checkBox.setDisabled(True) def setup_tool_tip_hint_audio_set_default(self): if self.audio_set_default_checkBox.isEnabled(): self.audio_set_default_checkBox.setToolTip( "<nobr>set this audio to be the default audio track " "when play") self.audio_set_default_checkBox.setToolTipDuration(12000) else: self.audio_set_default_checkBox.setToolTip( "<nobr>set this audio to be the default audio track when play<br><b>Disabled</b> because " "option " "<b>make this audio default</b> is enabled on mux setting tab " ) self.audio_set_default_checkBox.setToolTipDuration(12000) def setup_tool_tip_hint_audio_set_forced(self): if self.audio_set_forced_checkBox.isEnabled(): self.audio_set_forced_checkBox.setToolTip( "<nobr>set this audio to be the forced audio track when " "play") self.audio_set_forced_checkBox.setToolTipDuration(12000) else: self.audio_set_forced_checkBox.setToolTip( "<nobr>set this audio to be the forced audio track when play<br><b>Disabled</b> because " "option " "<b>make this audio default and forced</b> is enabled on mux setting tab " ) self.audio_set_forced_checkBox.setToolTipDuration(12000) def update_current_audio_index(self, new_index): self.current_audio_index = new_index self.audio_delay_spin.setValue( float(self.current_audio_delay[self.current_audio_index])) self.audio_set_default_checkBox.setChecked( bool(self.current_audio_set_default[self.current_audio_index])) self.audio_set_forced_checkBox.setChecked( bool(self.current_audio_set_forced[self.current_audio_index])) self.audio_language_comboBox.setCurrentIndex( AllAudiosLanguages.index( self.current_audio_language[self.current_audio_index])) self.audio_track_name_lineEdit.setText( self.current_audio_track_name[self.current_audio_index]) self.audio_name_value.setText( str(self.current_audio_name[self.current_audio_index])) def execute(self): self.exec_()
class SaveTab(QWidget): def __init__(self, parent): """Initialize the save tab """ super(SaveTab, self).__init__(parent) self.prefs = parent.prefs self.order_options = {'SortedOrder': 'Sorted (based on IDD file)', 'OriginalOrderTop': 'Original order (With new objects on top)', 'OriginalOrderBottom': 'Original order (With new objects on bottom)'} self.format_options = {'UseSpecialFormat': 'Use special formatting for some objects', 'None': 'Do not use special formatting'} # Sort Order Code order_label = QLabel("Save Order for Objects:") self.order_edit = QComboBox(self) self.order_edit.addItems(list(self.order_options.values())) self.order_edit.setMaximumWidth(350) order_setting = self.order_options[self.prefs['sort_order']] self.order_edit.setCurrentIndex(self.order_edit.findText(order_setting)) self.order_edit.currentIndexChanged.connect(self.update_order) format_label = QLabel("Special Formatting:") self.format_edit = QComboBox(self) self.format_edit.addItems(list(self.format_options.values())) self.format_edit.setMaximumWidth(350) format_setting = self.format_options[self.prefs['special_formatting']] self.format_edit.setCurrentIndex(self.format_edit.findText(format_setting)) self.order_edit.currentIndexChanged.connect(self.update_format) self.save_group_box = QGroupBox("Default Save Options") save_box = QVBoxLayout() save_box.addWidget(order_label) save_box.addWidget(self.order_edit) save_box.addSpacing(10) save_box.addWidget(format_label) save_box.addWidget(self.format_edit) save_box.addStretch(1) self.save_group_box.setLayout(save_box) self.save_group_box.setEnabled(False) # Save additional options code self.save_units_check = QCheckBox('Units to display by default (SI vs IP)', self) checked_header = Qt.Checked if self.prefs['save_units'] == 1 else Qt.Unchecked self.save_units_check.setCheckState(checked_header) self.save_units_check.stateChanged.connect(self.update) self.save_hidden_classes_check = QCheckBox('Whether empty classes are hidden', self) checked_cells = Qt.Checked if self.prefs['save_hidden_classes'] == 1 else Qt.Unchecked self.save_hidden_classes_check.setCheckState(checked_cells) self.save_hidden_classes_check.stateChanged.connect(self.update) self.save_groups_check = QCheckBox('Whether to hide group headers', self) checked_groups = Qt.Checked if self.prefs['save_hide_groups'] == 1 else Qt.Unchecked self.save_groups_check.setCheckState(checked_groups) self.save_groups_check.stateChanged.connect(self.update) # Save additional options group box code self.save_additional_group_box = QGroupBox("Save Additional Options in IDF File") save_additional_box = QVBoxLayout() save_additional_box.addWidget(self.save_units_check) save_additional_box.addWidget(self.save_hidden_classes_check) save_additional_box.addWidget(self.save_groups_check) save_additional_box.addStretch(1) self.save_additional_group_box.setLayout(save_additional_box) # Main layout code main_layout = QVBoxLayout() main_layout.addWidget(self.save_additional_group_box) main_layout.addSpacing(10) main_layout.addWidget(self.save_group_box) main_layout.addStretch(1) self.setLayout(main_layout) def update_order(self): text = self.order_edit.currentText() for key, val in list(self.order_options.items()): if val == text: to_save = key self.prefs['sort_order'] = to_save def update_format(self): text = self.format_edit.currentText() for key, val in self.format_options.items(): if val == text: to_save = key self.prefs['format'] = to_save def update(self): self.prefs['save_units'] = 1 if self.save_units_check.checkState() else 0 self.prefs['save_hidden_classes'] = 1 if self.save_hidden_classes_check.checkState() else 0 self.prefs['save_hide_groups'] = 1 if self.save_groups_check.checkState() else 0
class MyGui(QWidget, GitCmd): def __init__(self, title="Create By ZZZ", path=DEFAULT_GIT_REPO): super(MyGui, self).__init__() GitCmd.__init__(self, path) # 初始化命令 self.show_info = None self.cmd_history = None self.cmd_history_cmd_list = list() # 复选框 self.check_box_select_all = None self.check_box = list() self.check_box_button = None # 默认值 self.show_log_num = DEFAULT_GIT_LOG_NUM self.file_list = DEFAULT_GIT_ADD_LIST self.gridLayout = QGridLayout(self) self.setGeometry(100, 100, 800, 700) self.setWindowTitle(title) # 记录当前widget最大行号 self.max_line_no = 0 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 显示信息相关 def add_info_text(self): # 添加消息显示框,我们使用列表方式显示 self.show_info = QListWidget() self.show_info.setFixedSize(800, 600) self.gridLayout.addWidget(self.show_info, 0, 0, 1, 4) # 单击触发绑定的槽函数 self.show_info.itemClicked.connect(self.text_block_clicked) # 命令行显示,我们使用下拉框 self.cmd_history = QComboBox() self.gridLayout.addWidget(self.cmd_history, 1, 0, 1, 4) # 设置行号 self.max_line_no = 2 def add_cmd(self, cmd): if len(self.cmd_history_cmd_list) < 10: self.cmd_history_cmd_list.append(cmd) else: self.cmd_history_cmd_list = self.cmd_history_cmd_list[1:].append(cmd) self.cmd_history.clear() self.cmd_history.addItems(reversed(self.cmd_history_cmd_list)) def update_cmd(self, extra: str): cur_cmd = self.cmd_history.currentText().split(" ") new_cmd = cur_cmd[:2] + [extra] # 拆分出来git和后面的命令,拼接参数 if cur_cmd: self.cmd_history.setItemText(0, " ".join(new_cmd)) # 对每一行都进行上色 def my_print(self, text_list: list, background: list): # self.show_info.clear() 这个可以清空显示 self.show_info.addItems([". . . . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . . . "]) for ind in range(len(text_list)): item = QListWidgetItem('%s' % text_list[ind]) item.setBackground(QColor(background[ind])) # 上色 self.show_info.addItem(item) self.show_info.scrollToBottom() # 自动到最后行 @staticmethod def text_block_clicked(item): # 这里没有什么要做的 # QMessageBox.information(self, "命令历史", "你选择了: " + item.text()) pass # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 添加按钮 def add_git_button(self): cmd_add = QPushButton('Git Add') cmd_reset = QPushButton('Git Reset') cmd_status = QPushButton('Git Status') cmd_log = QPushButton('Git Log') cmd_run = QPushButton('Run Cmd') line_no = self.max_line_no self.gridLayout.addWidget(cmd_add, line_no, 0) self.gridLayout.addWidget(cmd_reset, line_no, 1) self.gridLayout.addWidget(cmd_status, line_no, 2) self.gridLayout.addWidget(cmd_log, line_no, 3) self.gridLayout.addWidget(cmd_run, line_no + 1, 0) self.max_line_no = self.max_line_no + 2 cmd_log.clicked.connect(self.git_log) cmd_add.clicked.connect(self.git_add) cmd_reset.clicked.connect(self.git_reset) cmd_status.clicked.connect(self.git_status) cmd_run.clicked.connect(self.run_git) def run_git(self): cur_cmd = self.cmd_history.currentText() # 执行代码 if cur_cmd.startswith("git add"): result, background = self.cmd_git_add(self.file_list) self.my_print(result, background) elif cur_cmd.startswith("git status"): result, background = self.cmd_git_status() self.my_print(result, background) elif cur_cmd.startswith("git log"): result, background = self.cmd_git_log(self.show_log_num) self.my_print(result, background) elif cur_cmd.startswith("git reset"): result, background = self.cmd_git_reset(self.file_list) self.my_print(result, background) def git_log(self): # 日常清理 self.cleanup() # 记录命令 self.add_cmd("git log -" + self.show_log_num) # 可以直接运行 self.run_git() def git_add(self): # 日常清理 self.cleanup() # 文件选择 files = self.get_file_list_by_status() self.create_check_box(files) # 记录命令 self.add_cmd("git add .") def git_status(self): # 日常清理 self.cleanup() # 记录命令 self.add_cmd("git status") # 可以直接运行 self.run_git() def git_reset(self): # 日常清理 self.cleanup() # 文件选择 files = self.get_file_list_by_status() self.create_check_box(files) # 记录命令 self.add_cmd("git reset .") # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 创建复选框 def create_check_box(self, opt_list: list): # 创建 self.check_box_select_all = QCheckBox('全选') # lambda可以传参:lambda: self.check_box_changes_all(<参数>) self.check_box_select_all.stateChanged.connect(lambda: self.check_box_changes_all()) for ind in range(len(opt_list)): self.check_box.append(QCheckBox(opt_list[ind])) self.check_box[ind].stateChanged.connect(lambda: self.check_box_changes()) # self.check_box_button = QPushButton('提交') # 布局 ind = self.max_line_no self.gridLayout.addWidget(self.check_box_select_all, ind, 0) ind = ind + 1 for check_box in self.check_box: self.gridLayout.addWidget(check_box, ind, 0) ind = ind + 1 # self.gridLayout.addWidget(self.check_box_button, ind, 0) # 添加按钮回调 # self.check_box_button.clicked.connect(self.check_box_ok) # 更新行号 # self.max_line_no = ind + 1 self.max_line_no = ind def check_box_ok(self): # 清除小部件 if self.check_box: self.file_list.clear() for check_box in self.check_box: # 更新列表 # if check_box.checkState() == Qt.Checked: # self.file_list.append(check_box.text()) # 清除 check_box.deleteLater() self.check_box.clear() if self.check_box_select_all: self.check_box_select_all.deleteLater() self.check_box_select_all = None if self.check_box_button: self.check_box_button.deleteLater() self.check_box_button = None def check_box_changes_all(self): if self.check_box_select_all.checkState() == Qt.Checked: for check_box in self.check_box: check_box.setChecked(True) elif self.check_box_select_all.checkState() == Qt.Unchecked: for check_box in self.check_box: check_box.setChecked(False) def check_box_changes(self): all_checked = True # one_checked = False self.file_list.clear() for check_box in self.check_box: if not check_box.isChecked(): all_checked = False # 只要有一个没勾选 else: self.file_list.append(check_box.text()) # 更新列表 # else: # one_checked = True # 只要有一个勾选 if all_checked: self.check_box_select_all.setCheckState(Qt.Checked) # elif one_checked: # self.check_box_select_all.setTristate() # 设置为3态选择框 # self.check_box_select_all.setCheckState(Qt.PartiallyChecked) # else: # self.check_box_select_all.setTristate() # 设置为3态选择框 # self.check_box_select_all.setCheckState(Qt.Unchecked) # 更新命令 files = " ".join(self.file_list) self.update_cmd(files) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 清理临时的小部件 def cleanup(self): self.check_box_ok() # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # 例子 def addButtonExample(self): # 创建一些小部件放在顶级窗口中 btn = QPushButton('press me') text = QLineEdit('enter text') listw = QListWidget() listw.addItems(["aa", "bb", "cc"]) # self.gridLayout = QGridLayout(self) # 将部件添加到布局中的适当位置, # addWidget参数:Widget实例, 起始row, 起始column, 占多少行(高度),占多少列(宽度) self.gridLayout.addWidget(btn, 0, 0) self.gridLayout.addWidget(text, 1, 0) self.gridLayout.addWidget(listw, 2, 0) # self.setLayout(self.gridLayout) # 画图1 def linePlot(self): plt1 = pg.PlotWidget() plt1.plot([i for i in range(10)], [i * i for i in range(10)]) self.gridLayout.addWidget(plt1, 0, 1, 1, 1) # 画图2 def scatterPlot(self): plt2 = pg.PlotWidget() x = np.random.normal(size=1000) y = np.random.normal(size=1000) plt2.plot(x, y, pen=None, symbol="o") self.gridLayout.addWidget(plt2, 1, 1, 1, 1) # 画图3 def three_curves(self): plt3 = pg.PlotWidget(title="Three plot curves") x = np.arange(1000) y = np.random.normal(size=(3, 1000)) for i in range(3): plt3.plot(x, y[i], pen=(i, 3)) # setting pen=(i,3) 自动创建3个不同颜色的笔 self.gridLayout.addWidget(plt3, 2, 1, 1, 1)
class MainWindow(QWidget): def __init__(self, appctx): super().__init__() self.appctx = appctx self.api = None self.settings = Settings() self.gateway = Gateway() self.timers: Dict[str, QTimer] = {} self.init_ui() def init_ui(self): self.vbox = QVBoxLayout() self.hbox = QHBoxLayout() # Set layout self.setLayout(self.vbox) # Group list vbox3 = QVBoxLayout() group_frame = QGroupBox("Device Groups") group_frame.setLayout(QVBoxLayout()) self.group_list = QListWidget() self.group_list.itemPressed.connect(self.group_selected) group_frame.layout().addWidget(self.group_list) vbox3.addWidget(group_frame) # Sliders self.group_toggle = QCheckBox("Power") self.group_toggle.setEnabled(False) vbox3.addWidget(self.group_toggle) vbox3.addWidget(QLabel("Brightness")) self.group_brightness_slider = QSlider(Qt.Orientation.Horizontal) self.group_brightness_slider.setEnabled(False) self.group_brightness_slider.sliderMoved.connect( self.group_brightness_changed) vbox3.addWidget(self.group_brightness_slider) vbox3.addWidget(QLabel("Color Temperature")) self.group_color_slider = QSlider(Qt.Orientation.Horizontal) self.group_color_slider.setEnabled(False) self.group_color_slider.sliderMoved.connect(self.group_color_changed) vbox3.addWidget(self.group_color_slider) self.hbox.addLayout(vbox3) # moods mood_frame = QGroupBox("Moods") mood_frame.setLayout(QVBoxLayout()) self.mood_list = QListWidget() self.mood_list.itemPressed.connect(self.mood_selected) mood_frame.layout().addWidget(self.mood_list) self.hbox.addWidget(mood_frame) # Devices in group vbox2 = QVBoxLayout() device_frame = QGroupBox("Devices in Group") device_frame.setLayout(QVBoxLayout()) self.device_list = QListWidget() self.device_list.setEnabled(False) self.device_list.itemPressed.connect(self.device_selected) device_frame.layout().addWidget(self.device_list) vbox2.addWidget(device_frame) # Sliders self.device_toggle = QCheckBox("Power") self.device_toggle.setEnabled(False) vbox2.addWidget(self.device_toggle) vbox2.addWidget(QLabel("Brightness")) self.brightness_slider = QSlider(Qt.Orientation.Horizontal) self.brightness_slider.setEnabled(False) self.brightness_slider.sliderMoved.connect(self.brightness_changed) vbox2.addWidget(self.brightness_slider) vbox2.addWidget(QLabel("Color Temperature")) self.color_slider = QSlider(Qt.Orientation.Horizontal) self.color_slider.setEnabled(False) self.color_slider.sliderMoved.connect(self.color_changed) vbox2.addWidget(self.color_slider) self.hbox.addLayout(vbox2) self.vbox.addLayout(self.hbox) # Settings button icon = QIcon(resource_path('icons/settings.png')) self.settings_button = QPushButton(icon, "Settings") self.settings_button.pressed.connect(self.settings_pressed) self.vbox.addWidget(self.settings_button) self.setWindowTitle('TradfriGUI') self.re_init() def re_init(self): if self.settings.gateway_ip is None or self.settings.gateway_ip == '': self.settings_pressed() self.api = get_api(self.settings) self.device_list.clear() self.group_list.clear() if self.api is None: return groups = self.api(self.gateway.get_groups()) if len(groups) == 0: self.group_list.setEnabled(False) # TODO: load devices directly for group in groups: item = self.api(group) list_item = QListWidgetItem(item.name, self.group_list) setattr(list_item, 'api_item', item) def group_selected(self): current_item = self.group_list.currentItem() item = getattr(current_item, 'api_item', None) if item is None: return # refresh from gateway item = self.api(self.gateway.get_group(item.id)) # load moods self.mood_list.clear() moods = self.api(item.moods()) for m in moods: mood = self.api(m) list_item = QListWidgetItem(mood.name, self.mood_list) setattr(list_item, 'api_item', mood) # load devices devices = item.members() self.device_list.clear() # determine shared state and add devices to list state = False color_temp = False min_color = 10000 max_color = 0 color = [] brightness = [] for d in devices: device = self.api(d) if device.has_light_control: if device.light_control.lights[0].state: state = True if device.light_control.can_set_dimmer: if device.light_control.lights[0].state: brightness.append( device.light_control.lights[0].dimmer) else: brightness.append(0) if device.light_control.can_set_temp: color_temp = True min_color = min(min_color, device.light_control.min_mireds) max_color = max(max_color, device.light_control.max_mireds) color.append(device.light_control.lights[0].color_temp) list_item = QListWidgetItem(device.name, self.device_list) setattr(list_item, 'api_item', device) if len(brightness) > 0: brightness = int(sum(brightness) / len(brightness)) else: brightness = 0 if len(color) > 0: color = int(sum(color) / len(color)) else: color = min_color # enable device list and controls self.device_list.setEnabled(True) self.group_brightness_slider.setEnabled(True) self.group_brightness_slider.setMinimum(0) self.group_brightness_slider.setMaximum(254) self.group_brightness_slider.setSingleStep(16) self.group_brightness_slider.setValue(brightness) if color_temp: self.group_color_slider.setEnabled(True) self.group_color_slider.setMinimum(min_color) self.group_color_slider.setMaximum(max_color) self.group_color_slider.setSingleStep( int((max_color - min_color) / 10)) self.group_color_slider.setValue(color) else: self.group_color_slider.setEnabled(False) self.group_toggle.setEnabled(True) try: self.group_toggle.stateChanged.disconnect(self.group_toggled) except RuntimeError: pass # Disconnect failed because nothing was connected self.group_toggle.setCheckState( Qt.CheckState.Checked if state else Qt.CheckState.Unchecked) self.group_toggle.stateChanged.connect(self.group_toggled) self.brightness_slider.setEnabled(False) self.color_slider.setEnabled(False) self.device_toggle.setEnabled(False) def device_selected(self): current_item = self.device_list.currentItem() item = getattr(current_item, 'api_item', None) if item is None: return # refresh from gateway item = self.api(self.gateway.get_device(item.id)) # enable appropriate controls if item.has_light_control: ctrl = item.light_control if ctrl.can_set_dimmer: self.brightness_slider.setEnabled(True) self.brightness_slider.setMinimum(0) self.brightness_slider.setMaximum(254) self.brightness_slider.setSingleStep(16) self.brightness_slider.setValue(ctrl.lights[0].dimmer) else: self.brightness_slider.setEnabled(False) if ctrl.can_set_temp: self.color_slider.setEnabled(True) self.color_slider.setMinimum(ctrl.min_mireds) self.color_slider.setMaximum(ctrl.max_mireds) self.color_slider.setSingleStep( int((ctrl.max_mireds - ctrl.min_mireds) / 10)) self.color_slider.setValue(ctrl.lights[0].color_temp) else: self.color_slider.setEnabled(False) self.device_toggle.setEnabled(True) try: self.device_toggle.stateChanged.disconnect(self.device_toggled) except RuntimeError: pass # disconnect failed because nothing was connected self.device_toggle.setCheckState( Qt.CheckState.Checked if ctrl.lights[0].state else Qt. CheckState.Unchecked) self.device_toggle.stateChanged.connect(self.device_toggled) else: self.brightness_slider.setEnabled(False) self.color_slider.setEnabled(False) self.device_toggle.setEnabled(False) def mood_selected(self): current_group = self.group_list.currentItem() group = getattr(current_group, 'api_item', None) if group is None: return # refresh from gateway group = self.api(self.gateway.get_group(group.id)) current_mood = self.mood_list.currentItem() mood = getattr(current_mood, 'api_item', None) if mood is None: return self.api(group.activate_mood(mood.id)) def group_brightness_changed(self): current_item = self.group_list.currentItem() if current_item is None: return item = getattr(current_item, 'api_item', None) command = item.set_dimmer(self.group_brightness_slider.value(), transition_time=2) self.queue_command('group_brightness', command) def group_color_changed(self): current_item = self.group_list.currentItem() if current_item is None: return item = getattr(current_item, 'api_item', None) command = item.set_color_temp(self.group_color_slider.value(), transition_time=2) self.queue_command('group_color', command) def brightness_changed(self): current_item = self.device_list.currentItem() if current_item is None: return item = getattr(current_item, 'api_item', None) command = item.light_control.set_dimmer(self.brightness_slider.value(), transition_time=2) self.queue_command('device_brightness_{}'.format(item.id), command) def color_changed(self): current_item = self.device_list.currentItem() if current_item is None: return item = getattr(current_item, 'api_item', None) command = item.light_control.set_color_temp(self.color_slider.value(), transition_time=2) self.queue_command('device_color_{}'.format(item.id), command) def device_toggled(self): current_item = self.device_list.currentItem() if current_item is None: return item = getattr(current_item, 'api_item', None) command = item.light_control.set_state( self.device_toggle.checkState() == Qt.CheckState.Checked) self.api(command) def group_toggled(self): current_item = self.group_list.currentItem() if current_item is None: return item = getattr(current_item, 'api_item', None) command = item.set_state( self.group_toggle.checkState() == Qt.CheckState.Checked) self.api(command) def settings_pressed(self): config = ConfigWindow(self.appctx, self) config.setWindowModality(Qt.ApplicationModal) config.exec_() # reload settings self.settings = config.settings # re-initialize window self.re_init() def queue_command(self, name, command): timer = self.timers.get(name, None) if timer is None: timer = QTimer() timer.setInterval(200) timer.setSingleShot(True) timer.timeout.connect(self.timeout) timer.start() setattr(timer, 'command', command) self.timers[name] = timer def timeout(self): remove = [] for key, item in self.timers.items(): if item.isActive() == False: cmd = getattr(item, 'command') self.api(cmd) remove.append(key) for key in remove: del self.timers[key]
class FilewriterCommandWidget(QWidget): """ Used for the required and optional fields when saving a filewriter command JSON file. """ def __init__(self, parent=None): super(FilewriterCommandWidget, self).__init__() self.setParent(parent) self.setLayout(QFormLayout()) self.nexus_file_name_edit = QLineEdit() self.ok_button = QPushButton("Ok") if parent is not None: self.ok_button.clicked.connect(parent.close) self.broker_line_edit = QLineEdit() self.broker_line_edit.setPlaceholderText("broker:port") self.ok_validator = CommandDialogOKValidator() self.ok_validator.is_valid.connect(self.ok_button.setEnabled) filename_validator = CommandDialogFileNameValidator() self.nexus_file_name_edit.setValidator(filename_validator) filename_validator.is_valid.connect( partial( validate_line_edit, self.nexus_file_name_edit, tooltip_on_reject= f"Invalid NeXus file name - Should end with {HDF_FILE_EXTENSIONS}", )) filename_validator.is_valid.connect( self.ok_validator.set_filename_valid) filename_validator.is_valid.emit(False) broker_validator = NameValidator([]) self.broker_line_edit.setValidator(broker_validator) broker_validator.is_valid.connect( partial( validate_line_edit, self.broker_line_edit, tooltip_on_reject="Broker is required", )) broker_validator.is_valid.connect(self.ok_validator.set_broker_valid) broker_validator.is_valid.emit(False) self.start_time_enabled = QCheckBox() self.start_time_picker = QDateTimeEdit(QDateTime.currentDateTime()) self.start_time_picker.setDisplayFormat(TIME_FORMAT) self.start_time_enabled.stateChanged.connect( partial(self.state_changed, True)) self.start_time_enabled.setChecked(True) self.stop_time_enabled = QCheckBox() self.stop_time_picker = QDateTimeEdit(QDateTime.currentDateTime()) self.stop_time_picker.setDisplayFormat(TIME_FORMAT) self.stop_time_enabled.stateChanged.connect( partial(self.state_changed, False)) self.stop_time_enabled.setChecked(False) self.state_changed(False, Qt.CheckState.Unchecked) self.service_id_lineedit = QLineEdit() self.service_id_lineedit.setPlaceholderText("(Optional)") self.abort_on_uninitialised_stream_checkbox = QCheckBox() self.use_swmr_checkbox = QCheckBox() self.use_swmr_checkbox.setChecked(True) self.layout().addRow("nexus_file_name", self.nexus_file_name_edit) self.layout().addRow("broker", self.broker_line_edit) self.layout().addRow("specify start time?", self.start_time_enabled) self.layout().addRow("start_time", self.start_time_picker) self.layout().addRow("specify stop time?", self.stop_time_enabled) self.layout().addRow("stop_time", self.stop_time_picker) self.layout().addRow("service_id", self.service_id_lineedit) self.layout().addRow("abort_on_uninitialised_stream", self.abort_on_uninitialised_stream_checkbox) self.layout().addRow("use_hdf_swmr", self.use_swmr_checkbox) self.layout().addRow(self.ok_button) def state_changed(self, is_start_time: bool, state: Qt.CheckState): if state != Qt.CheckState.Checked: self.start_time_picker.setEnabled( False) if is_start_time else self.stop_time_picker.setEnabled( False) else: self.start_time_picker.setEnabled( True) if is_start_time else self.stop_time_picker.setEnabled( True) def get_arguments( self, ) -> Tuple[str, str, Union[str, None], Union[str, None], str, bool, bool]: """ gets the arguments of required and optional fields for the filewriter command. :return: Tuple containing all of the fields. """ return ( self.nexus_file_name_edit.text(), self.broker_line_edit.text(), self.start_time_picker.dateTime().toMSecsSinceEpoch() if self.start_time_enabled.checkState() == Qt.CheckState.Checked else None, self.stop_time_picker.dateTime().toMSecsSinceEpoch() if self.stop_time_enabled.checkState() == Qt.CheckState.Checked else None, self.service_id_lineedit.text(), self.abort_on_uninitialised_stream_checkbox.checkState() == Qt.CheckState.Checked, self.use_swmr_checkbox.checkState() == Qt.CheckState.Checked, )
class ChartWin(QMainWindow): parent = None sheets = None num_param = 0 row = 0 canvas = None NavigationToolbar.toolitems = ( ('Home', 'Reset original view', 'home', 'home'), # ('Back', 'Back to previous view', 'back', 'back'), # ('Forward', 'Forward to next view', 'forward', 'forward'), (None, None, None, None), ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'), ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'), # ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'), (None, None, None, None), ('Save', 'Save the figure', 'filesave', 'save_figure'), ) def __init__(self, parent: QMainWindow, sheets: ExcelSPC, num_param: int, row: int): super().__init__(parent=parent) self.icons = Icons() self.parent = parent self.sheets = sheets self.num_param = num_param self.row = row self.initUI() self.setWindowIcon(QIcon(self.icons.CHART)) # ------------------------------------------------------------------------- # initUI - UI initialization # # argument # (none) # # return # (none) # ------------------------------------------------------------------------- def initUI(self): # ---------------- # Create toolbar toolbar = QToolBar() self.addToolBar(toolbar) # Add buttons to toolbar btn_before: QToolButton = QToolButton() btn_before.setIcon(QIcon(self.icons.LEFT)) btn_before.setStyleSheet("QToolButton {margin: 0 5px;}") btn_before.setStatusTip('goto previous PARAMETER') btn_before.clicked.connect(self.prev_chart) toolbar.addWidget(btn_before) # Add buttons to toolbar btn_after: QToolButton = QToolButton() btn_after.setIcon(QIcon(self.icons.RIGHT)) btn_after.setStyleSheet("QToolButton {margin: 0 5px;}") btn_after.setStatusTip('go to next PARAMETER') btn_after.clicked.connect(self.next_chart) toolbar.addWidget(btn_after) toolbar.addSeparator() self.check_update = QCheckBox('Hide Spec Limit(s)', self) self.check_update.setStyleSheet("QCheckBox {margin: 0 5px;}") self.checkbox_state() self.check_update.stateChanged.connect(self.update_status) toolbar.addWidget(self.check_update) # spacer to expand spacer: QWidget = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) # ComboBox to choose PowerPoint format self.ppt_format = bwidget.BComboBox(self) self.ppt_format.setText('PPT Format') self.ppt_format.addItems(['Default', 'Custom']) self.ppt_format.currentIndexChanged(self.selectionComboChange) toolbar.addWidget(self.ppt_format) toolbar.addSeparator() self.check_all_slides = QCheckBox('All parameters', self) toolbar.addWidget(self.check_all_slides) # PowerPoint but_ppt: QToolButton = QToolButton() but_ppt.setIcon(QIcon(self.icons.PPT)) but_ppt.setStatusTip('generate PowerPoint slide(s)') but_ppt.clicked.connect(self.OnPPT) toolbar.addWidget(but_ppt) # ------------ # Status Bar self.statusbar = QStatusBar() self.setStatusBar(self.statusbar) self.create_chart() self.show() # for combobox testing def selectionComboChange(self, i): sender = self.sender() print("Current index", i, "selection changed ", sender.currentText()) # ------------------------------------------------------------------------- # checkbox_state # # argument # (none) # # return # (none) # ------------------------------------------------------------------------- def checkbox_state(self): if self.sheets.get_SL_flag(self.row): self.check_update.setCheckState(Qt.Checked) else: self.check_update.setCheckState(Qt.Unchecked) # ------------------------------------------------------------------------- # update_status # # argument # state : # # return # (none) # ------------------------------------------------------------------------- def update_status(self, state): sender = self.sender() if sender.checkState() == Qt.Checked: flag_new: bool = True else: flag_new: bool = False flag_old = self.sheets.get_SL_flag(self.row) if flag_new is not flag_old: self.sheets.set_SL_flag(self.row, flag_new) self.create_chart() # ------------------------------------------------------------------------- # create_chart # # argument # (none) # # return # (none) # ------------------------------------------------------------------------- def create_chart(self): # Canvas for SPC Chart if self.canvas is not None: # CentralWidget self.takeCentralWidget() del self.canvas # DockWidget self.removeDockWidget(self.dock) self.dock.deleteLater() del self.navtoolbar # PART Number & PARAMETER Name name_part, name_param = self.get_part_param(self.row) self.updateTitle(name_part, name_param) # CentralWidget self.canvas: FigureCanvas = self.gen_chart(name_part, name_param) self.setCentralWidget(self.canvas) # DockWidget self.navtoolbar: NavigationToolbar = NavigationToolbar( self.canvas, self) self.dock: QDockWidget = QDockWidget('Navigation Toolbar') self.dock.setFeatures(QDockWidget.NoDockWidgetFeatures) self.dock.setWidget(self.navtoolbar) self.addDockWidget(Qt.BottomDockWidgetArea, self.dock) # update row selection of 'Master' sheet self.parent.setMasterRowSelect(self.row) # ------------------------------------------------------------------------- # get_part_param - get PART No & PARAMETER Name from sheet # # argument # row : row object on the Master Table # # return # part : PART Name # param : PPARAMETER Name # ------------------------------------------------------------------------- def get_part_param(self, row: int): df_master: pd.DataFrame = self.sheets.get_master() df_row: pd.Series = df_master.iloc[row] part: str = df_row['Part Number'] param: str = df_row['Parameter Name'] return part, param # ------------------------------------------------------------------------- # updateTitle - update window title # # argument # part : PART name # param : PARAMETER name # # return # (none) # ------------------------------------------------------------------------- def updateTitle(self, part: str, param: str): self.setWindowTitle(part + ' : ' + param) # ------------------------------------------------------------------------- # gen_chart - generate chart # # argument # part : PART Number # param : Parameter Name # sheet : data sheet from Excel file # # return # canvas : generated chart # ------------------------------------------------------------------------- def gen_chart(self, part: str, param: str): # create PowerPoint file info = { 'PART': part, 'PARAM': param, } trend: Trend = Trend(self, self.sheets, self.row) figure = trend.get(info) canvas: FigureCanvas = FigureCanvas(figure) return canvas # ------------------------------------------------------------------------- # next_chart # # argument # event : # # return # (none) # ------------------------------------------------------------------------- def next_chart(self, event: bool): if self.row >= self.num_param - 1: self.row = self.num_param - 1 return self.row += 1 self.update_chart() # ------------------------------------------------------------------------- # prev_chart # # argument # event : # # return # (none) # ------------------------------------------------------------------------- def prev_chart(self, event: bool): if self.row <= 0: self.row: int = 0 return self.row -= 1 self.update_chart() # ------------------------------------------------------------------------- # update_chart # # argument # (none) # # return # (none) # ------------------------------------------------------------------------- def update_chart(self): self.checkbox_state() self.create_chart() # ------------------------------------------------------------------------- # OnPPT # ------------------------------------------------------------------------- def OnPPT(self, event): template_path: str = 'template/template.pptx' image_path: str = tempfile.NamedTemporaryFile(suffix='.png').name save_path: str = tempfile.NamedTemporaryFile(suffix='.pptx').name # check box is checked? if self.check_all_slides.checkState() == Qt.Checked: # loop fpr all parameters loop = range(self.num_param) else: # This is single loop loop = [self.row] for row in loop: # get Parameter Name & PART Number name_part, name_param = self.get_part_param(row) # print(row + 1, name_part, name_param) # create PowerPoint file info = { 'PART': name_part, 'PARAM': name_param, 'IMAGE': image_path, } # create chart trend = Trend(self, self.sheets, row) figure = trend.get(info) dateObj = trend.get_last_date() # print(dateObj) # print(type(dateObj)) if dateObj is None: info['Date of Last Lot Received'] = 'n/a' elif type(dateObj) is float: if math.isnan(dateObj): info['Date of Last Lot Received'] = 'n/a' else: info['Date of Last Lot Received'] = str(dateObj) elif type(dateObj) is str: info['Date of Last Lot Received'] = dateObj else: info['Date of Last Lot Received'] = dateObj.strftime( '%m/%d/%Y') # create PNG file of plot figure.savefig(image_path) # gen_ppt(template_path, image_path, save_path, info) if self.check_all_slides.checkState() == Qt.Checked and row > 0: template_path = save_path ppt_obj = PowerPoint(template_path) ppt_obj.add_slide(self.sheets, info) ppt_obj.save(save_path) # open created file self.open_file_with_app(save_path) # ------------------------------------------------------------------------- # open_file_with_app # # argument # name_file : filename to open with associated application # # return # (none) # ------------------------------------------------------------------------- def open_file_with_app(self, name_file): path = pathlib.PurePath(name_file) if platform.system() == 'Linux': app_open = 'xdg-open' else: # Windows Explorer can cover all cases to start application with file app_open = 'explorer' subprocess.Popen([app_open, path])
class TopicSelection(QWidget): #recordSettingsSelected = Signal(bool, list) recordSettingsSelected = SIGNAL(str) def __init__(self): super(TopicSelection, self).__init__() master = rosgraph.Master('rqt_bag_recorder') self.setWindowTitle("Select the topics you want to record") self.resize(500, 700) self.topic_list = [] self.selected_topics = [] self.items_list = [] self.area = QScrollArea(self) self.main_widget = QWidget(self.area) self.ok_button = QPushButton("Record", self) self.ok_button.clicked.connect(self.onButtonClicked) self.ok_button.setEnabled(False) self.from_nodes_button = QPushButton("From Nodes", self) self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked) self.main_vlayout = QVBoxLayout(self) self.main_vlayout.addWidget(self.area) self.main_vlayout.addWidget(self.ok_button) self.main_vlayout.addWidget(self.from_nodes_button) self.setLayout(self.main_vlayout) self.selection_vlayout = QVBoxLayout(self) self.item_all = QCheckBox("All", self) self.item_all.stateChanged.connect(self.updateList) self.selection_vlayout.addWidget(self.item_all) topic_data_list = master.getPublishedTopics('') topic_data_list.sort() for topic, datatype in topic_data_list: self.addCheckBox(topic) self.main_widget.setLayout(self.selection_vlayout) self.area.setWidget(self.main_widget) self.show() def addCheckBox(self, topic): self.topic_list.append(topic) item = QCheckBox(topic, self) item.stateChanged.connect(lambda x: self.updateList(x, topic)) self.items_list.append(item) self.selection_vlayout.addWidget(item) def changeTopicCheckState(self, topic, state): for item in self.items_list: if item.text() == topic: item.setCheckState(state) return def updateList(self, state, topic=None, force_update_state=False): if topic is None: # The "All" checkbox was checked / unchecked if state == Qt.Checked: self.item_all.setTristate(False) for item in self.items_list: if item.checkState() == Qt.Unchecked: item.setCheckState(Qt.Checked) elif state == Qt.Unchecked: self.item_all.setTristate(False) for item in self.items_list: if item.checkState() == Qt.Checked: item.setCheckState(Qt.Unchecked) else: if state == Qt.Checked: self.selected_topics.append(topic) else: self.selected_topics.remove(topic) if self.item_all.checkState() == Qt.Checked: self.item_all.setCheckState(Qt.PartiallyChecked) if self.selected_topics == []: self.ok_button.setEnabled(False) else: self.ok_button.setEnabled(True) def onButtonClicked(self): self.close() self.recordSettingsSelected.emit( self.item_all.checkState() == Qt.Checked, self.selected_topics) def onFromNodesButtonClicked(self): self.node_selection = NodeSelection(self)
class FilterDock(QDockWidget): def __init__(self, platforms, regions, genres, years): super(FilterDock, self).__init__() # QDockWidget settings self.setAllowedAreas(Qt.BottomDockWidgetArea) self.setFeatures(QDockWidget.DockWidgetClosable) self.setFixedHeight(150) self.setVisible(False) self.setWindowTitle("Filter options") # The selected items for each widget are saved in a set-dictionary self._selections = defaultdict(set) # Widget settings # Platform widgets self._platformLabel = QLabel("Platform") self._platforms = QListWidget() self._platforms.addItems(platforms) self._platforms.setSelectionMode(QAbstractItemView.MultiSelection) self._platforms.setMaximumWidth(200) self._platformVBox = QVBoxLayout() self._platformVBox.addWidget(self._platformLabel, 0) self._platformVBox.addWidget(self._platforms, 1) # Region widgets self._regionLabel = QLabel("Region") self._regions = QListWidget() self._regions.addItems(regions) self._regions.setSelectionMode(QAbstractItemView.MultiSelection) self._regions.setMaximumWidth(200) self._regionVBox = QVBoxLayout() self._regionVBox.addWidget(self._regionLabel, 0) self._regionVBox.addWidget(self._regions, 1) # Genre widgets self._genreLabel = QLabel("Genre") self._genres = QListWidget() self._genres.addItems(genres) self._genres.setSelectionMode(QAbstractItemView.MultiSelection) self._genres.setMaximumWidth(300) self._genreVBox = QVBoxLayout() self._genreVBox.addWidget(self._genreLabel, 0) self._genreVBox.addWidget(self._genres, 1) # Year widgets self._yearLabel = QLabel("Year") self._years = QListWidget() self._years.addItems(years) self._years.setSelectionMode(QAbstractItemView.MultiSelection) self._years.setMaximumWidth(75) self._yearsVbox = QVBoxLayout() self._yearsVbox.addWidget(self._yearLabel, 0) self._yearsVbox.addWidget(self._years, 1) # Inventory widgets self._itemType = {1: "Game", 2: "Console", 3: "Accessory"} self._item = QCheckBox(self._itemType[1]) self._item.setTristate(True) self._item.setCheckState(Qt.PartiallyChecked) self._manual = QCheckBox("Manual") self._manual.setTristate(True) self._manual.setCheckState(Qt.PartiallyChecked) self._box = QCheckBox("Box") self._box.setTristate(True) self._box.setCheckState(Qt.PartiallyChecked) self._inventoryLabelsVBox = QVBoxLayout() self._inventorySelectionsVBox = QVBoxLayout() self._inventorySelectionsVBox.addStretch(3) self._inventorySelectionsVBox.addWidget(self._item, 0) self._inventorySelectionsVBox.addWidget(self._box, 1) self._inventorySelectionsVBox.addWidget(self._manual, 2) self._inventorySelectionsVBox.setAlignment(Qt.AlignLeft) self._haveHBox = QHBoxLayout() self._haveHBox.addLayout(self._inventoryLabelsVBox, 0) self._haveHBox.addLayout(self._inventorySelectionsVBox, 1) self._inventoryGroup = QGroupBox("Inventory") self._inventoryGroup.setMaximumWidth(120) self._inventoryGroup.setLayout(self._haveHBox) # Clear and Apply button widgets self._clearBtn = QPushButton("Clear selection") self._clearBtn.setMaximumSize(self._clearBtn.sizeHint()) self._clearBtn.clicked.connect(self._clearFilters) self._btnHBox = QHBoxLayout() self._btnHBox.setAlignment(Qt.AlignBottom | Qt.AlignRight) self._btnHBox.addWidget(self._clearBtn, 0) # General layout mainHBox = QHBoxLayout() mainHBox.setAlignment(Qt.AlignLeft) mainHBox.addLayout(self._platformVBox, 0) mainHBox.addLayout(self._regionVBox, 0) mainHBox.addLayout(self._genreVBox, 0) mainHBox.addLayout(self._yearsVbox, 0) mainHBox.addWidget(self._inventoryGroup, 0) mainHBox.addLayout(self._btnHBox, 0) mainWidget = QWidget() mainWidget.setLayout(mainHBox) self.setWidget(mainWidget) def _clearFilters(self): self._platforms.clearSelection() self._regions.clearSelection() self._genres.clearSelection() self._years.clearSelection() self._item.setCheckState(Qt.PartiallyChecked) self._box.setCheckState(Qt.PartiallyChecked) self._manual.setCheckState(Qt.PartiallyChecked) logger.info("Cleared all filters.") def getSelections(self): self._selections = defaultdict(set) # Reset selections if len(self._platforms.selectedItems()) > 0: platforms = [x.text() for x in self._platforms.selectedItems()] for platform in platforms: self._selections["Platform"].add(platform) if len(self._regions.selectedItems()) > 0: regions = [x.text() for x in self._regions.selectedItems()] for region in regions: self._selections["Region"].add(region) if len(self._genres.selectedItems()) > 0: genres = [x.text() for x in self._genres.selectedItems()] for genre in genres: self._selections["Genre"].add(genre) if len(self._years.selectedItems()) > 0: years = [x.text() for x in self._years.selectedItems()] for year in years: self._selections["Year"].add(year) if self._item.checkState() is not Qt.PartiallyChecked: self._selections[self._item.text()].add("Yes" if self._item.isChecked() else "No") if self._manual.checkState() is not Qt.PartiallyChecked: self._selections["Manual"].add("Yes" if self._manual.isChecked() else "No") if self._box.checkState() is not Qt.PartiallyChecked: self._selections["Box"].add("Yes" if self._box.isChecked() else "No") return self._selections def setItemType(self, itemType: int): if 0 < itemType < 4: if self._item.text() in self._selections: # Delete previous item entry so we don't search for the wrong type in the wrong table del self._selections[self._item.text()] self._item.setText(self._itemType[itemType]) def toggleVisibility(self): self.setVisible(False if self.isVisible() else True) def updatePlatforms(self, platforms): self._platforms.clear() self._platforms.addItems(platforms) logger.info("Updated platforms list.") def updateRegions(self, regions): self._regions.clear() self._regions.addItems(regions) logger.info("Updated regions list.") def updateGenres(self, genres): self._genres.clear() self._genres.addItems(genres) logger.info("Updated genres list.") def updateYears(self, years): self._years.clear() self._years.addItems(years) logger.info("Updated years list.")
class StatsManager: GROUP_BY = ['filename', 'lineno', 'traceback'] # index in the combo box GROUP_BY_FILENAME = 0 GROUP_BY_LINENO = 1 GROUP_BY_TRACEBACK = 2 def __init__(self, window, app): self.app = app self.window = window self.snapshots = window.snapshots self.source = window.source self.filename_parts = 3 self._auto_refresh = False self.filters = [] self.history = History(self) self.model = StatsModel(self) self.view = QTableView(window) self.view.setModel(self.model) self.cumulative_checkbox = QCheckBox(window.tr("Cumulative sizes"), window) self.group_by = QtGui.QComboBox(window) self.group_by.addItems([ window.tr("Filename"), window.tr("Line number"), window.tr("Traceback"), ]) self.filters_label = QLabel(window) self.summary = QLabel(window) self.view.verticalHeader().hide() self.view.resizeColumnsToContents() self.view.setSortingEnabled(True) window.connect(self.group_by, QtCore.SIGNAL("currentIndexChanged(int)"), self.group_by_changed) window.connect(self.view, QtCore.SIGNAL("doubleClicked(const QModelIndex&)"), self.double_clicked) window.connect(self.cumulative_checkbox, QtCore.SIGNAL("stateChanged(int)"), self.change_cumulative) window.connect(self.snapshots.load_button, QtCore.SIGNAL("clicked(bool)"), self.load_snapshots) window.connect( self.view.selectionModel(), QtCore.SIGNAL( "selectionChanged(const QItemSelection&, const QItemSelection&)" ), self.selection_changed) self.clear() self._auto_refresh = True def clear(self): del self.filters[:] self.cumulative_checkbox.setCheckState(Qt.Unchecked) self.group_by.setCurrentIndex(self.GROUP_BY_FILENAME) self.history.clear() self.append_history() self.refresh() def load_snapshots(self, checked): self.source.clear() self.clear() def append_history(self): group_by = self.group_by.currentIndex() filters = self.filters[:] cumulative = self.cumulative_checkbox.checkState() state = HistoryState(group_by, filters, cumulative) self.history.append(state) def restore_state(self, state): self.filters = state.filters[:] self._auto_refresh = False self.cumulative_checkbox.setCheckState(state.cumulative) self.group_by.setCurrentIndex(state.group_by) self._auto_refresh = True self.refresh() def format_filename(self, filename): parts = filename.split(os.path.sep) if len(parts) > self.filename_parts: parts = [MORE_TEXT] + parts[-self.filename_parts:] return os.path.join(*parts) def get_group_by(self): index = self.group_by.currentIndex() return self.GROUP_BY[index] def get_cumulative(self): return (self.cumulative_checkbox.checkState() == Qt.Checked) def refresh(self): group_by = self.get_group_by() if group_by != 'traceback': cumulative = self.get_cumulative() else: # FIXME: add visual feedback cumulative = False snapshot1, snapshot2 = self.snapshots.load_snapshots(self.filters) self.view.clearSelection() group_by = self.get_group_by() self.model.set_stats(snapshot1, snapshot2, group_by, cumulative) self.view.resizeColumnsToContents() self.view.sortByColumn(self.model.get_default_sort_column(), Qt.DescendingOrder) if self.filters: filters = [] for filter in self.filters: text = self.format_filename(filter.filename_pattern) if filter.lineno: text = "%s:%s" % (text, filter.lineno) if filter.all_frames: text += self.window.tr(" (any frame)") if filter.inclusive: text = fmt(self.window.tr("include %s"), text) else: text = fmt(self.window.tr("exclude %s"), text) filters.append(text) filters_text = ", ".join(filters) else: filters_text = self.window.tr("(none)") filters_text = fmt(self.window.tr("Filters: %s"), filters_text) self.filters_label.setText(filters_text) total = self.model.total_text lines = len(self.model.stats) if group_by == 'filename': lines = fmt(self.window.tr("Files: %s"), lines) elif group_by == 'lineno': lines = fmt(self.window.tr("Lines: %s"), lines) else: lines = fmt(self.window.tr("Tracebacks: %s"), lines) total = fmt(self.window.tr("%s - Total: %s"), lines, total) self.summary.setText(total) def selection_changed(self, selected, unselected): indexes = selected.indexes() if not indexes: return stat = self.model.get_stat(indexes[0]) if stat is None: return self.source.set_traceback(stat.traceback, self.get_group_by() != 'filename') self.source.show_frame(stat.traceback[0]) def double_clicked(self, index): stat = self.model.get_stat(index) if stat is None: return group_by = self.get_group_by() if group_by == 'filename': all_frames = self.get_cumulative() self.filters.append( tracemalloc.Filter(True, stat.traceback[0].filename, all_frames=all_frames)) self._auto_refresh = False self.group_by.setCurrentIndex(self.GROUP_BY_LINENO) self.append_history() self._auto_refresh = True self.refresh() elif group_by == 'lineno': # Replace filter by filename with filter by line new_filter = tracemalloc.Filter(True, stat.traceback[0].filename, stat.traceback[0].lineno, all_frames=False) if self.filters: old_filter = self.filters[-1] replace = (old_filter.inclusive == new_filter.inclusive and old_filter.filename_pattern == new_filter.filename_pattern and old_filter.lineno == None) else: replace = False if replace: self.filters[-1] = new_filter else: self.filters.append(new_filter) self._auto_refresh = False self.group_by.setCurrentIndex(self.GROUP_BY_TRACEBACK) self.append_history() self._auto_refresh = True self.refresh() def group_by_changed(self, index): if not self._auto_refresh: return self.append_history() self.refresh() def change_cumulative(self, state): if not self._auto_refresh: return self.append_history() self.refresh()
class MainWindow(QMainWindow): def __init__(self, backlight_sysfs_path: Path) -> None: QMainWindow.__init__(self) self.backlight = Backlight(backlight_sysfs_path) self.screenshot = QPixmap(get_image_path("raspbian.png")) self.image_display_on = load_display_image( get_image_path("display_on.png")) self.image_display_off = load_display_image( get_image_path("display_off.png")) widget = QWidget() checkbox_layout = QBoxLayout(QBoxLayout.LeftToRight) main_layout = QBoxLayout(QBoxLayout.TopToBottom) brightness_slider_label = QLabel("Brightness", widget) self.live_screen_checkbox = QCheckBox("Show live screen", widget) self.live_screen_checkbox.stateChanged.connect(self.update_screen) self.power_checkbox = QCheckBox("Power", widget) self.power_checkbox.stateChanged.connect(self.write_power_change) self.brightness_slider = QSlider(Qt.Horizontal, widget) self.brightness_slider.valueChanged.connect( self.write_brightness_change) self.brightness_slider.setSingleStep(1) self.brightness_slider.setMinimum(0) self.brightness_slider.setMaximum(100) self.screen_image = QLabel() checkbox_layout.addWidget(self.power_checkbox) checkbox_layout.addWidget(self.live_screen_checkbox) main_layout.addLayout(checkbox_layout) main_layout.addWidget(brightness_slider_label) main_layout.addWidget(self.brightness_slider) main_layout.addWidget(self.screen_image) widget.setLayout(main_layout) self.thread = FileWatcherThread(self, backlight_sysfs_path) self.thread.file_changed.connect(self.update_widgets) self.thread.start() self.timer = QTimer(self) self.timer.setInterval(100) self.timer.timeout.connect(self.update_screen) self.timer.start() self.update_widgets("bl_power") self.update_widgets("brightness") self.setCentralWidget(widget) self.setWindowTitle('Raspberry Pi 7" display backlight emulator') self.setWindowIcon(QIcon(get_image_path("icon.png"))) def write_power_change(self): on = self.power_checkbox.checkState() == Qt.CheckState.Checked self.backlight.power = on def write_brightness_change(self): value = self.brightness_slider.value() self.backlight.brightness = value def update_widgets(self, filename: str) -> None: if filename == "bl_power": self.power_checkbox.setChecked(self.backlight.power) if filename == "brightness": self.brightness_slider.setValue(self.backlight.brightness) def update_screen(self) -> None: use_live_screen = ( self.live_screen_checkbox.checkState() == Qt.CheckState.Checked) is_powered_on = self.power_checkbox.checkState( ) == Qt.CheckState.Checked image_display = (self.image_display_on if is_powered_on else self.image_display_off) result = QPixmap(image_display.size()) result.fill(Qt.transparent) painter = QPainter(result) painter.drawPixmap(QPoint(0, 0), image_display) if is_powered_on: screenshot = get_screenshot( ) if use_live_screen else self.screenshot screenshot = screenshot.scaled(800, 800, Qt.KeepAspectRatio, Qt.SmoothTransformation) screenshot = screenshot.copy(QRect(0, 0, 800, 480 * 0.94)) offset_x = (image_display.size().width() - screenshot.size().width()) / 2 offset_y = (image_display.size().height() - screenshot.size().height()) / 2 painter.setOpacity(self.backlight.brightness / 100) painter.drawPixmap(QPoint(offset_x, offset_y), screenshot) painter.end() result = result.scaled(600, 600, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.screen_image.setPixmap(result) def closeEvent(self, event) -> None: self.thread.interrupt() self.thread.quit() self.thread.wait() self.timer.stop() super(MainWindow, self).closeEvent(event)
class MainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.inputsToSkip = { "SceneInput": 0, "MaterialInput": 1, "Diffuse Color Material": 2, } self.data_types_to_skip = { "Image": 0, "ColorCurves": 1, "Histogram": 2, "Mask": 3, "DataType3D": 4, "Gradient": 5, "MtlGraph3D": 6, } self.createWidgets() self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint) def createWidgets(self): self._tm = TableModel(self) self._tm.inputsToSkip = self.inputsToSkip self._tm.data_types_to_skip = self.data_types_to_skip self._tv = TableView(self) self.alwaysOnTop = QCheckBox("Always on top") self.alwaysOnTop.setChecked(True) self.drawInputInfoColors = QToolButton() self.drawInputInfoColors.setCheckable(True) self.drawInputInfoColors.setChecked(True) self.drawInputInfoColors.setText("Draw Color Info") self.pushButton = QPushButton() self.pushButton.setText("Refresh") self.pushButton.setFixedSize(QSize(128, 20)) self.lineEdit = QLineEdit(self) self.lineEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.statusBar().showMessage("System Status | Normal") self.cacheButton = QToolButton() self.cacheButton.setCheckable(True) self.cacheButton.setChecked(False) self.cacheButton.setText("use cache") v_box = QVBoxLayout() h_box = QHBoxLayout() h_box.setAlignment(Qt.AlignRight) h_box.addWidget(self.alwaysOnTop) h_box.addWidget(self.lineEdit) h_box.addWidget(self.pushButton) h_box.addWidget(self.drawInputInfoColors) h_box.addWidget(self.cacheButton) h_box.setContentsMargins(0, 0, 0, 0) v_box.addLayout(h_box) v_box.addWidget(self._tv) sizeGrip = QSizeGrip(self) # sizeGrip.setParent(self) # v_box.addWidget(sizeGrip) # v_box.setAlignment(sizeGrip, Qt.AlignBottom | Qt.AlignRight) v_box.setContentsMargins(2, 2, 2, 2) # v_box.setSpacing(0) sizeGrip.setWindowFlags(Qt.WindowStaysOnTopHint) sizeGrip.move(0, 200) central_widget = QWidget() central_widget.setLayout(v_box) self.setCentralWidget(central_widget) self.statusBar() self.proxyModel = TableSortFilterProxyModel() self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive) self.proxyModel.setDynamicSortFilter(True) self.drawInputInfoColors.setChecked(True) # self.lineEdit.textChanged.connect(self._tv.updateColumns) # self.proxyModel.setSourceModel(self._tm) # self.proxyModel.filteredKeys = self._tm.attributeNameKeys self._tv.setModel(self.proxyModel) self.progressBar = QProgressBar() self.statusBar().addPermanentWidget(self.progressBar) # This is simply to show the bar # self.progressBar.setGeometry(30, 40, 200, 25) self.progressBar.setValue(0) # Connections self.alwaysOnTop.stateChanged.connect(self.changeAlwaysOnTop) self.lineEdit.textChanged.connect(self.filterRegExpChanged) self.drawInputInfoColors.clicked.connect( self.changeTableModelBackgroundRoleMethod) self.cacheButton.clicked.connect(self.changeCacheMode) self.pushButton.pressed.connect(self.reloadFusionData) self._tm.communicate.broadcast.connect(self.communication) def changeAlwaysOnTop(self): if self.alwaysOnTop.checkState(): self.setWindowFlags(self.windowFlags() | Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint) self.show() else: self.setWindowFlags(self.windowFlags() ^ (Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint)) self.show() def communication(self, value): if not value: return if isinstance(value, float): self.progressBar.setValue(value) if isinstance(value, str): self.statusBar().showMessage(value) def loadFusionData(self): self._tm.load_fusion_data() self.proxyModel.setSourceModel(self._tm) self._tv.setSortingEnabled(True) self._tv.updateColumns() def reloadFusionData(self): self.proxyModel.setSourceModel(None) self._tm.load_fusion_data() self.proxyModel.setSourceModel(self._tm) self._tv.setSortingEnabled(True) self._tv.updateColumns() def changeCacheMode(self): # Not sure where this goes, is it a method for the TableModel? or should we inherit the dict that has all # the fusion input caches and have that cycle through all contained fusion inputs? # For now we do it here c = self.cacheButton.isChecked() for input_list in self._tm.toolsInputs: for tool_input in list(input_list.values()): tool_input.cache = c def changeTableModelBackgroundRoleMethod(self): if self.drawInputInfoColors.isChecked(): self._tm.backgroundRoleMethod = self._tm.backgroundRole else: self._tm.backgroundRoleMethod = self._tm.noRole def filterRegExpChanged(self): """ This makes sure that the ItemDelegates for the TableView columns get updated, we have to do this as for some reason Qt has TableView column delegates decoupled from the underlying ProxyModel and indices get out of sync during sorting and filtering. """ regExp = self.lineEdit.text() self.proxyModel.filteredKeys = [] self.proxyModel.setFilterRegExp(regExp) self._tv.updateColumns()
class MainWindow(QMainWindow): def __init__(self): super().__init__(flags=Qt.WindowContextHelpButtonHint | Qt.WindowCloseButtonHint | Qt.CustomizeWindowHint) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setUpMainWindow() def setUpMainWindow(self): self.setWindowTitle( "Lab Tools 1.0 (2021 Edition) - Applications of ML in Mechatronics" ) # set icon self.setUpIcon() #set up the info and start processing button self.inputLineEdit = QLineEdit() self.outputFolderLineEdit = QLineEdit() self.modelLineEdit = QLineEdit() self.browseOutputButton = QPushButton() self.browseInputButton = QPushButton() self.browseModelButton = QPushButton() self.startStopButton = QPushButton() self.useDefaultModelCheckbox = QCheckBox() self.inputLineEdit = self.findChild(QLineEdit, "inputLineEdit") self.modelLineEdit = self.findChild(QLineEdit, "modelLineEdit") self.outputFolderLineEdit = self.findChild(QLineEdit, "outputFolderLineEdit") self.browseOutputButton = self.findChild(QPushButton, "browseOutputButton") self.browseInputButton = self.findChild(QPushButton, "browseInputButton") self.browseModelButton = self.findChild(QPushButton, "browseModelButton") self.startStopButton = self.findChild(QPushButton, "startStopButton") self.useDefaultModelCheckbox = self.findChild( QCheckBox, "useDefaultModelCheckbox") self.chooseModelLabel = self.findChild(QLabel, "chooseModelLabel") #disabling model transfer capability if needed self._modelRPiPath = False if DISABLE_MODEL_TRASFER: self.useDefaultModelCheckbox.hide() self.modelLineEdit.setEnabled(1) self.browseModelButton.hide() self.chooseModelLabel.setText(self.chooseModelLabel.text() + " Name") # self.gridLayout = self.findChild(QGridLayout, "gridLayout") # self.gridLayout.removeWidget(self.browseModelButton) # self.gridLayout.removeWidget(self.useDefaultModelCheckbox) self._modelRPiPath = True self.startStopButton.clicked.connect(self.handleStartStopButtonClicked) self.browseOutputButton.clicked.connect(self.handleBrowseOutputButton) self.browseInputButton.clicked.connect(self.handleBrowseInputButton) self.browseModelButton.clicked.connect(self.handleBrowseModelButton) self.useDefaultModelCheckbox.stateChanged.connect( self.handleUseDefaultModelCheckboxStateChanged) self.useDefaultModelCheckbox.setChecked(True) #set up the log and progress bar self.logTextBrowser = QTextBrowser() self.lastLogTextLabel = QLabel() self.logTextBrowser = self.findChild(QTextBrowser, "logTextBrowser") self.progressBar = self.findChild(QProgressBar, "progressBar") self.clearLogButton = self.findChild(QPushButton, "clearLogButton") self.saveLogButton = self.findChild(QPushButton, "saveLogButton") self.lastLogTextLabel = self.findChild(QLabel, "lastLogTextLabel") self.clearLogButton.clicked.connect(self.handleClearLogButton) self.saveLogButton.clicked.connect(self.handleSaveLogButton) #set up menu bar self.actionHelp = self.findChild(QAction, "actionHelp") self.actionAbout = self.findChild(QAction, "actionAbout") self.actionHelp.triggered.connect(self.handleActionHelpClicked) self.actionAbout.triggered.connect(self.handleActionAboutClicked) # Add additional menu actions self.utilitiesMenu = self.menuBar().addMenu("Utilities") self.actionGetRPiIP = QAction("Get RPi IP") self.utilitiesMenu.addAction(self.actionGetRPiIP) self.actionGetRPiIP.triggered.connect(self.handleActionGetRPiIPClicked) self.actionUpdateRPiScript = QAction("Updare RPi Script") self.utilitiesMenu.addAction(self.actionUpdateRPiScript) self.actionUpdateRPiScript.triggered.connect( self.handleActionUpdateRPiScript) #create objects from the other classes self.logger = Logger(self.logTextBrowser, self.lastLogTextLabel) #initialize member variables self._b_processRunning = False # set up lab names self.setUpLabNames() #set up serial comms self.setupSerial() self.refreshSerialPorts() self.logger.log("The application is ready!", type="INFO") def setUpIcon(self): self.appIcon = QIcon("images/favicon.png") self.setWindowIcon(self.appIcon) def setUpLabNames(self): self.labNameComboBox = QComboBox() self.labNameComboBox = self.findChild(QComboBox, "labNameComboBox") self.labNameComboBox.currentIndexChanged.connect( self.handleLabNameComboboxCurrentIndexChanged) for code, name in utils.lab_names.items(): self.labNameComboBox.addItem(code + ": " + name) self.labNameComboBox.setCurrentIndex(1) def setupSerial(self): self.refreshSerialPortsButton = QPushButton() self.connectDisconnectSerialButton = QPushButton() self.serialPortComboBox = QComboBox() self.refreshSerialPortsButton = self.findChild( QPushButton, "refreshSerialPortsButton") self.connectDisconnectSerialButton = self.findChild( QPushButton, "connectDisconnectSerialButton") self.serialPortComboBox = self.findChild(QComboBox, "serialPortComboBox") self.refreshSerialPortsButton.clicked.connect(self.refreshSerialPorts) self.connectDisconnectSerialButton.clicked.connect( self.handleSerialConnectDisconnect) self._b_serialConnected = False def refreshSerialPorts(self): availablePorts = utils.find_serial_ports() self.serialPortComboBox.clear() for portName in availablePorts: self.serialPortComboBox.addItem(portName) def handleSerialConnectDisconnect(self): if not self.b_serialConnected: try: currentPortName = self.serialPortComboBox.currentText() self.port = serial.Serial(currentPortName, 115200, timeout=1, write_timeout=240, bytesize=8, parity='N', stopbits=1) self.port.set_buffer_size(rx_size=10**3, tx_size=10**8) self.serialPortComboBox.setItemText( self.serialPortComboBox.currentIndex(), currentPortName + " (CONNECTED)") self.connectDisconnectSerialButton.setText("Disconnect") self.b_serialConnected = True self.refreshSerialPortsButton.setDisabled(1) except (OSError, serial.SerialException): print("Problem with Serial Connection!") self.logger.log( "Problem with Serial Connection, Make sure you chose the right port", type="ERROR") else: try: self.port.close() self.refreshSerialPorts() self.connectDisconnectSerialButton.setText("Connect") self.b_serialConnected = False self.refreshSerialPortsButton.setEnabled(1) except (OSError, serial.SerialException): print("Problem with Serial Connection!") self.logger.log("Problem with Serial Connection", type="ERROR") def _startButtonClicked(self): self.logger.log("Attempting to start the processing", type="INFO") if not self.b_serialConnected: self.logger.log( "Serial is not connected, Please connect serial first", type="ERROR") return if self.inputLineEdit.text()[-4:].lower() != ".csv": self.logger.log("Please select a valid input csv file", type="ERROR") return if self.outputFolderLineEdit.text() == "": self.logger.log("Please select an output directory", type="ERROR") return self.executer = Executer(serialObj=self.port, loggerObj=self.logger) if self.modelLineEdit.text() != "": modelPath = self.modelLineEdit.text() else: modelPath = None if self._modelRPiPath: self.logger.log( "Please select a valid model that is already available in the folder saved_models on the RPi", type="ERROR") return #Read the Input File try: inputDataFrame = pd.read_csv(self.inputLineEdit.text()) except: self.logger.log("CSV File Reading Failed, select a valid csv file", type="ERROR") possibleInputs = list(inputDataFrame.columns) #Display a dialog to ask the user to choose what inputs they want dialog = QDialog(self) dialog.setWindowTitle("Select the Input Fields") dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0) dialogButtons.accepted.connect(dialog.accept) dialogButtons.rejected.connect(dialog.reject) mainLayout = QVBoxLayout(dialog) scroll = QScrollArea(dialog) scroll.setWidgetResizable(True) layoutWidget = QWidget() layout = QVBoxLayout(layoutWidget) scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setWidget(layoutWidget) chosenInputs = [] checkboxes = [] def handleCheckboxClicked(): dialogButtons.button(QDialogButtonBox.Ok).setDisabled(1) for checkbox in checkboxes: if checkbox.isChecked(): dialogButtons.button(QDialogButtonBox.Ok).setDisabled(0) for input in possibleInputs: checkbox = QCheckBox(text=input) checkbox.clicked.connect(handleCheckboxClicked) checkbox.setChecked(True) checkboxes.append(checkbox) layout.addWidget(checkbox) mainLayout.addWidget( QLabel(text="Please select the input fields from the following:")) mainLayout.addWidget(scroll) mainLayout.addWidget(dialogButtons) dialog.setLayout(mainLayout) # dialog.setFixedHeight(400) if dialog.exec_() == QDialog.Accepted: for checkbox in checkboxes: if checkbox.isChecked(): chosenInputs.append(checkbox.text()) self.logger.log("The chosen input fields are: " + ', '.join(chosenInputs), type="INFO") else: return self.startStopButton.setText("Stop Processing") self.b_processRunning = True executionResult = self.executer.execute(self.labNameComboBox.currentText().split(":")[0], inputDataFrame, \ self.outputFolderLineEdit.text(), inputFields=chosenInputs, progressBar=self.progressBar, \ model=modelPath if not self._modelRPiPath else "RPI:"+modelPath) if executionResult == ExecutionResult.COMPLETED: self._stopButtonClicked(finishedProcessing=True) elif executionResult == ExecutionResult.INTERRUPTED or executionResult == ExecutionResult.FAILED: self._stopButtonClicked() if self.executer.reset() == ExecutionResult.FAILED: self.logger.log( "Resetting the serial state of RPi Failed, please power cycle the RPi", type="ERROR") else: self.logger.log("The serial state of RPi has been reset", type="INFO") def _stopButtonClicked(self, finishedProcessing=False): self.startStopButton.setText("Start Processing") if finishedProcessing: self.logger.log("", special="ProcessingCompleted") else: self.logger.log("", special="ProcessingStopped") self.b_processRunning = False #TODO: Complete Implementing this def handleStartStopButtonClicked(self): if (self.b_processRunning): self.executer.requestStop() else: self._startButtonClicked() def handleActionHelpClicked(self): helpBox = QMessageBox() helpBox.setIcon(QMessageBox.Information) helpBox.setStandardButtons(QMessageBox.Ok) helpBox.setWindowTitle("Need Help?") helpBox.setText( "For Help, please reach out to your Instructor or TA or read the lab manual" ) helpBox.setTextFormat(Qt.RichText) helpBox.setInformativeText( f"You can access the project <a href=\"{utils.docs_link}\">Manual</a> and source in the <a href=\"{utils.repo_link}\">Github Repo!</a>" ) helpBox.setWindowIcon(self.appIcon) helpBox.exec_() def handleActionAboutClicked(self): aboutBox = QMessageBox() aboutBox.setIcon(QMessageBox.Information) aboutBox.setStandardButtons(QMessageBox.Ok) aboutBox.setWindowTitle("About the Software") aboutBox.setText(utils.license_text) aboutBox.setWindowIcon(self.appIcon) aboutBox.exec_() def handleBrowseInputButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFile) dialog.setNameFilter("*.csv") if dialog.exec_(): filePath = dialog.selectedFiles() if len(filePath) == 1: self.inputLineEdit.setText(filePath[0]) def handleBrowseModelButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFile) dialog.setNameFilter(utils.lab_model_extensions[ self.labNameComboBox.currentText().split(":")[0]]) if dialog.exec_(): filePath = dialog.selectedFiles() if len(filePath) == 1: self.modelLineEdit.setText(filePath[0]) def handleBrowseOutputButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.DirectoryOnly) dialog.setOption(QFileDialog.ShowDirsOnly) if dialog.exec_(): folderPath = dialog.selectedFiles() if len(folderPath) == 1: self.outputFolderLineEdit.setText(folderPath[0]) def handleSaveLogButton(self): dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.AnyFile) dialog.AcceptMode(QFileDialog.AcceptSave) dialog.setNameFilter("*.txt") if dialog.exec_(): filePath = dialog.selectedFiles() if len(filePath) == 1: if self.logger.saveLog(filePath[0]) != -1: self.logger.log( "The log has been saved, feel free to clear the log now", type="SUCCESS") return self.logger.log("Failed to save the log, please select a valid file", type="ERROR") def handleClearLogButton(self): self.logger.clearLog() def handleUseDefaultModelCheckboxStateChanged(self): if self._modelRPiPath: return if not self.useDefaultModelCheckbox.checkState(): self.modelLineEdit.setDisabled(0) self.browseModelButton.setDisabled(0) else: self.modelLineEdit.clear() self.modelLineEdit.setDisabled(1) self.browseModelButton.setDisabled(1) def handleLabNameComboboxCurrentIndexChanged(self): if self._modelRPiPath: self.modelLineEdit.setText(utils.lab_default_models[ self.labNameComboBox.currentText().split(":")[0]]) # Disable the model options when the lab selected is Communication Test if self.labNameComboBox.currentIndex() == 0: self.modelLineEdit.setDisabled(1) self.browseModelButton.setDisabled(1) self.modelLineEdit.setText("Model is not required") else: self.modelLineEdit.setDisabled(0) self.browseModelButton.setDisabled(0) def handleActionGetRPiIPClicked(self): self.logger.log("Attempting to Get Raspberry Pi IP Address", type="INFO") if not self.b_serialConnected: replyMessage = "Serial is not connected, Please connect serial first" else: self.executer = Executer(serialObj=self.port, loggerObj=self.logger) ipaddr = self.executer.executeOther("GET_IP") replyMessage = ( "Raspberry Pi IP is " + ipaddr ) if ipaddr != ExecutionResult.FAILED else "Failed to obtain the IP Address" self.logger.log(replyMessage) ipAddrMessage = QMessageBox() ipAddrMessage.setIcon(QMessageBox.Information) ipAddrMessage.setStandardButtons(QMessageBox.Ok) ipAddrMessage.setWindowTitle("Raspberry Pi IP Address") ipAddrMessage.setText(replyMessage) ipAddrMessage.setTextFormat(Qt.RichText) ipAddrMessage.setWindowIcon(self.appIcon) ipAddrMessage.exec_() def handleActionUpdateRPiScript(self): self.logger.log( 'Attempting to "git pull" for the Raspberry Pi Python Script', type="INFO") if not self.b_serialConnected: replyMessage = "Serial is not connected, Please connect serial first" else: self.executer = Executer(serialObj=self.port, loggerObj=self.logger) result = self.executer.executeOther("UPDATE_SCRIPT") if result != ExecutionResult.FAILED and "FAIL" not in result: replyMessage = "Raspberry Pi Script has been updated. You still need to reboot or power cycle the Raspberry Pi for the updated script to run" \ "\nReceived: " + result else: replyMessage = "Failed to update the RPi Script" if "FAIL" in result: replyMessage = replyMessage + "\nReceived: " + result self.logger.log(replyMessage) ipAddrMessage = QMessageBox() ipAddrMessage.setIcon(QMessageBox.Information) ipAddrMessage.setStandardButtons(QMessageBox.Ok) ipAddrMessage.setWindowTitle("Raspberry Pi Script Updating Status") ipAddrMessage.setText(replyMessage) ipAddrMessage.setTextFormat(Qt.RichText) ipAddrMessage.setWindowIcon(self.appIcon) ipAddrMessage.exec_() @property def b_processRunning(self): return self._b_processRunning @property def b_serialConnected(self): return self._b_serialConnected @b_serialConnected.setter def b_serialConnected(self, newValue): self._b_serialConnected = newValue if newValue is True: self.logger.log("", special="SerialConnected") else: self.logger.log("", special="SerialDisconnected") @b_processRunning.setter def b_processRunning(self, newValue): self._b_processRunning = newValue if newValue is True: self.logger.log("", special="ProcessingStarted") def __del__(self): if self.b_serialConnected: self.port.close()
class SubtitleInfoDialog(QDialog): def __init__(self, subtitle_name="Test", subtitle_delay=0.0, subtitle_language=Default_Subtitle_Language, subtitle_track_name="Test", subtitle_set_default=False, subtitle_set_forced=False, subtitle_default_value_delay=0.0, subtitle_default_value_language=Default_Subtitle_Language, subtitle_default_value_track_name="Test", subtitle_default_value_set_default=False, subtitle_default_value_set_forced=False, subtitle_set_default_disabled=False, subtitle_set_forced_disabled=False, disable_edit=False, parent=None): super().__init__(parent) self.window_title = "Subtitle Info" self.state = "no" self.messageIcon = QLabel() self.disable_edit = disable_edit self.current_subtitle_language = str(subtitle_language) self.current_subtitle_delay = str(subtitle_delay) self.current_subtitle_track_name = str(subtitle_track_name) self.current_subtitle_set_default = subtitle_set_default self.current_subtitle_set_forced = subtitle_set_forced self.default_subtitle_language = str(subtitle_default_value_language) self.default_subtitle_delay = str(subtitle_default_value_delay) self.default_subtitle_track_name = str( subtitle_default_value_track_name) self.default_subtitle_set_default = subtitle_default_value_set_default self.default_subtitle_set_forced = subtitle_default_value_set_forced self.subtitle_set_default_disabled = subtitle_set_default_disabled self.subtitle_set_forced_disabled = subtitle_set_forced_disabled self.subtitle_name_label = QLabel("Subtitle Name:") self.subtitle_name_value = QLabel(str(subtitle_name)) self.subtitle_delay_label = QLabel("Subtitle Delay:") self.subtitle_delay_spin = QDoubleSpinBox() self.setup_subtitle_delay_spin() self.subtitle_language_label = QLabel("Subtitle Language:") self.subtitle_language_comboBox = QComboBox() self.setup_subtitle_language_comboBox() self.subtitle_track_name_label = QLabel("Subtitle Track Name:") self.subtitle_track_name_lineEdit = QLineEdit() self.setup_subtitle_track_name_lineEdit() self.subtitle_set_forced_label = QLabel("Subtitle Forced State:") self.subtitle_set_forced_checkBox = QCheckBox() self.setup_subtitle_set_forced_checkBox() self.subtitle_set_default_label = QLabel("Subtitle Default State:") self.subtitle_set_default_checkBox = QCheckBox() self.setup_subtitle_set_default_checkBox() self.yes_button = QPushButton("OK") self.no_button = QPushButton("Cancel") self.reset_button = QPushButton("Reset To Default") self.buttons_layout = QHBoxLayout() self.subtitle_delay_layout = QHBoxLayout() self.subtitle_language_layout = QHBoxLayout() self.subtitle_track_name_layout = QHBoxLayout() self.subtitle_set_default_layout = QHBoxLayout() self.subtitle_set_forced_layout = QHBoxLayout() self.buttons_layout.addWidget(QLabel(""), stretch=3) self.buttons_layout.addWidget(self.reset_button, stretch=2) self.buttons_layout.addWidget(self.yes_button, stretch=2) self.buttons_layout.addWidget(self.no_button, stretch=2) self.buttons_layout.addWidget(QLabel(""), stretch=3) self.subtitle_setting_layout = QGridLayout() self.subtitle_changeble_setting_layout = QFormLayout() self.subtitle_changeble_setting_layout.addRow(self.subtitle_name_label, self.subtitle_name_value) self.subtitle_changeble_setting_layout.addRow( self.subtitle_track_name_label, self.subtitle_track_name_lineEdit) self.subtitle_changeble_setting_layout.addRow( self.subtitle_language_label, self.subtitle_language_comboBox) self.subtitle_changeble_setting_layout.addRow( self.subtitle_delay_label, self.subtitle_delay_spin) self.subtitle_changeble_setting_layout.addRow( self.subtitle_set_default_label, self.subtitle_set_default_checkBox) self.subtitle_changeble_setting_layout.addRow( self.subtitle_set_forced_label, self.subtitle_set_forced_checkBox) self.subtitle_setting_layout.addLayout( self.subtitle_changeble_setting_layout, 0, 0, 5, 2) self.subtitle_setting_layout.addWidget(self.messageIcon, 0, 3, 5, -1) self.main_layout = QGridLayout() self.main_layout.addLayout(self.subtitle_setting_layout, 0, 0, 2, 3) self.main_layout.addLayout(self.buttons_layout, 2, 0, 1, -1) self.main_layout.setContentsMargins(20, 20, 20, 20) self.setLayout(self.main_layout) self.setup_ui() self.signal_connect() def setup_ui(self): self.disable_question_mark_window() self.messageIcon.setPixmap( QtGui.QPixmap(GlobalFiles.SubtitleIconPath).scaledToHeight(100)) self.set_dialog_values() self.set_default_buttons() if self.subtitle_set_default_disabled: self.subtitle_set_default_disable() if self.subtitle_set_forced_disabled: self.subtitle_set_forced_disable() if self.disable_edit: self.subtitle_track_name_lineEdit.setEnabled(False) self.subtitle_language_comboBox.setEnabled(False) self.subtitle_delay_spin.setEnabled(False) self.subtitle_set_default_checkBox.setEnabled(False) self.subtitle_set_forced_checkBox.setEnabled(False) self.reset_button.setEnabled(False) self.setup_tool_tip_hint_subtitle_set_default() self.setup_tool_tip_hint_subtitle_set_forced() def signal_connect(self): self.subtitle_track_name_lineEdit.textEdited.connect( self.update_current_subtitle_track_name) self.subtitle_delay_spin.editingFinished.connect( self.update_current_subtitle_delay) self.subtitle_language_comboBox.currentTextChanged.connect( self.update_current_subtitle_language) self.subtitle_set_default_checkBox.stateChanged.connect( self.update_current_subtitle_set_default) self.subtitle_set_forced_checkBox.stateChanged.connect( self.update_current_subtitle_set_forced) self.yes_button.clicked.connect(self.click_yes) self.no_button.clicked.connect(self.click_no) self.reset_button.clicked.connect(self.reset_subtitle_setting) def click_yes(self): self.state = "yes" self.close() def click_no(self): self.close() def set_dialog_values(self): self.setWindowTitle(self.window_title) self.setWindowIcon(GlobalFiles.InfoSettingIcon) def disable_question_mark_window(self): self.setWindowFlag(Qt.WindowContextHelpButtonHint, on=False) def increase_message_font_size(self, value): message_font = self.message.font() message_font.setPointSize(self.message.fontInfo().pointSize() + value) self.message.setFont(message_font) def set_default_buttons(self): self.yes_button.setDefault(True) self.yes_button.setFocus() def showEvent(self, a0: QtGui.QShowEvent) -> None: super().showEvent(a0) self.setFixedSize(self.size()) def setup_subtitle_track_name_lineEdit(self): self.subtitle_track_name_lineEdit.setClearButtonEnabled(True) self.subtitle_track_name_lineEdit.setText( self.current_subtitle_track_name) def setup_subtitle_language_comboBox(self): self.subtitle_language_comboBox.addItems(AllSubtitlesLanguages) self.subtitle_language_comboBox.setCurrentIndex( AllSubtitlesLanguages.index(self.current_subtitle_language)) self.subtitle_language_comboBox.setMaxVisibleItems(8) self.subtitle_language_comboBox.setStyleSheet( "QComboBox { combobox-popup: 0; }") def setup_subtitle_delay_spin(self): # self.subtitle_delay_spin.setMaximumWidth(screen_size.width() // 16) self.subtitle_delay_spin.setDecimals(3) self.subtitle_delay_spin.setMinimum(-9999.0) self.subtitle_delay_spin.setMaximum(9999.0) self.subtitle_delay_spin.setSingleStep(0.5) self.subtitle_delay_spin.setValue(float(self.current_subtitle_delay)) def setup_subtitle_set_default_checkBox(self): self.subtitle_set_default_checkBox.setText("Set Default") self.subtitle_set_default_checkBox.setChecked( bool(self.current_subtitle_set_default)) def setup_subtitle_set_forced_checkBox(self): self.subtitle_set_forced_checkBox.setText("Set Forced") self.subtitle_set_forced_checkBox.setChecked( bool(self.current_subtitle_set_forced)) def update_current_subtitle_track_name(self): self.current_subtitle_track_name = str( self.subtitle_track_name_lineEdit.text()) def update_current_subtitle_delay(self): self.current_subtitle_delay = round(self.subtitle_delay_spin.value(), 5) def update_current_subtitle_language(self): self.current_subtitle_language = str( self.subtitle_language_comboBox.currentText()) def update_current_subtitle_set_default(self): self.current_subtitle_set_default = ( self.subtitle_set_default_checkBox.checkState() == Qt.Checked) def update_current_subtitle_set_forced(self): self.current_subtitle_set_forced = ( self.subtitle_set_forced_checkBox.checkState() == Qt.Checked) def reset_subtitle_setting(self): self.current_subtitle_language = self.default_subtitle_language self.current_subtitle_delay = self.default_subtitle_delay self.current_subtitle_track_name = self.default_subtitle_track_name self.current_subtitle_set_default = self.default_subtitle_set_default self.current_subtitle_set_forced = self.default_subtitle_set_forced self.subtitle_language_comboBox.setCurrentIndex( AllSubtitlesLanguages.index(self.current_subtitle_language)) self.subtitle_delay_spin.setValue(float(self.current_subtitle_delay)) self.subtitle_track_name_lineEdit.setText( self.current_subtitle_track_name) self.subtitle_set_default_checkBox.setChecked( bool(self.current_subtitle_set_default)) self.subtitle_set_forced_checkBox.setChecked( bool(self.current_subtitle_set_forced)) def subtitle_set_default_disable(self): self.subtitle_set_default_checkBox.setDisabled(True) def subtitle_set_forced_disable(self): self.subtitle_set_forced_checkBox.setDisabled(True) def setup_tool_tip_hint_subtitle_set_default(self): if self.subtitle_set_default_checkBox.isEnabled(): self.subtitle_set_default_checkBox.setToolTip( "<nobr>set this subtitle to be the default subtitle track " "when play") self.subtitle_set_default_checkBox.setToolTipDuration(12000) else: self.subtitle_set_default_checkBox.setToolTip( "<nobr>set this subtitle to be the default subtitle track when play<br><b>Disabled</b> because " "option " "<b>make this subtitle default</b> is enabled on mux setting tab " ) self.subtitle_set_default_checkBox.setToolTipDuration(12000) def setup_tool_tip_hint_subtitle_set_forced(self): if self.subtitle_set_forced_checkBox.isEnabled(): self.subtitle_set_forced_checkBox.setToolTip( "<nobr>set this subtitle to be the forced subtitle track when " "play") self.subtitle_set_forced_checkBox.setToolTipDuration(12000) else: self.subtitle_set_forced_checkBox.setToolTip( "<nobr>set this subtitle to be the forced subtitle track when play<br><b>Disabled</b> because " "option " "<b>make this subtitle default and forced</b> is enabled on mux setting tab " ) self.subtitle_set_forced_checkBox.setToolTipDuration(12000) def execute(self): self.exec_()
class AppearanceTab(QWidget): def __init__(self, parent): """Initialize the appearance tab """ super(AppearanceTab, self).__init__(parent) self.prefs = parent.prefs # Default column width code col_width_label = QLabel("Default Column Width:") self.col_width_edit = QLineEdit(str(self.prefs['default_column_width'])) self.col_width_edit.setMinimumWidth(40) self.col_width_edit.setMaximumWidth(100) validator = QIntValidator(10, 200, self) self.col_width_edit.setValidator(validator) # Visual style code style_label = QLabel("Visual Style of Application:") self.style_edit = QComboBox(self) self.style_edit.addItems(list(QStyleFactory.keys())) self.style_edit.setMaximumWidth(200) self.style_edit.setCurrentIndex(self.style_edit.findText(self.prefs['style'])) # Units display code units_header_label = QLabel("Units Display:") self.header_units_check = QCheckBox('Show Units in Table Headers', self) checked_header = Qt.Checked if self.prefs['show_units_in_headers'] == 1 else Qt.Unchecked self.header_units_check.setCheckState(checked_header) self.cells_units_check = QCheckBox('Show Units in Table Cells', self) checked_cells = Qt.Checked if self.prefs['show_units_in_cells'] == 1 else Qt.Unchecked self.cells_units_check.setCheckState(checked_cells) # Handling of file options code default_handling_text = QLabel("Select how options saved directly within an IDF " "file are treated. See \"Save Options\" tab " "for the options in question.") default_handling_text.setWordWrap(True) default_handling_text.setMaximumWidth(450) self.button_force = QRadioButton("Force Session Options:", self) force_text = QLabel("Options from the current session will be used for all " "files, ignoring any options saved in the IDF file.") force_text.setWordWrap(True) force_text.setMaximumWidth(450) force_text.setMinimumHeight(30) force_text.setIndent(25) self.button_obey = QRadioButton("Obey IDF Options if Present:", self) obey_text = QLabel("Obey options saved in the IDF file. If none are " "present, use the current session's options.") obey_text.setWordWrap(True) obey_text.setMaximumWidth(450) obey_text.setMinimumHeight(30) obey_text.setIndent(25) # Handling of file options group box self.behaviour_group_box = QGroupBox("Handling of File-based Options") self.behaviour_group_box.setMinimumHeight(220) self.behaviour_group_box.setMinimumWidth(450) behaviour_box = QVBoxLayout() behaviour_box.addWidget(default_handling_text) behaviour_box.addWidget(self.button_force) behaviour_box.addWidget(force_text) behaviour_box.addSpacing(5) behaviour_box.addWidget(self.button_obey) behaviour_box.addWidget(obey_text) behaviour_box.addStretch(1) self.behaviour_group_box.setLayout(behaviour_box) self.behaviour_button_group = QButtonGroup(self) self.behaviour_button_group.addButton(self.button_force) self.behaviour_button_group.addButton(self.button_obey) self.behaviour_button_group.setId(self.button_force, 0) self.behaviour_button_group.setId(self.button_obey, 1) self.behaviour_button_group.button(self.prefs['obey_idf_options']).setChecked(True) # Main layout code mainLayout = QVBoxLayout() mainLayout.addWidget(col_width_label) mainLayout.addWidget(self.col_width_edit) mainLayout.addSpacing(10) mainLayout.addWidget(style_label) mainLayout.addWidget(self.style_edit) mainLayout.addSpacing(10) mainLayout.addWidget(self.behaviour_group_box) mainLayout.addSpacing(10) mainLayout.addWidget(units_header_label) mainLayout.addWidget(self.header_units_check) mainLayout.addWidget(self.cells_units_check) mainLayout.addStretch(1) self.setLayout(mainLayout) # Update settings self.behaviour_button_group.buttonClicked.connect(self.update) self.col_width_edit.textChanged.connect(self.update) self.style_edit.currentIndexChanged.connect(self.update) self.header_units_check.stateChanged.connect(self.update) self.cells_units_check.stateChanged.connect(self.update) def update(self): self.prefs['default_column_width'] = self.col_width_edit.text() self.prefs['style'] = self.style_edit.currentText() self.prefs['obey_idf_options'] = self.behaviour_button_group.checkedId() self.prefs['show_units_in_headers'] = 1 if self.header_units_check.checkState() else 0 self.prefs['show_units_in_cells'] = 1 if self.cells_units_check.checkState() else 0