class MangaTrackerConfigWindow(QDialog, ui_configdialog.Ui_ConfigDialog): def __init__(self, parent=None): super(MangaTrackerConfigWindow, self).__init__(parent) self.setupUi(self) self.config = Config() self.database_name_text.setText(self.config.database_name) # Set up Show Empty Series option self.show_empty_series_button_group = QButtonGroup() self.show_empty_series_button_group.addButton( self.show_empty_series_yes_button, 1) self.show_empty_series_button_group.addButton( self.show_empty_series_no_button, 0) if self.config.show_empty_series: self.show_empty_series_yes_button.setChecked(True) else: self.show_empty_series_no_button.setChecked(True) # Set up Default to GUI option self.default_to_gui_button_group = QButtonGroup() self.default_to_gui_button_group.addButton( self.default_to_gui_yes_button, 1) self.default_to_gui_button_group.addButton( self.default_to_gui_no_button, 0) if self.config.default_to_gui: self.default_to_gui_yes_button.setChecked(True) else: self.default_to_gui_no_button.setChecked(True) self.config_save.clicked.connect(self.save_changes) self.config_cancel.clicked.connect(self.close) def save_changes(self): show_empty_series = self.show_empty_series_button_group.checkedId() self.config.set_property("show_empty_series", show_empty_series) default_to_gui = self.default_to_gui_button_group.checkedId() self.config.set_property("default_to_gui", default_to_gui) name = self.database_name_text.text() self.results_dialog = QMessageBox() if name == self.config.database_name: self.close() elif is_database(name): self.config.set_property("database_name", name) self.results_dialog.setText("Database name has been changed. ") self.results_dialog.show() # set up database if table doesn't exist DatabaseManager(name, init_database, False) self.close() else: self.results_dialog.setText("Database name must match " "the format *.db and not be " "a pre-existing file.") self.results_dialog.show()
class ChooseOneOfWidget(QWidget): toggled = Signal(int, bool) def __init__(self, title: str, index_to_label: Dict[int, str], is_vertical=True, checked_index: Optional[int] = None, parent=None): super().__init__(parent) self.__mapping = {} self.__main_layout = QVBoxLayout() self.__group_box = QGroupBox(title) self.__button_group = QButtonGroup() if is_vertical: self.__group_box_layout = QVBoxLayout() else: self.__group_box_layout = QHBoxLayout() for index, label in index_to_label.items(): button = QRadioButton(label) self.__button_group.addButton(button, index) self.__group_box_layout.addWidget(button) if checked_index == index: button.setChecked(True) self.__group_box.setLayout(self.__group_box_layout) self.__button_group.idToggled.connect(self.__on_toggled) self.__main_layout.addWidget(self.__group_box) self.setLayout(self.__main_layout) @Slot(int, bool) def __on_toggled(self, index, is_checked): self.toggled.emit(index, is_checked) def get_checked(self) -> int: return self.__button_group.checkedId()
class ButtonGroupWidget(QGroupBox): def __init__(self, parent=None): super(ButtonGroupWidget, self).__init__(parent) self._selectedOption = -1 self.buttonGroup = QButtonGroup() self.layoutGroupBox = QVBoxLayout(self) def addRadioButton(self, optionText, optionId): print(optionText) radioButton = QRadioButton(optionText) radioButton.clicked.connect(self.updateOptionSelected) self.layoutGroupBox.addWidget(radioButton) self.buttonGroup.addButton(radioButton, optionId) def updateOptionSelected(self): # print(self.buttonGroup.checkedId()) # for test purpose # self.selectedOption = self.buttonGroup.checkedId() # print(self._selectedOption) # for test purpose self.selectedOption = self.buttonGroup.checkedId() QApplication.postEvent( self, QKeyEvent(QEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier)) def getSelectedOption(self): print("get selectedOption is called") return self._selectedOption def setSelectedOption(self, selectedOption): # print ("selectedOption",selectedOption) print("set selectedOption is called") self._selectedOption = selectedOption self.buttonGroup.button(selectedOption).setChecked(True) selectedOption = Property(int, getSelectedOption, setSelectedOption)
class StartMineSchedDialog(QDialog): # 定义选择信号 start_minesched_signal = Signal(str) # 初始化 def __init__(self, config: ConfigFactory, logger: LoggerFactory, title: str): super(StartMineSchedDialog, self).__init__() self.config = config self.logger = logger self.setWindowTitle(title) self.setModal(True) self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.layout = QVBoxLayout() self.setLayout(self.layout) self.start_minesched_button_group = QButtonGroup() self.start_minesched_button_group.setExclusive(True) self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.minescheds = [] self.minesched_id = -1 # 设置MineSched不同版本列表 def set_minescheds(self, minescheds: list): self.minescheds = minescheds for _id, minesched in enumerate(self.minescheds): minesched_item = QRadioButton(minesched) self.start_minesched_button_group.addButton(minesched_item) self.start_minesched_button_group.setId(minesched_item, _id) if _id == 0: minesched_item.setChecked(True) self.minesched_id = 0 self.layout.addWidget(minesched_item) self.start_minesched_button_group.buttonClicked.connect( self.start_minesched_change) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) self.layout.addWidget(self.buttons) # 如果单击ok按钮 def accept(self): # 先关闭对话框,然后发送消息 super(StartMineSchedDialog, self).accept() self.config.set_config('minesched', 'minesched_location', self.minescheds[self.minesched_id]) # 发送surpac启动消息 self.start_minesched_signal.emit(self.minescheds[self.minesched_id]) def start_minesched_change(self): self.minesched_id = self.start_minesched_button_group.checkedId()
class ChoiceSurpacDialog(QDialog): # 定义选择信号 choices_surpac_signal = Signal(str) # 初始化 def __init__(self, config: ConfigFactory, logger: LoggerFactory, title: str, surpacs: list): super(ChoiceSurpacDialog, self).__init__() self.config = config self.logger = logger self.setWindowTitle(title) self.setModal(True) self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.surpacs = surpacs self.choice_surpac_button_group = QButtonGroup() self.choice_surpac_button_group.setExclusive(True) layout = QVBoxLayout() for surpac_id, choice in enumerate(surpacs): surpac_item = QRadioButton(choice) self.choice_surpac_button_group.addButton(surpac_item) self.choice_surpac_button_group.setId(surpac_item, surpac_id) if surpac_id == 0: surpac_item.setChecked(True) self.surpac_id = 0 layout.addWidget(surpac_item) self.choice_surpac_button_group.buttonClicked.connect( self.choice_surpac_change) self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) layout.addWidget(self.buttons) self.setLayout(layout) def accept(self): # 先关闭对话框,然后发送消息 super(ChoiceSurpacDialog, self).accept() if self.config.get('master', 'surpac_location') == self.surpacs[self.surpac_id]: pass else: self.choices_surpac_signal.emit(self.surpacs[self.surpac_id]) self.config.set_config('master', 'surpac_location', self.surpacs[self.surpac_id]) def choice_surpac_change(self): self.surpac_id = self.choice_surpac_button_group.checkedId()
class RadioLayout(QVBoxLayout): """Radio buttons layout with QButtonGroup""" def __init__(self, buttons, index, parent=None): QVBoxLayout.__init__(self) self.setSpacing(0) self.group = QButtonGroup() for i, button in enumerate(buttons): btn = QRadioButton(button) if i == index: btn.setChecked(True) self.addWidget(btn) self.group.addButton(btn, i) def currentIndex(self): return self.group.checkedId() def setStyleSheet(self, style): for btn in self.group.buttons(): btn.setStyleSheet(style)
class ChoiceLanguageDialog(QDialog): # 定义选择信号 choices_language_dialog_signal = Signal(str) # 初始化 def __init__(self, config: ConfigFactory, logger: LoggerFactory, title: str, languages: list): super(ChoiceLanguageDialog, self).__init__() self.config = config self.logger = logger self.setWindowTitle(title) self.setModal(True) self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.languages = languages self.choice_language_button_group = QButtonGroup() self.choice_language_button_group.setExclusive(True) layout = QVBoxLayout() for language_id, language in enumerate(languages): # 显示语言提示 language_item = QRadioButton(language.split(':')[0]) self.choice_language_button_group.addButton(language_item) self.choice_language_button_group.setId(language_item, language_id) if language_id == 0: language_item.setChecked(True) self.language_id = 0 layout.addWidget(language_item) self.choice_language_button_group.buttonClicked.connect(self.language_change) self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) layout.addWidget(self.buttons) self.setLayout(layout) def accept(self): # 先关闭对话框,然后发送消息 super(ChoiceLanguageDialog, self).accept() # 发送语言文件 language = self.languages[self.language_id].split(':')[1] self.choices_language_dialog_signal.emit(language) self.config.set_config('master', 'surpac_language_cfg', language) def language_change(self): self.language_id = self.choice_language_button_group.checkedId()
class SetTimeDialog(QDialog): """ Let the user enter the time You can pass in the parameters in the initialization, the dialog box will be displayed, if not set all will be displayed as the default value function __init__: The UI that depicts the dialog box _________________ X | ( )ON ( )OFF | | min:————— | | sec:————— | | ( )+0.5s ( )0s | -------------------- rbclicked: """ def __init__(self, parent=None, **reserved_vrg) -> None: super().__init__(parent) if 'min' in reserved_vrg: min = str(reserved_vrg['min']) sec = str(reserved_vrg['sec']) pulse = reserved_vrg['pulse'] sec_sta = reserved_vrg['sec_sta'] else: min = '59' sec = '59' sec_sta = True pulse = True # Sets the title and size of the dialog box self.setWindowTitle('Inching Settings') self.resize(200, 200) # Set the window to modal, and the user can only return to the main # interface after closing the popover self.setWindowModality(Qt.ApplicationModal) # Table layout used to layout QLabel and QLineEdit and QSpinBox grid = QGridLayout() self.rb01 = QRadioButton('Inching ON', self) self.rb02 = QRadioButton('Inching OFF', self) self.bg0 = QButtonGroup(self) self.bg0.addButton(self.rb01, 11) self.bg0.addButton(self.rb02, 12) if pulse: self.rb01.setChecked(True) self.set_sta = True else: self.rb02.setChecked(True) self.set_sta = False self.bg0.buttonClicked.connect(self.rbclicked) grid.addWidget(self.rb01, 0, 0, 1, 1) grid.addWidget(self.rb02, 0, 1, 1, 1) grid.addWidget(QLabel('mins(number)', parent=self), 1, 0, 1, 1) self.minute = QLineEdit(parent=self) self.minute.setText(min) grid.addWidget(self.minute, 1, 1, 1, 1) grid.addWidget(QLabel('secs(number)', parent=self), 2, 0, 1, 1) self.second = QLineEdit(parent=self) self.second.setText(sec) grid.addWidget(self.second, 2, 1, 1, 1) self.rb11 = QRadioButton('+0.5s', self) self.rb12 = QRadioButton('+0s', self) self.bg1 = QButtonGroup(self) self.bg1.addButton(self.rb11, 21) self.bg1.addButton(self.rb12, 22) grid.addWidget(self.rb11, 3, 0, 1, 1) grid.addWidget(self.rb12, 3, 1, 1, 1) if sec_sta: self.rb11.setChecked(True) self.second_point = True else: self.rb12.setChecked(True) self.second_point = False self.bg1.buttonClicked.connect(self.rbclicked) grid.addWidget( QLabel( 'Inching duration range is 0:0.5 ~ 59:59.5\n' 'with the interval of 0.5 sec.', parent=self), 4, 0, 2, 2) # Create ButtonBox, and the user confirms and cancels buttonbox = QDialogButtonBox(parent=self) buttonbox.setOrientation(Qt.Horizontal) # Set to horizontal buttonbox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) # Connect the signal to the slot buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) # Vertical layout, layout tables and buttons layout = QVBoxLayout() # Add the table layout you created earlier layout.addLayout(grid) # Put a space object to beautify the layout spacer_item = QSpacerItem(20, 48, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(spacer_item) # ButtonBox layout.addWidget(buttonbox) self.setLayout(layout) def rbclicked(self) -> None: """ Process radio check boxes :return: """ print('sender') if self.bg0.checkedId() == 11: self.set_sta = True elif self.bg0.checkedId() == 12: self.set_sta = False if self.bg1.checkedId() == 21: self.second_point = True elif self.bg1.checkedId() == 22: self.second_point = False else: self.second_point = False print(self.bg0.checkedId()) print(self.bg1.checkedId()) def minute(self) -> str: """ View the number of minutes the user entered :return:str """ return self.minute.text() def second(self) -> str: """ View the number of seconds the user entered :return: str """ return self.second.text() def all_time(self) -> int: """ Calculate all times entered by the user :return: int (Number of milliseconds) """ input_min = self.minute.text() input_sec = self.second.text() if input_sec.isdigit() and input_min.isdigit(): min = int(input_min) sec = int(input_sec) print(min, sec) all_time = min * 60000 + sec * 1000 if self.second_point: all_time += 500 if not (499 < all_time < 3600000): all_time = 0 return all_time return 0
class BreakpointDialog(QDialog): """ Dialog to edit breakpoints. """ def __init__(self, breakpoint_: Breakpoint, workspace: 'Workspace', parent=None): super().__init__(parent) self.breakpoint = breakpoint_ self.workspace = workspace self.setWindowTitle('Edit Breakpoint') self.main_layout: QVBoxLayout = QVBoxLayout() self._type_radio_group: Optional[QButtonGroup] = None self._address_box: Optional[QAddressInput] = None self._size_box: Optional[QLineEdit] = None self._comment_box: Optional[QLineEdit] = None self._status_label: Optional[QLabel] = None self._ok_button: Optional[QPushButton] = None self._init_widgets() self.setLayout(self.main_layout) self._validate() # # Private methods # def _init_widgets(self): layout = QGridLayout() self.main_layout.addLayout(layout) self._status_label = QLabel(self) row = 0 layout.addWidget(QLabel('Break on:', self), row, 0, Qt.AlignRight) self._type_radio_group = QButtonGroup(self) self._type_radio_group.addButton(QRadioButton('Execute', self), BreakpointType.Execute.value) self._type_radio_group.addButton(QRadioButton('Write', self), BreakpointType.Write.value) self._type_radio_group.addButton(QRadioButton('Read', self), BreakpointType.Read.value) for b in self._type_radio_group.buttons(): layout.addWidget(b, row, 1) row += 1 self._type_radio_group.button( self.breakpoint.type.value).setChecked(True) layout.addWidget(QLabel('Address:', self), row, 0, Qt.AlignRight) self._address_box = QAddressInput(self._on_address_changed, self.workspace, parent=self, default=f'{self.breakpoint.addr:#x}') layout.addWidget(self._address_box, row, 1) row += 1 layout.addWidget(QLabel('Size:', self), row, 0, Qt.AlignRight) self._size_box = QLineEdit(self) self._size_box.setText(f'{self.breakpoint.size:#x}') self._size_box.textChanged.connect(self._on_size_changed) layout.addWidget(self._size_box, row, 1) row += 1 layout.addWidget(QLabel('Comment:', self), row, 0, Qt.AlignRight) self._comment_box = QLineEdit(self) self._comment_box.setText(self.breakpoint.comment) layout.addWidget(self._comment_box, row, 1) row += 1 self.main_layout.addWidget(self._status_label) buttons = QDialogButtonBox(parent=self) buttons.setStandardButtons(QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok) buttons.accepted.connect(self._on_ok_clicked) buttons.rejected.connect(self.close) self._ok_button = buttons.button(QDialogButtonBox.Ok) self._ok_button.setEnabled(False) self.main_layout.addWidget(buttons) def _set_valid(self, valid: bool): if not valid: self._status_label.setText('Invalid') self._status_label.setProperty('class', 'status_invalid') else: self._status_label.setText('Valid') self._status_label.setProperty('class', 'status_valid') self._ok_button.setEnabled(valid) self._status_label.style().unpolish(self._status_label) self._status_label.style().polish(self._status_label) def _get_size(self): try: return int(self._size_box.text(), 0) except ValueError: pass return None # # Event handlers # def _validate(self): self._set_valid( bool(self._address_box.target is not None and self._get_size())) def _on_address_changed(self, new_text): # pylint: disable=unused-argument self._validate() def _on_size_changed(self, new_text): # pylint: disable=unused-argument self._validate() def _on_ok_clicked(self): self.breakpoint.type = BreakpointType( self._type_radio_group.checkedId()) self.breakpoint.addr = self._address_box.target self.breakpoint.size = self._get_size() self.breakpoint.comment = self._comment_box.text() self.workspace.instance.breakpoint_mgr.breakpoints.am_event() self.accept()
class SelectDialog(QDialog): def __init__(self, image, trimaps, images): super(SelectDialog, self).__init__() self.image = image.copy() # self.candidateTrimaps = [] self.candidateResults = [] for image in images: # self.candidateTrimaps.append(image) self.candidateResults.append(image) labelW = 200 #控制图片大小 h, w = self.image.shape[:2] if w > labelW: ratio = float(labelW) / float(w) else: labelW = w ratio = 1 labelH = int(h * ratio) self.image = cv2.resize(self.image, (labelW, labelH)) for i in range(len(self.candidateResults)): self.candidateResults[i] = cv2.resize( self.candidateResults[i], (labelW, labelH), interpolation=cv2.INTER_NEAREST) self.resize(labelW * 3 + 150, 800) #设置图片宽高结束 widget = QWidget() self.Vlayout = QVBoxLayout() #整体布局 self.Vlayout.setAlignment(Qt.AlignCenter) image_label = QLabel() image_label.setFixedSize(QSize(labelW, labelH)) image_label.setPixmap(numpytoPixmap(self.image)) self.firstImageLayout = QHBoxLayout() #原图的布局 self.firstImageLayout.addWidget(image_label) self.Vlayout.addLayout(self.firstImageLayout) #插入原图布局 self.buttonGroup = QButtonGroup() id = 0 self.resultLayout = QHBoxLayout() #四个结果图的布局 for i, result in enumerate(self.candidateResults): # foreground = self.changeBackground1(result,self.image) # result = self.saveBoth1(result, trimaps[i]) image_label = QLabel() image_label.setFixedSize(QSize(labelW, labelH)) image_label.setPixmap(numpytoPixmap(self.image)) final_label = QLabel() final_label.setFixedSize(QSize(labelW, labelH)) final_label.setPixmap(numpytoPixmap(result)) radioButton = QRadioButton(str(id)) # 创建单选按钮 self.buttonGroup.addButton(radioButton, id) id += 1 self.Hlayout = QVBoxLayout() #一张图和一个radio的布局 self.Hlayout.addWidget(final_label) self.Hlayout.addWidget(radioButton) self.resultLayout.addLayout(self.Hlayout) self.Vlayout.addLayout(self.resultLayout) #插入四个结果布局 #控制ok按钮逻辑 self.button = QPushButton('OK') self.button.setFixedSize(QSize(100, 50)) self.button.clicked.connect(self.select) self.btnLayout = QHBoxLayout() self.btnLayout.setAlignment(Qt.AlignCenter) self.btnLayout.addWidget(self.button) self.Vlayout.addLayout(self.btnLayout) #插入按钮布局 # scrollArea = QScrollArea() # scrollArea.setWidget(widget) # layout = QVBoxLayout(self) # layout.addWidget(scrollArea) self.setLayout(self.Vlayout) self.buttonGroup.button(0).setChecked(True) self.selectId = 0 def select(self): self.selectId = self.buttonGroup.checkedId() self.accept() def saveBoth1(self, alpha, foreground): b_channel, g_channel, r_channel = cv2.split(foreground) a_channel = alpha.mean(axis=2) img_bgra = cv2.merge((b_channel, g_channel, r_channel, a_channel)) return img_bgra
class MyWidget(QWidget): def __init__(self, parent): super().__init__(parent) self.buttons_id_value = { 1: ('comma', ','), 2: ('space', '\b'), 3: ('tab', '\t'), 4: ('semicolon', ';') } self.separator = QButtonGroup() lab = QLabel() lab.setText('Choose a separator:') for bid, value in self.buttons_id_value.items(): self.separator.addButton(QRadioButton(value[0]), id=bid) self.separator.setExclusive(True) self.default_button = self.separator.button(1) button_layout = QHBoxLayout() for button in self.separator.buttons(): button_layout.addWidget(button) self.default_button.click() openFileChooser = QPushButton('Choose') fileChooser = QFileDialog(self, 'Open csv', str(os.getcwd()), 'Csv (*.csv *.tsv *.dat)') fileChooser.setFileMode(QFileDialog.ExistingFile) self.filePath = QLineEdit() openFileChooser.released.connect(fileChooser.show) fileChooser.fileSelected.connect(self.filePath.setText) self.filePath.textChanged.connect(self.checkFileExists) nameLabel = QLabel('Select a name:', self) self.nameField = QLineEdit(self) self.nameErrorLabel = QLabel(self) self.file_layout = QVBoxLayout() fileChooserLayout = QHBoxLayout() nameRowLayout = QHBoxLayout() fileChooserLayout.addWidget(openFileChooser) fileChooserLayout.addWidget(self.filePath) nameRowLayout.addWidget(nameLabel) nameRowLayout.addWidget(self.nameField) self.fileErrorLabel = QLabel(self) self.file_layout.addLayout(fileChooserLayout) self.file_layout.addWidget(self.fileErrorLabel) self.file_layout.addLayout(nameRowLayout) self.file_layout.addWidget(self.nameErrorLabel) self.fileErrorLabel.hide() self.nameErrorLabel.hide() self.tablePreview = SearchableAttributeTableWidget(self, True) self.tableSpinner = QtWaitingSpinner( self.tablePreview, centerOnParent=True, disableParentWhenSpinning=True) self.nameField.textEdited.connect(self.nameErrorLabel.hide) # Split file by row splitRowLayout = QHBoxLayout() self.checkSplit = QCheckBox('Split file by rows', self) self.numberRowsChunk = QLineEdit(self) self.numberRowsChunk.setPlaceholderText( 'Number of rows per chunk') self.numberRowsChunk.setValidator(QIntValidator(self)) splitRowLayout.addWidget(self.checkSplit) splitRowLayout.addWidget(self.numberRowsChunk) self.checkSplit.stateChanged.connect(self.toggleSplitRows) layout = QVBoxLayout() layout.addLayout(self.file_layout) layout.addWidget(lab) layout.addLayout(button_layout) layout.addLayout(splitRowLayout) layout.addWidget(QLabel('Preview')) layout.addWidget(self.tablePreview) self.setLayout(layout) self.filePath.textChanged.connect(self.loadPreview) self.separator.buttonClicked.connect(self.loadPreview) @Slot(object) def loadPreview(self) -> None: if not os.path.isfile(self.filePath.text()): return class WorkerThread(QThread): resultReady = Signal(Frame) def __init__(self, path: str, separ: str, parent=None): super().__init__(parent) self.__path = path self.__sep = separ def run(self): header = pd.read_csv(self.__path, sep=self.__sep, index_col=False, nrows=0) self.resultReady.emit(Frame(header)) sep: int = self.separator.checkedId() sep_s: str = self.buttons_id_value[sep][ 1] if sep != -1 else None assert sep_s is not None # Async call to load header worker = WorkerThread(path=self.filePath.text(), separ=sep_s, parent=self) worker.resultReady.connect(self.onPreviewComputed) worker.finished.connect(worker.deleteLater) self.tableSpinner.start() worker.start() @Slot(Frame) def onPreviewComputed(self, header: Frame): self.tablePreview.setSourceFrameModel(FrameModel(self, header)) self.tablePreview.model().setAllChecked(True) self.tableSpinner.stop() @Slot(str) def checkFileExists(self, path: str) -> None: file_exists = os.path.isfile(path) if not file_exists: self.fileErrorLabel.setText('File does not exists!') self.fileErrorLabel.setStyleSheet('color: red') self.filePath.setToolTip('File does not exists!') self.filePath.setStyleSheet('border: 1px solid red') # self.file_layout.addWidget(self.fileErrorLabel) self.parentWidget().disableOkButton() self.fileErrorLabel.show() else: # self.file_layout.removeWidget(self.fileErrorLabel) self.fileErrorLabel.hide() self.filePath.setStyleSheet('') self.parentWidget().enableOkButton() if not self.nameField.text(): name: str = os.path.splitext(os.path.basename(path))[0] self.nameField.setText(name) @Slot(Qt.CheckState) def toggleSplitRows(self, state: Qt.CheckState) -> None: if state == Qt.Checked: self.numberRowsChunk.setEnabled(True) else: self.numberRowsChunk.setDisabled(True) def showNameError(self, msg: str) -> None: self.nameErrorLabel.setText(msg) self.nameErrorLabel.setStyleSheet('color: red') self.nameErrorLabel.show()
class DocumentTableHeaderDialog(QDialog): def __init__(self, type, index, parent=None): super(DocumentTableHeaderDialog, self).__init__(parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # Group box text = 'Binary Number' if index >= 0 else 'Binary Numbers' toolTip = 'Change label to a binary number' if index >= 0 else 'Change all labels to binary numbers' rdbBinary = QRadioButton(text) rdbBinary.setToolTip(toolTip) text = 'With prefix 0b' toolTip = 'Change label to a binary number with prefix 0b otherwise without prefix' if index >= 0 else 'Change all labels to binary numbers with prefix 0b otherwise without prefix' self.chkBinary = QCheckBox(text) self.chkBinary.setChecked(True) self.chkBinary.setEnabled(False) self.chkBinary.setToolTip(toolTip) rdbBinary.toggled.connect( lambda checked: self.chkBinary.setEnabled(checked)) text = 'Octal Number' if index >= 0 else 'Octal Numbers' toolTip = 'Change label to a octal number' if index >= 0 else 'Change all labels to octal numbers' rdbOctal = QRadioButton(text) rdbOctal.setToolTip(toolTip) text = 'With prefix 0o' toolTip = 'Change label to a octal number with prefix 0o otherwise without prefix' if index >= 0 else 'Change all labels to octal numbers with prefix 0o otherwise without prefix' self.chkOctal = QCheckBox(text) self.chkOctal.setChecked(True) self.chkOctal.setEnabled(False) self.chkOctal.setToolTip(toolTip) rdbOctal.toggled.connect( lambda checked: self.chkOctal.setEnabled(checked)) text = 'Decimal Number' if index >= 0 else 'Decimal Numbers' toolTip = 'Change label to a decimal number' if index >= 0 else 'Change all labels to decimal numbers' rdbDecimal = QRadioButton(text) rdbDecimal.setToolTip(toolTip) text = 'Enumeration starting with 1' toolTip = 'Change label to a decimal number with the enumeration starting with 1 otherwise with 0' if index >= 0 else 'Change all labels to decimal numbers with the enumeration starting with 1 otherwise with 0' self.chkDecimal = QCheckBox(text) self.chkDecimal.setChecked(True) self.chkDecimal.setEnabled(False) self.chkDecimal.setToolTip(toolTip) rdbDecimal.toggled.connect( lambda checked: self.chkDecimal.setEnabled(checked)) text = 'Hexadecimal Number' if index >= 0 else 'Hexadecimal Numbers' toolTip = 'Change label to a hexadecimal number' if index >= 0 else 'Change all labels to hexadecimal numbers' rdbHexadecimal = QRadioButton(text) rdbHexadecimal.setToolTip(toolTip) text = 'With prefix 0x' toolTip = 'Change label to a hexadecimal number with prefix 0x otherwise without prefix' if index >= 0 else 'Change all labels to hexadecimal numbers with prefix 0x otherwise without prefix' self.chkHexadecimal = QCheckBox(text) self.chkHexadecimal.setChecked(True) self.chkHexadecimal.setEnabled(False) self.chkHexadecimal.setToolTip(toolTip) rdbHexadecimal.toggled.connect( lambda checked: self.chkHexadecimal.setEnabled(checked)) text = 'Capital Letter' if index >= 0 else 'Capital Letters' toolTip = 'Change label to a capital letter' if index >= 0 else 'Change all labels to capital letters' rdbLetter = QRadioButton(text) rdbLetter.setToolTip(toolTip) text = 'Letter as uppercase letter' if index >= 0 else 'Letters as uppercase letters' toolTip = 'Change label to a letter as uppercase letter otherwise lowercase letter' if index >= 0 else 'Change all labels to letters as uppercase letters otherwise lowercase letters' self.chkLetter = QCheckBox(text) self.chkLetter.setChecked(True) self.chkLetter.setEnabled(False) self.chkLetter.setToolTip(toolTip) rdbLetter.toggled.connect( lambda checked: self.chkLetter.setEnabled(checked)) text = 'User-defined Text' if index >= 0 else 'User-defined Texts' toolTip = 'Change label to a user-defined text' if index >= 0 else 'Change all labels to user-defined texts' rdbCustom = QRadioButton(text) rdbCustom.setToolTip(toolTip) toolTip = 'Change label to a user-defined text' if index >= 0 else 'Change all labels to user-defined texts' self.ledCustom = QLineEdit() self.ledCustom.setEnabled(False) self.ledCustom.setToolTip(toolTip) rdbCustom.toggled.connect( lambda checked: self.ledCustom.setEnabled(checked)) text = '# will be replaced with column index' if type == 'horizontal' else '# will be replaced with row index' lblCustom = QLabel(text) lblCustom.setEnabled(False) rdbCustom.toggled.connect( lambda checked: lblCustom.setEnabled(checked)) self.grpHeaderLabel = QButtonGroup(self) self.grpHeaderLabel.addButton(rdbBinary, Preferences.HeaderLabel.Binary.value) self.grpHeaderLabel.addButton(rdbOctal, Preferences.HeaderLabel.Octal.value) self.grpHeaderLabel.addButton(rdbDecimal, Preferences.HeaderLabel.Decimal.value) self.grpHeaderLabel.addButton( rdbHexadecimal, Preferences.HeaderLabel.Hexadecimal.value) self.grpHeaderLabel.addButton(rdbLetter, Preferences.HeaderLabel.Letter.value) self.grpHeaderLabel.addButton(rdbCustom, Preferences.HeaderLabel.Custom.value) self.grpHeaderLabel.buttonClicked.connect(self.onSettingChanged) groupLayout = QGridLayout() groupLayout.addWidget(rdbBinary, 0, 0) groupLayout.addWidget(self.chkBinary, 0, 1) groupLayout.addWidget(rdbOctal, 1, 0) groupLayout.addWidget(self.chkOctal, 1, 1) groupLayout.addWidget(rdbDecimal, 2, 0) groupLayout.addWidget(self.chkDecimal, 2, 1) groupLayout.addWidget(rdbHexadecimal, 3, 0) groupLayout.addWidget(self.chkHexadecimal, 3, 1) groupLayout.addWidget(rdbLetter, 4, 0) groupLayout.addWidget(self.chkLetter, 4, 1) groupLayout.addWidget(rdbCustom, 5, 0) groupLayout.addWidget(self.ledCustom, 5, 1) groupLayout.addWidget(lblCustom, 6, 1) groupLayout.setRowStretch(7, 1) text = 'Change label to a …' if index >= 0 else 'Change all labels to …' groupBox = QGroupBox(text) groupBox.setLayout(groupLayout) # Button box buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonOk = buttonBox.button(QDialogButtonBox.Ok) self.buttonOk.setEnabled(False) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) # Main layout layout = QVBoxLayout() layout.addWidget(groupBox) layout.addWidget(buttonBox) self.setLayout(layout) def onSettingChanged(self): """ Enables the ok button if a setting has been changed. """ self.buttonOk.setEnabled(True) def headerLabelType(self): """ Returns the type of the header label. """ return Preferences.HeaderLabel(self.grpHeaderLabel.checkedId()) def headerLabelParameter(self): """ Returns the parameter of the header label. """ type = self.headerLabelType() if type == Preferences.HeaderLabel.Binary: return '0b' if self.chkBinary.isChecked() else '' elif type == Preferences.HeaderLabel.Octal: return '0o' if self.chkOctal.isChecked() else '' elif type == Preferences.HeaderLabel.Decimal: return '1' if self.chkDecimal.isChecked() else '0' elif type == Preferences.HeaderLabel.Hexadecimal: return '0x' if self.chkHexadecimal.isChecked() else '' elif type == Preferences.HeaderLabel.Letter: return 'upper' if self.chkLetter.isChecked() else 'lower' elif type == Preferences.HeaderLabel.Custom: return self.ledCustom.text() else: return ''
class PreferencesDocumentPresetsPage(QWidget): preferencesChanged = Signal() def __init__(self, parent=None): super().__init__(parent) # Title title = QLabel( self.tr("<strong style=\"font-size:large;\">{0}</strong>").format( self.title())) # # Content: Header Labels rdbDefaultHeaderLabelHorizontalLetters = QRadioButton( self.tr("Letters")) rdbDefaultHeaderLabelHorizontalLetters.setToolTip( self. tr("Capital letters as default horizontal header labels of new documents" )) rdbDefaultHeaderLabelHorizontalNumbers = QRadioButton( self.tr("Numbers")) rdbDefaultHeaderLabelHorizontalNumbers.setToolTip( self. tr("Decimal numbers as default horizontal header labels of new documents" )) self._grpDefaultHeaderLabelHorizontal = QButtonGroup(self) self._grpDefaultHeaderLabelHorizontal.addButton( rdbDefaultHeaderLabelHorizontalLetters, Preferences.HeaderLabel.Letter.value) self._grpDefaultHeaderLabelHorizontal.addButton( rdbDefaultHeaderLabelHorizontalNumbers, Preferences.HeaderLabel.Decimal.value) self._grpDefaultHeaderLabelHorizontal.buttonClicked.connect( self._onPreferencesChanged) defaultHeaderLabelHorizontalBox = QHBoxLayout() defaultHeaderLabelHorizontalBox.addWidget( rdbDefaultHeaderLabelHorizontalLetters) defaultHeaderLabelHorizontalBox.addWidget( rdbDefaultHeaderLabelHorizontalNumbers) rdbDefaultHeaderLabelVerticalLetters = QRadioButton(self.tr("Letters")) rdbDefaultHeaderLabelVerticalLetters.setToolTip( self. tr("Capital letters as default vertical header labels of new documents" )) rdbDefaultHeaderLabelVerticalNumbers = QRadioButton(self.tr("Numbers")) rdbDefaultHeaderLabelVerticalNumbers.setToolTip( self. tr("Decimal numbers as default vertical header labels of new documents" )) self._grpDefaultHeaderLabelVertical = QButtonGroup() self._grpDefaultHeaderLabelVertical.addButton( rdbDefaultHeaderLabelVerticalLetters, Preferences.HeaderLabel.Letter.value) self._grpDefaultHeaderLabelVertical.addButton( rdbDefaultHeaderLabelVerticalNumbers, Preferences.HeaderLabel.Decimal.value) self._grpDefaultHeaderLabelVertical.buttonClicked.connect( self._onPreferencesChanged) defaultHeaderLabelVerticalBox = QHBoxLayout() defaultHeaderLabelVerticalBox.addWidget( rdbDefaultHeaderLabelVerticalLetters) defaultHeaderLabelVerticalBox.addWidget( rdbDefaultHeaderLabelVerticalNumbers) defaultHeaderLabelLayout = QFormLayout() defaultHeaderLabelLayout.addRow( self.tr("Labels of the horizontal header"), defaultHeaderLabelHorizontalBox) defaultHeaderLabelLayout.addRow( self.tr("Labels of the vertical header"), defaultHeaderLabelVerticalBox) defaultHeaderLabelGroup = QGroupBox(self.tr("Header Labels")) defaultHeaderLabelGroup.setLayout(defaultHeaderLabelLayout) # # Content: Cell Counts self._spbDefaultCellCountColumn = QSpinBox() self._spbDefaultCellCountColumn.setRange(1, 1000) self._spbDefaultCellCountColumn.setToolTip( self.tr("Default number of columns of new documents")) self._spbDefaultCellCountColumn.valueChanged.connect( self._onPreferencesChanged) self._spbDefaultCellCountRow = QSpinBox() self._spbDefaultCellCountRow.setRange(1, 1000) self._spbDefaultCellCountRow.setToolTip( self.tr("Default number of rows of new documents")) self._spbDefaultCellCountRow.valueChanged.connect( self._onPreferencesChanged) defaultCellCountLayout = QFormLayout() defaultCellCountLayout.addRow(self.tr("Number of columns"), self._spbDefaultCellCountColumn) defaultCellCountLayout.addRow(self.tr("Number of rows"), self._spbDefaultCellCountRow) defaultCellCountGroup = QGroupBox(self.tr("Cell Counts")) defaultCellCountGroup.setLayout(defaultCellCountLayout) # Main layout self._layout = QVBoxLayout(self) self._layout.addWidget(title) self._layout.addWidget(defaultHeaderLabelGroup) self._layout.addWidget(defaultCellCountGroup) self._layout.addStretch(1) def setZeroMargins(self): self._layout.setContentsMargins(0, 0, 0, 0) def title(self): return self.tr("Document Presets") def _onPreferencesChanged(self): self.preferencesChanged.emit() def setDefaultHeaderLabelHorizontal(self, type): if type.value != self._grpDefaultHeaderLabelHorizontal.checkedId(): self._onPreferencesChanged() for button in self._grpDefaultHeaderLabelHorizontal.buttons(): if self._grpDefaultHeaderLabelHorizontal.id(button) == type.value: button.setChecked(True) def defaultHeaderLabelHorizontal(self): return Preferences.HeaderLabel( self._grpDefaultHeaderLabelHorizontal.checkedId()) def setDefaultHeaderLabelVertical(self, type): if type.value != self._grpDefaultHeaderLabelVertical.checkedId(): self._onPreferencesChanged() for button in self._grpDefaultHeaderLabelVertical.buttons(): if self._grpDefaultHeaderLabelVertical.id(button) == type.value: button.setChecked(True) def defaultHeaderLabelVertical(self): return Preferences.HeaderLabel( self._grpDefaultHeaderLabelVertical.checkedId()) def setDefaultCellCountColumn(self, val): self._spbDefaultCellCountColumn.setValue(val) def defaultCellCountColumn(self): return self._spbDefaultCellCountColumn.value() def setDefaultCellCountRow(self, val): self._spbDefaultCellCountRow.setValue(val) def defaultCellCountRow(self): return self._spbDefaultCellCountRow.value()
class _RemoveNanEditor(AbsOperationEditor): _baseText = { 0: 'Remove with more than: <b>{}</b> nan', 1: 'Remove with more than: <b>{}%</b> nan' } def __init__(self, mode: str, parent: QWidget = None): """ Builds the editor :param mode: one of 'col' or 'row' :param parent: a parent widget """ self.__mode: str = mode super().__init__(parent) def editorBody(self) -> QWidget: self.__group = QButtonGroup() self.__group.setExclusive(True) lab = QLabel('Choose how to remove:') self.__group.addButton(QRadioButton('By number'), id=0) self.__group.addButton(QRadioButton('By percentage'), id=1) self.__currId = None self.__summaryLabel = QLabel() self.__slider = QSlider(Qt.Horizontal, self) self.__slider.setMinimum(0) self.__slider.setTracking(True) self.__slider.setSingleStep(1) self.__numBox = QSpinBox() self.__numBox.setMinimum(0) self.__numBox.setMaximum(10000000) radioLayout = QHBoxLayout() radioLayout.addWidget(self.__group.button(0)) radioLayout.addWidget(self.__group.button(1)) self.__bodyLayout = QVBoxLayout() self.__bodyLayout.addWidget(lab) self.__bodyLayout.addLayout(radioLayout) self.__bodyLayout.addSpacing(20) self.__bodyLayout.addWidget(QLabel('Move the slider to set removal parameter:')) self.__bodyLayout.addSpacing(10) self.__bodyLayout.addWidget(self.__slider if self.__mode == 'row' else self.__numBox) self.__bodyLayout.addWidget(self.__summaryLabel) self.__group.buttonClicked[int].connect(self._toggleMode) # Both are connected, only one is shown self.__slider.valueChanged.connect(self._onValueChanged) self.__numBox.valueChanged[int].connect(self._onValueChanged) # Set a default button and label text self.__group.button(0).click() self.__summaryLabel.setText(self._baseText[0].format(self.__slider.minimum())) body = QWidget() body.setLayout(self.__bodyLayout) return body @Slot(int) def _toggleMode(self, bid: int) -> None: # NOTE: could be refactored if bid == self.__currId: return self.__currId = bid if bid == 0: if not (self.inputShapes and self.inputShapes[0]) and self.__mode == 'row': self.__slider.setDisabled(True) self._onValueChanged(self.__slider.value()) elif not self.__slider.isEnabled(): self.__slider.setEnabled(True) else: if self.__mode == 'row': self.__slider.setMaximum(self.inputShapes[0].nColumns) self._onValueChanged(self.__slider.value()) else: self.__bodyLayout.replaceWidget(self.__slider, self.__numBox) self.__slider.hide() self.__numBox.show() self._onValueChanged(self.__numBox.value()) else: if self.__mode == 'row': if not self.__slider.isEnabled(): self.__slider.setEnabled(True) else: self.__bodyLayout.replaceWidget(self.__numBox, self.__slider) self.__numBox.hide() self.__slider.show() self._onValueChanged(self.__slider.value()) self.__slider.setMaximum(100) @Slot(int) def _onValueChanged(self, value: int): self.__summaryLabel.setText(self._baseText[self.__currId].format(value)) def getOptions(self) -> Iterable: if self.__group.checkedId() == 0: # By number return None, self.__slider.value() if self.__mode == 'row' else self.__numBox.value() else: # By perc return self.__slider.value() / 100, None def setOptions(self, percentage: float, number: int) -> None: if percentage is not None: self.__group.button(1).click() self.__slider.setValue(percentage * 100) elif number is not None: self.__group.button(0).click() self.__slider.setValue(number) if self.__mode == 'row' else self.__numBox.setValue(number) else: # Both None self.__slider.setValue(0) self.__numBox.setValue(0) def refresh(self) -> None: if self.__mode == 'row' and self.__group.checkedId() == 0: self.__slider.setMaximum(self.inputShapes[0].nColumns) self.__slider.setEnabled(True)
class Prescreen(QWidget): REASONS = ('Inattentive', 'Child Talking', 'Parent Talking', 'Parent Interference', 'Child Not Looking Before Sound', 'Equipment Malfunction', 'Experiment Ended Early', 'Other') def __init__(self, callback): super().__init__() self.callback = callback trial_label = QLabel('Trial:') self.trial_box = QSpinBox() self.trial_box.setFixedWidth(64) self.trial_box.setValue(1) # self.trial_box.setFocusPolicy(Qt.NoFocus) reason_label = QLabel('Reason:') self.reason_box = QComboBox() self.reason_box.addItems(self.REASONS) self.reason_box.setFocusPolicy(Qt.NoFocus) self.code_radio = QRadioButton('Code') self.nocode_radio = QRadioButton('Do Not Code') self.code_radio.setChecked(True) self.code_radio.setFocusPolicy(Qt.NoFocus) self.nocode_radio.setFocusPolicy(Qt.NoFocus) radio_layout = QVBoxLayout() radio_layout.addStretch() radio_layout.addWidget(self.code_radio) radio_layout.addWidget(self.nocode_radio) radio_layout.addStretch() self.group_code = QButtonGroup() self.group_code.addButton(self.code_radio) self.group_code.addButton(self.nocode_radio) self.record_button = QPushButton('Record Reason') self.record_button.clicked.connect(self.record_reason) self.record_button.setEnabled(False) self.record_button.setFocusPolicy(Qt.NoFocus) self.both_checkbox = QCheckBox('Display both coders') self.both_checkbox.setFocusPolicy(Qt.NoFocus) self.radio_primary = QRadioButton('Primary') self.radio_secondary = QRadioButton('Secondary') self.radio_primary.setChecked(True) self.radio_primary.setFocusPolicy(Qt.NoFocus) self.radio_secondary.setFocusPolicy(Qt.NoFocus) who_layout = QVBoxLayout() who_layout.addWidget(self.both_checkbox) who_layout.addWidget(self.radio_primary) who_layout.addWidget(self.radio_secondary) self.group_who = QButtonGroup() self.group_who.addButton(self.radio_primary, id=1) self.group_who.addButton(self.radio_secondary, id=2) layout = QHBoxLayout() layout.addWidget(trial_label) layout.addWidget(self.trial_box) layout.addWidget(reason_label) layout.addWidget(self.reason_box) layout.addLayout(radio_layout) layout.addWidget(self.record_button) layout.addStretch() layout.addLayout(who_layout) self.setLayout(layout) def record_reason(self): reason = Reason(trial=self.trial_box.value(), include=self.code_radio.isChecked(), reason=self.reason_box.currentText()) self.callback(reason) def prescreener(self): if self.both_checkbox.isChecked(): return 0 else: return self.group_who.checkedId()
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