def setup_ui(self): loader = QUiLoader() file = QFile('./media/main_window.ui') file.open(QFile.ReadOnly) self._window = loader.load(file) file.close() self.set_title() self.set_buttons() # Setup combobox self._window.transportation_combo.addItem('HSR', 'HighSpeedRail') self._window.transportation_combo.addItem('Taxi', 'Uber,Taxi') self._window.transportation_combo.addItem('Drive', 'Car') self._window.transportation_combo.addItem('Scooter', 'Motorcycle') # Setup RadioButton / CheckBox self._window.yes_radio.setChecked(False) self._window.no_radio.setChecked(True) vegetarian_group = QButtonGroup(self._window) vegetarian_group.setExclusive(True) vegetarian_group.addButton(self._window.yes_radio) vegetarian_group.addButton(self._window.no_radio) self._window.absolutly_check.setChecked(True) self._window.maybe_check.setChecked(False) self._window.sorry_check.setChecked(False) participate_group = QButtonGroup(self._window) participate_group.setExclusive(True) participate_group.addButton(self._window.absolutly_check) participate_group.addButton(self._window.maybe_check) participate_group.addButton(self._window.sorry_check) # Setup SpinBox self._window.members_spin.setRange(1, 10)
class ChannelSelector(QWidget): channelSelected = Signal(str) channelDeselected = Signal(str) def __init__(self): QWidget.__init__(self) self.setLayout(QGridLayout()) self.control_group = QButtonGroup() self.control_group.setExclusive(False) self.control_group.idToggled.connect(self.notifyChannel) self.ids_to_channels = {} # {id: channel_name (str)} self.checkboxes = {} # {channel_name: QCheckBox} self.next_id = 0 # TODO(jacob): 4 columns is mostly an arbitrary choice; 5 seemed # too crowded, 3 seemed too empty. Ideally we'd change this # dynamically based on the column width. self.num_cols = 4 def add_checkbox(self, channel_name): if channel_name in self.checkboxes: warnings.warn('attempted to add a duplicate checkbox to the DAQ channel selector') return checkbox = QCheckBox(channel_name) self.checkboxes[channel_name] = checkbox num_widgets = len(self.checkboxes) row = (num_widgets - 1) // self.num_cols col = (num_widgets - 1) % self.num_cols self.layout().addWidget(checkbox, row, col) self.control_group.addButton(checkbox, self.next_id) self.ids_to_channels[self.next_id] = channel_name self.next_id += 1 def clear_checkboxes(self): for checkbox in self.checkboxes.values(): self.control_group.removeButton(checkbox) self.layout().removeWidget(checkbox) checkbox.deleteLater() self.checkboxes = {} self.ids_to_channels = {} @Slot(top.PlumbingEngine) def updateNodeList(self, plumb): self.clear_checkboxes() for node in plumb.nodes(data=False): self.add_checkbox(node) @Slot(int) def notifyChannel(self, checkbox_id, is_checked): channel = self.ids_to_channels[checkbox_id] if is_checked: self.channelSelected.emit(channel) else: self.channelDeselected.emit(channel)
def __init__(self): self.widget = QWidget() layout = QVBoxLayout() self.widget.setLayout(layout) # Section Buttons load_image_button = QPushButton("Load Section") layout.addWidget(load_image_button) load_image_button.clicked.connect(self.show_load_image_dialog) load_image_button2 = QPushButton("Quick Load Section") layout.addWidget(load_image_button2) load_image_button2.clicked.connect(lambda: self.load_section( "data/RA_10X_scans/MeA/S1_07032020.ome.tiff")) # Scale Slider (Set Section Resolution) self.resample_widget = LabelledSliderWidget(min=15, max=200, label="Scale") layout.addLayout(self.resample_widget.layout) self.resample_widget.connect( lambda val: self.set_section_image_resolution(val)) self.dim_widgets = [] for dim in [ 'right', 'superior', 'anterior', 'rot_lateral', 'rot_axial', 'rot_median' ]: widget = LabelledSliderWidget( min=-10000 if not dim.startswith('rot_') else -180, max=10000 if not dim.startswith('rot_') else 180, label=dim) layout.addLayout(widget.layout) fun = lambda d, value: self.transform_section(**{d: value}) widget.connect(partial(fun, dim)) self.dim_widgets.append((widget, fun)) # Atlas BUttons button_hbox = QHBoxLayout() layout.addLayout(button_hbox) atlas_buttons = QButtonGroup(self.widget) atlas_buttons.setExclusive(True) atlas_buttons.buttonToggled.connect(self.atlas_button_toggled) for resolution in [100, 25, 10]: atlas_button = QPushButton(f"{resolution}um") atlas_button.setCheckable(True) button_hbox.addWidget(atlas_button) atlas_buttons.addButton(atlas_button) # The 10um atlas takes way too long to download at the moment. # It needs some kind of progress bar or async download feature to be useful. # The disabled button here shows it as an option for the future, but keeps it from being used. if resolution == 10: atlas_button.setDisabled(True)
class View(QMainWindow, Ui_DsManager): def __init__(self, *args, **kwargs): super(View, self).__init__(*args, **kwargs) self.setupUi(self) def setupUi(self, DsManager): super(View, self).setupUi(DsManager) self.source_btn_group = QButtonGroup(self) self.reversed_entry_btn_group = QButtonGroup(self) self.source_btn_group.setExclusive(True) self.reversed_entry_btn_group.setExclusive(True) self.source_btn_group.addButton(self.cash_radio, 1) self.source_btn_group.addButton(self.main_radio, 2) self.source_btn_group.addButton(self.building_radio, 3) self.reversed_entry_btn_group.addButton(self.reversed_entry_increase, 1) self.reversed_entry_btn_group.addButton(self.reversed_entry_decrease, 2) self.cheque_label.hide() self.cheque_number.hide() def view_pdf(self, pdf_js, pdf_file_name): new_window = QMainWindow(self) pdf_viewer = Ui_PDFViewer() pdf_viewer.setupUi(new_window) pdf_url = QUrl.fromLocalFile(pdf_js) pdf_url.setQuery("file=" + pdf_file_name) pdf_viewer.webView.load(pdf_url) new_window.show() @classmethod def show_about_ds(cls): dialog = QDialog() about = Ui_About() about.setupUi(dialog) dialog.exec_() @classmethod def show_message(cls, message: str, logo: str): msg = QMessageBox() icon = QIcon() icon.addFile(u"inc/icon.ico", QSize(), QIcon.Normal, QIcon.Off) msg.setWindowIcon(icon) if logo == "error": msg.setIcon(QMessageBox.Critical) elif logo == "info": msg.setIcon(QMessageBox.Information) msg.setText(message) msg.setWindowTitle(logo) msg.exec_() def closeEvent(self, event): model = Model() model.close_connection() event.accept()
class ElchPlotMenu(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) controls = ['Start', 'Clear', 'Export'] self.buttons = { key: QPushButton(parent=self, text=key, objectName=key) for key in controls } self.buttons['Start'].setCheckable(True) self.checks = { key: QCheckBox(parent=self, text=key, objectName=key) for key in ['Sensor PV', 'Controller PV', 'Setpoint', 'Power'] } self.check_group = QButtonGroup() self.check_group.setExclusive(False) vbox = QVBoxLayout() vbox.addWidget(QLabel(text='Plotting', objectName='Header')) for key in controls: vbox.addWidget(self.buttons[key]) self.buttons[key].clicked.connect({ 'Start': functools.partial(self.start_stop_plotting), 'Clear': self.clear_pplot, 'Export': self.export_data }[key]) vbox.addSpacing(20) vbox.addWidget(QLabel(text='Data sources', objectName='Header')) for key, button in self.checks.items(): button.setChecked(True) self.check_group.addButton(button) vbox.addWidget(button) vbox.addStretch() vbox.setSpacing(10) vbox.setContentsMargins(10, 10, 10, 10) self.setLayout(vbox) def start_stop_plotting(self): pubsub.pub.sendMessage('gui.plot.start' if self.buttons['Start']. isChecked() else 'gui.plot.stop') def clear_pplot(self): pubsub.pub.sendMessage('gui.plot.clear') if self.buttons['Start'].isChecked(): self.buttons['Start'].click() def export_data(self): if (file_path := QFileDialog.getSaveFileName( self, 'Save as...', 'Logs/Log.csv', 'CSV (*.csv)')[0]) != '': pubsub.pub.sendMessage('gui.plot.export', filepath=file_path)
def _init(self): print("Building...") self.win = QMainWindow() self._default_window_title = self.title widget = QWidget() self.win.setCentralWidget(widget) main_layout = QHBoxLayout() widget.setLayout(main_layout) main_layout.addWidget(self.slice_widget) main_layout.addWidget(self.volume_widget) side_layout = QVBoxLayout() main_layout.addLayout(side_layout) load_image_button = QPushButton("Load Section") side_layout.addWidget(load_image_button) load_image_button.clicked.connect(self.show_load_image_dialog) # Atlas BUttons button_hbox = QHBoxLayout() side_layout.addLayout(button_hbox) atlas_buttons = QButtonGroup(self.win) atlas_buttons.setExclusive(True) atlas_buttons.buttonToggled.connect(self.atlas_button_toggled) for resolution in [100, 25, 10]: atlas_button = QPushButton(f"{resolution}um") atlas_button.setCheckable(True) button_hbox.addWidget(atlas_button) atlas_buttons.addButton(atlas_button) # The 10um atlas takes way too long to download at the moment. # It needs some kind of progress bar or async download feature to be useful. # The disabled button here shows it as an option for the future, but keeps it from being used. if resolution == 10: atlas_button.setDisabled(True) self.title_reset_timer = Timer(interval=2, connect=lambda e: self._show_default_window_title(), iterations=1, start=False) self._show_default_window_title() self.statusbar = self.win.statusBar() self.image_coord_label = QLabel(text="Image Coords") self.statusbar.addPermanentWidget(self.image_coord_label) self.win.show()
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()
def __init__(self, parent: QWidget = None): """ Constructs a NewProjectDialog object. :param parent: the widget to nest this dialog inside of. If None, this dialog will be a window. :type parent: PySide2.QtWidgets.QWidget :return: The constructed new project dialog object. :rtype: NewProjectDialog """ super(NewProjectDialog, self).__init__(parent) self.ui = Ui_NewProjectDialog() self.ui.setupUi(self) self.setWindowTitle("Create New Project") # allow user to select folder to save project in self.ui.browseFilesButton_folder.clicked.connect( self._browseProjectFolders) self.ui.browseFilesButton_executable.clicked.connect( self._browseApplicationFile) # group all radio buttons together to make them mutually exclusive group = QButtonGroup() group.setExclusive(True) group.addButton(self.ui.option_Other) group.addButton(self.ui.option_idk) group.addButton(self.ui.option_Legacy) group.addButton(self.ui.option_MFC) group.addButton(self.ui.option_VB6) group.addButton(self.ui.option_VCL) group.addButton(self.ui.option_Browser) group.addButton(self.ui.option_Store_App) group.addButton(self.ui.option_WPF) group.addButton(self.ui.option_WinForms) group.addButton(self.ui.option_Qt5) group.buttonClicked.connect(self._onBackendChecked) self._radioBtnGroup = group # set default backend to unknown self.ui.option_idk.setChecked(True) self.ui.other_edit.setEnabled(False) # Remove error message originally self.ui.error_label.setText("") # disable file path editors self.ui.executable_file_edit.setEnabled(False) self.ui.project_folder_edit.setEnabled(False)
class CheckHLayout(QHBoxLayout): """Check boxes hlayout with QButtonGroup""" def __init__(self, boxes, checks, parent=None): QHBoxLayout.__init__(self) self.setSpacing(0) self.group = QButtonGroup() self.group.setExclusive(False) for i, (box, check) in enumerate(zip(boxes, checks)): cbx = QCheckBox(box) cbx.setChecked(eval(check)) self.addWidget(cbx) self.group.addButton(cbx, i) def values(self): return [cbx.isChecked() for cbx in self.group.buttons()] def setStyleSheet(self, style): for cbx in self.group.buttons(): cbx.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()
def _insert_merged(self, al, bl): if al: row = self.rowCount() self.insertRow(row) self.setItem(row, 1, self._table_item('\n'.join(map(lambda x: x[0], al)))) self.setItem(row, 2, self._table_item()) self.setItem(row, 3, self._table_item()) editor = NPTextEdit(bg_color='#ffeef0') editor.sig_size.connect(self.item(row, 3).setSizeHint) self._highlight(editor, ''.join(map(lambda x: x[1], al)), self.fmt_sub, self.fmt_sub) self.setCellWidget(row, 3, editor) if not bl: self.setItem(row, 0, self._table_item()) self.setCellWidget(row, 0, QCheckBox(checked=True)) self.cellWidget(row, 3).setReadOnly(True) if bl: row = self.rowCount() self.insertRow(row) self.setItem(row, 1, self._table_item()) self.setItem(row, 2, self._table_item('\n'.join(map(lambda x: x[0], bl)))) self.setItem(row, 3, self._table_item()) editor = NPTextEdit(bg_color='#e6ffed') editor.sig_size.connect(self.item(row, 3).setSizeHint) self._highlight(editor, ''.join(map(lambda x: x[1], bl)), self.fmt_add, self.fmt_add) self.setCellWidget(row, 3, editor) if not al: self.setCellWidget(row, 0, QCheckBox(checked=True)) if al and bl: # 변경 시 radio button 필요 group = QButtonGroup(self) group.setExclusive(True) ar = QRadioButton() br = QRadioButton(checked=True) group.addButton(ar) group.addButton(br) self.setCellWidget(self.rowCount() - 2, 0, ar) self.setCellWidget(self.rowCount() - 1, 0, br)
class _Widget(QWidget): _SPACER: int = 20 def __init__(self, parent=None): super().__init__(parent) self.mainLayout = QVBoxLayout(self) self.byTime = QCheckBox('By time', self) self.byDate = QCheckBox('By date', self) self.group = QButtonGroup(self) butLayout = QHBoxLayout() butLayout.addWidget(self.byDate) butLayout.addWidget(self.byTime) self.group.addButton(self.byDate) self.group.addButton(self.byTime) self.addRowBut = QPushButton('Add interval', self) self.addRowBut.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.gLayout = QGridLayout() self.mainLayout.addLayout(butLayout) self.mainLayout.addWidget(self.addRowBut, 0, Qt.AlignLeft) self.mainLayout.addLayout(self.gLayout) self.gLayout.setHorizontalSpacing(self._SPACER) self.group.setExclusive(False) self.byDate.setChecked(True) self.byTime.setChecked(True)
class MultiCheckWidget(QGroupBox): """Qt Widget to show multiple checkboxes for a sequence of numbers. Args: count: The number of checkboxes to show. title: Display title for group of checkboxes. selected: List of checkbox numbers to initially check. default: Whether to default boxes as checked. """ def __init__(self, *args, count: int, title: Optional[str] = "", selected: Optional[List] = None, default: Optional[bool] = False, **kwargs): super(MultiCheckWidget, self).__init__(*args, **kwargs) # QButtonGroup is the logical container # it allows us to get list of checked boxes more easily self.check_group = QButtonGroup() self.check_group.setExclusive(False) # more than one can be checked if title != "": self.setTitle(title) self.setFlat(False) else: self.setFlat(True) if selected is None: selected = list(range(count)) if default else [] check_layout = QGridLayout() self.setLayout(check_layout) for i in range(count): check = QCheckBox("%d" % (i)) # call signal/slot on self when one of the checkboxes is changed check.stateChanged.connect(lambda e: self.selectionChanged.emit()) self.check_group.addButton(check, i) check_layout.addWidget(check, i // 8, i % 8) self.setSelected(selected) """ selectionChanged signal sent when a checkbox gets a stateChanged signal """ selectionChanged = Signal() def getSelected(self) -> list: """Method to get list of the checked checkboxes. Returns: list of checked checkboxes """ selected = [] for check_button in self.check_group.buttons(): if check_button.isChecked(): selected.append(self.check_group.id(check_button)) return selected def setSelected(self, selected: list): """Method to set some checkboxes as checked. Args: selected: List of checkboxes to check. Returns: None """ for check_button in self.check_group.buttons(): if self.check_group.id(check_button) in selected: check_button.setChecked(True) else: check_button.setChecked(False) def boundingRect(self) -> QRectF: """Method required by Qt. """ return QRectF() def paint(self, painter, option, widget=None): """Method required by Qt. """ pass
class ParameterTagToolBar(QToolBar): """A toolbar to add items using drag and drop actions.""" tag_button_toggled = Signal("QVariant", "bool") manage_tags_action_triggered = Signal("bool") tag_actions_added = Signal("QVariant", "QVariant") def __init__(self, parent, db_mngr, *db_maps): """ Args: parent (DataStoreForm): tree or graph view form db_mngr (SpineDBManager): the DB manager for interacting with the db db_maps (iter): DiffDatabaseMapping instances """ super().__init__("Parameter Tag Toolbar", parent=parent) self.db_mngr = db_mngr self.db_maps = db_maps label = QLabel("Parameter tag") self.addWidget(label) self.tag_button_group = QButtonGroup(self) self.tag_button_group.setExclusive(False) self.actions = [] self.db_map_ids = [] empty = QWidget() empty.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.empty_action = self.addWidget(empty) button = QPushButton("Manage tags...") self.addWidget(button) # noinspection PyUnresolvedReferences # pylint: disable=unnecessary-lambda button.clicked.connect(lambda checked: self.manage_tags_action_triggered.emit(checked)) self.setStyleSheet(PARAMETER_TAG_TOOLBAR_SS) self.setObjectName("ParameterTagToolbar") self.tag_actions_added.connect(self._add_db_map_tag_actions) def init_toolbar(self): for button in self.tag_button_group.buttons(): self.tag_button_group.removeButton(button) for action in self.actions: self.removeAction(action) action = QAction("untagged") self.insertAction(self.empty_action, action) action.setCheckable(True) button = self.widgetForAction(action) self.tag_button_group.addButton(button, id=0) self.actions = [action] self.db_map_ids = [[(db_map, 0) for db_map in self.db_maps]] tag_data = {} for db_map in self.db_maps: for parameter_tag in self.db_mngr.get_items(db_map, "parameter tag"): tag_data.setdefault(parameter_tag["tag"], {})[db_map] = parameter_tag["id"] for tag, db_map_data in tag_data.items(): action = QAction(tag) self.insertAction(self.empty_action, action) action.setCheckable(True) button = self.widgetForAction(action) self.tag_button_group.addButton(button, id=len(self.db_map_ids)) self.actions.append(action) self.db_map_ids.append(list(db_map_data.items())) self.tag_button_group.buttonToggled["int", "bool"].connect( lambda i, checked: self.tag_button_toggled.emit(self.db_map_ids[i], checked) ) def receive_parameter_tags_added(self, db_map_data): for db_map, parameter_tags in db_map_data.items(): self.tag_actions_added.emit(db_map, parameter_tags) @Slot("QVariant", "QVariant") def _add_db_map_tag_actions(self, db_map, parameter_tags): action_texts = [a.text() for a in self.actions] for parameter_tag in parameter_tags: if parameter_tag["tag"] in action_texts: # Already a tag named after that, add db_map id information i = action_texts.index(parameter_tag["tag"]) self.db_map_ids[i].append((db_map, parameter_tag["id"])) else: action = QAction(parameter_tag["tag"]) self.insertAction(self.empty_action, action) action.setCheckable(True) button = self.widgetForAction(action) self.tag_button_group.addButton(button, id=len(self.db_map_ids)) self.actions.append(action) self.db_map_ids.append([(db_map, parameter_tag["id"])]) action_texts.append(action.text()) def receive_parameter_tags_removed(self, db_map_data): for db_map, parameter_tags in db_map_data.items(): parameter_tag_ids = {x["id"] for x in parameter_tags} self._remove_db_map_tag_actions(db_map, parameter_tag_ids) def _remove_db_map_tag_actions(self, db_map, parameter_tag_ids): for tag_id in parameter_tag_ids: i = next(k for k, x in enumerate(self.db_map_ids) if (db_map, tag_id) in x) self.db_map_ids[i].remove((db_map, tag_id)) if not self.db_map_ids[i]: self.db_map_ids.pop(i) self.removeAction(self.actions.pop(i)) def receive_parameter_tags_updated(self, db_map_data): for db_map, parameter_tags in db_map_data.items(): self._update_db_map_tag_actions(db_map, parameter_tags) def _update_db_map_tag_actions(self, db_map, parameter_tags): for parameter_tag in parameter_tags: i = next(k for k, x in enumerate(self.db_map_ids) if (db_map, parameter_tag["id"]) in x) action = self.actions[i] action.setText(parameter_tag["tag"])
def __init__(self, name: str, parent: QWidget = None): QFrame.__init__(self, parent) self.setFrameShape(QFrame.Shape(QFrame.Sunken | QFrame.StyledPanel)) self.graphicsView = GraphicsView(self) self.graphicsView.setRenderHint(QPainter.Antialiasing, False) self.graphicsView.setDragMode(QGraphicsView.RubberBandDrag) self.graphicsView.setOptimizationFlag( QGraphicsView.DontSavePainterState) self.graphicsView.setViewportUpdateMode( QGraphicsView.SmartViewportUpdate) self.graphicsView.setTransformationAnchor( QGraphicsView.AnchorUnderMouse) size = self.style().pixelMetric(QStyle.PM_ToolBarIconSize) iconSize = QSize(size, size) self.zoomInIcon = QToolButton() self.zoomInIcon.setAutoRepeat(True) self.zoomInIcon.setAutoRepeatInterval(33) self.zoomInIcon.setAutoRepeatDelay(0) self.zoomInIcon.setIcon(QIcon(":/zoomin.png")) self.zoomInIcon.setIconSize(iconSize) self.zoomOutIcon = QToolButton() self.zoomOutIcon.setAutoRepeat(True) self.zoomOutIcon.setAutoRepeatInterval(33) self.zoomOutIcon.setAutoRepeatDelay(0) self.zoomOutIcon.setIcon(QIcon(":/zoomout.png")) self.zoomOutIcon.setIconSize(iconSize) self.zoomSlider = QSlider() self.zoomSlider.setMinimum(0) self.zoomSlider.setMaximum(500) self.zoomSlider.setValue(250) self.zoomSlider.setTickPosition(QSlider.TicksRight) # Zoom slider layout zoomSliderLayout = QVBoxLayout() zoomSliderLayout.addWidget(self.zoomInIcon) zoomSliderLayout.addWidget(self.zoomSlider) zoomSliderLayout.addWidget(self.zoomOutIcon) self.rotateLeftIcon = QToolButton() self.rotateLeftIcon.setIcon(QIcon(":/rotateleft.png")) self.rotateLeftIcon.setIconSize(iconSize) self.rotateRightIcon = QToolButton() self.rotateRightIcon.setIcon(QIcon(":/rotateright.png")) self.rotateRightIcon.setIconSize(iconSize) self.rotateSlider = QSlider() self.rotateSlider.setOrientation(Qt.Horizontal) self.rotateSlider.setMinimum(-360) self.rotateSlider.setMaximum(360) self.rotateSlider.setValue(0) self.rotateSlider.setTickPosition(QSlider.TicksBelow) # Rotate slider layout rotateSliderLayout = QHBoxLayout() rotateSliderLayout.addWidget(self.rotateLeftIcon) rotateSliderLayout.addWidget(self.rotateSlider) rotateSliderLayout.addWidget(self.rotateRightIcon) self.resetButton = QToolButton() self.resetButton.setText(self.tr("0")) self.resetButton.setEnabled(False) # Label layout labelLayout = QHBoxLayout() self.label = QLabel(name) self.label2 = QLabel(self.tr("Pointer Mode")) self.selectModeButton = QToolButton() self.selectModeButton.setText(self.tr("Select")) self.selectModeButton.setCheckable(True) self.selectModeButton.setChecked(True) self.dragModeButton = QToolButton() self.dragModeButton.setText(self.tr("Drag")) self.dragModeButton.setCheckable(True) self.dragModeButton.setChecked(False) self.antialiasButton = QToolButton() self.antialiasButton.setText(self.tr("Antialiasing")) self.antialiasButton.setCheckable(True) self.antialiasButton.setChecked(False) self.openGlButton = QToolButton() self.openGlButton.setText(self.tr("OpenGL")) self.openGlButton.setCheckable(True) self.openGlButton.setEnabled(QGLFormat.hasOpenGL()) self.printButton = QToolButton() self.printButton.setIcon(QIcon(":/fileprint.png")) pointerModeGroup = QButtonGroup(self) pointerModeGroup.setExclusive(True) pointerModeGroup.addButton(self.selectModeButton) pointerModeGroup.addButton(self.dragModeButton) labelLayout.addWidget(self.label) labelLayout.addStretch() labelLayout.addWidget(self.label2) labelLayout.addWidget(self.selectModeButton) labelLayout.addWidget(self.dragModeButton) labelLayout.addStretch() labelLayout.addWidget(self.antialiasButton) labelLayout.addWidget(self.openGlButton) labelLayout.addWidget(self.printButton) topLayout = QGridLayout() topLayout.addLayout(labelLayout, 0, 0) topLayout.addWidget(self.graphicsView, 1, 0) topLayout.addLayout(zoomSliderLayout, 1, 1) topLayout.addLayout(rotateSliderLayout, 2, 0) topLayout.addWidget(self.resetButton, 2, 1) self.setLayout(topLayout) self.resetButton.clicked.connect(self.resetView) self.zoomSlider.valueChanged.connect(self.setupMatrix) self.rotateSlider.valueChanged.connect(self.setupMatrix) self.graphicsView.verticalScrollBar().valueChanged.connect( self.setResetButtonEnabled) self.graphicsView.horizontalScrollBar().valueChanged.connect( self.setResetButtonEnabled) self.selectModeButton.toggled.connect(self.togglePointerMode) self.dragModeButton.toggled.connect(self.togglePointerMode) self.antialiasButton.toggled.connect(self.toggleAntialiasing) self.openGlButton.toggled.connect(self.toggleOpenGL) self.rotateLeftIcon.clicked.connect(self.rotateLeft) self.rotateRightIcon.clicked.connect(self.rotateRight) self.zoomInIcon.clicked.connect(self.zoomIn) self.zoomOutIcon.clicked.connect(self.zoomOut) self.printButton.clicked.connect(self.print) self.setupMatrix()
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 ElchDeviceMenu(QWidget): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.labels = { key: QLabel(text=key, objectName='Header') for key in ['Controller', 'Sensor'] } self.device_menus = {key: QComboBox() for key in self.labels} self.port_menus = {key: QComboBox() for key in self.labels} self.connect_buttons = { key: QPushButton(text='Connect', objectName=key) for key in self.labels } self.buttongroup = QButtonGroup() self.buttongroup.setExclusive(False) self.buttongroup.buttonToggled.connect(self.connect_device) self.unitbuttons = { key: QRadioButton(text=key) for key in ['Temperature', 'Voltage'] } self.refresh_button = QPushButton(text='Refresh Serial', objectName='Refresh') vbox = QVBoxLayout() vbox.setSpacing(10) vbox.setContentsMargins(10, 10, 10, 10) vbox.addWidget(QLabel(text='Process Variable', objectName='Header')) for key, button in self.unitbuttons.items(): vbox.addWidget(button) button.toggled.connect( functools.partial(self.set_measurement_unit, unit=key)) vbox.addSpacing(20) for key in self.labels: self.buttongroup.addButton(self.connect_buttons[key]) self.connect_buttons[key].setCheckable(True) vbox.addWidget(self.labels[key]) vbox.addWidget(self.device_menus[key]) vbox.addWidget(self.port_menus[key]) vbox.addWidget(self.connect_buttons[key]) vbox.addSpacing(20) vbox.addWidget(self.refresh_button) self.refresh_button.clicked.connect( lambda: pubsub.pub.sendMessage('gui.request.ports')) vbox.addStretch() self.setLayout(vbox) pubsub.pub.subscribe(listener=self.update_ports, topicName='engine.answer.ports') pubsub.pub.subscribe(listener=self.update_devices, topicName='engine.answer.devices') pubsub.pub.sendMessage('gui.request.ports') def update_ports(self, ports): """Populate the controller and sensor menus with lists of device names and ports""" for key, menu in self.port_menus.items(): menu.clear() menu.addItems(ports) for port, description in ports.items(): index = menu.findText(port) menu.setItemData(index, description, Qt.ToolTipRole) def update_devices(self, devices): for key in self.device_menus: self.device_menus[key].clear() self.device_menus[key].addItems(devices[key]) def connect_device(self, source, state): key = source.objectName() port = self.port_menus[key].currentText() device = self.device_menus[key].currentText() if state: if key == 'Controller': pubsub.pub.sendMessage('gui.con.connect_controller', controller_type=device, controller_port=port) elif key == 'Sensor': pubsub.pub.sendMessage('gui.con.connect_sensor', sensor_type=device, sensor_port=port) else: if key == 'Controller': pubsub.pub.sendMessage('gui.con.disconnect_controller') elif key == 'Sensor': pubsub.pub.sendMessage('gui.con.disconnect_sensor') @staticmethod def set_measurement_unit(checked, unit): if checked: pubsub.pub.sendMessage('gui.set.units', unit=unit)
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 PaletteSelectorLayout(QGroupBox): """ Qt Layout class for a palette """ def __init__(self, fgIndex, bgIndex, palette, informFunction, parent=None): super(PaletteSelectorLayout, self).__init__("", parent) if ZXAttribute.paletteCount() != 2: raise Exception( "The palette selector is current designed for 2 palettes only") self._bright = palette self._fgIndex = fgIndex self._bgIndex = bgIndex self._informFunction = informFunction vert_layout = QVBoxLayout() self.setLayout(vert_layout) vert_layout.addWidget(QLabel("Palette Selector:")) vert_layout.addSpacing(20) # Add check box to select brightness bright_select = QCheckBox("Bright Enabled") vert_layout.addWidget(bright_select) if palette == 1: bright_select.setChecked(True) bright_select.clicked.connect(self._brightSelect) vert_layout.addSpacing(10) # Foreground color checkboxes self._fg_group = QButtonGroup() self._fg_group.setExclusive(True) self._createLayout(vert_layout, "Foreground color:", self._fg_group, self._fgIndexSelect, fgIndex) vert_layout.addSpacing(10) # Background color checkboxes self._bg_group = QButtonGroup() self._bg_group.setExclusive(True) self._createLayout(vert_layout, "Background color:", self._bg_group, self._bgIndexSelect, bgIndex) def _createLayout(self, vert_layout, labelText, buttonGroup, clickSlot, setIndex): horiz_layout = QHBoxLayout() vert_layout.addLayout(horiz_layout) horiz_layout.addWidget(QLabel(labelText)) for index in range(0, ZXAttribute.paletteSize()): button = QCheckBox() color = QColor(*ZXAttribute.getPaletteColor(index, 0)) button.setStyleSheet("background-color: {}".format(color.name())) button.setText(ZXAttribute.getPaletteName(index, 0)) if index == setIndex: button.setChecked(True) buttonGroup.addButton(button, index) horiz_layout.addWidget(button) button.clicked.connect(clickSlot) @Slot() def _brightSelect(self, checked): if not checked: self._bright = 0 else: self._bright = 1 self._informFunction(self.fgIndex, self.bgIndex, self.palette) @Slot() def _fgIndexSelect(self, checked): self._fgIndex = self._fg_group.id(self.sender()) self._informFunction(self.fgIndex, self.bgIndex, self.palette) @Slot() def _bgIndexSelect(self, checked): self._bgIndex = self._bg_group.id(self.sender()) self._informFunction(self.fgIndex, self.bgIndex, self.palette) @property def palette(self): return self._bright @property def fgIndex(self): return self._fgIndex @property def bgIndex(self): return self._bgIndex