def __init__(self, parent=None): super(BlockingClient, self).__init__(parent) self.thread = FortuneThread() self.currentFortune = '' hostLabel = QLabel("&Server name:") portLabel = QLabel("S&erver port:") for ipAddress in QNetworkInterface.allAddresses(): if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0: break else: ipAddress = QHostAddress(QHostAddress.LocalHost) ipAddress = ipAddress.toString() self.hostLineEdit = QLineEdit(ipAddress) self.portLineEdit = QLineEdit() self.portLineEdit.setValidator(QIntValidator(1, 65535, self)) hostLabel.setBuddy(self.hostLineEdit) portLabel.setBuddy(self.portLineEdit) self.statusLabel = QLabel( "This example requires that you run the Fortune Server example as well.") self.statusLabel.setWordWrap(True) self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) self.getFortuneButton.setEnabled(False) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) self.thread.newFortune.connect(self.showFortune) self.thread.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostLineEdit, 0, 1) mainLayout.addWidget(portLabel, 1, 0) mainLayout.addWidget(self.portLineEdit, 1, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Blocking Fortune Client") self.portLineEdit.setFocus()
def createButtonBox(self): self.buttonBox = QDialogButtonBox() closeButton = self.buttonBox.addButton(QDialogButtonBox.Close) helpButton = self.buttonBox.addButton(QDialogButtonBox.Help) rotateWidgetsButton = self.buttonBox.addButton("Rotate &Widgets", QDialogButtonBox.ActionRole) rotateWidgetsButton.clicked.connect(self.rotateWidgets) closeButton.clicked.connect(self.close) helpButton.clicked.connect(self.show_help)
def __init__(self, messages, hiddenLifelines, parent = None): super(HiddenMessageDialog, self).__init__(parent) self.lifelineList = hiddenLifelines self.msgList = messages layout = QVBoxLayout(self) listTitle = QLabel('Hidden Messages') layout.addWidget(listTitle) self.listHiddenMessages = QTableWidget(len(self.msgList),4) self.listHiddenMessages.setHorizontalHeaderLabels(['Index','Name','Departure','Destination']) self.listHiddenMessages.setFixedWidth(400) #self.listHiddenMessages.setSelectionMode(QtGui.QAbstractItemView.MultiSelection) self.listHiddenMessages.setSelectionBehavior(QAbstractItemView.SelectRows) for idx, msg in enumerate(self.msgList): self.listHiddenMessages.setItem(idx,0,QTableWidgetItem("%d" % msg['messageindex'])) self.listHiddenMessages.setItem(idx,1,QTableWidgetItem(msg['message'])) item = QTableWidgetItem(msg['departure']['class']) item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignRight) if msg['departure']['class'] in self.lifelineList: item.setForeground(QColor(200,200,200)) self.listHiddenMessages.setItem(idx,2,item) item = QTableWidgetItem(msg['dest']) item.setTextAlignment(QtCore.Qt.AlignmentFlag.AlignRight) if msg['dest'] in self.lifelineList: item.setForeground(QColor(200,200,200)) self.listHiddenMessages.setItem(idx,3,item) layout.addWidget(self.listHiddenMessages) buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self) buttons.button(QDialogButtonBox.Ok).setText('Show') buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) layout.addWidget(buttons)
def __init__(self): super(Dialog, self).__init__() self.createMenu() self.createHorizontalGroupBox() self.createGridGroupBox() self.createFormGroupBox() bigEditor = QTextEdit() bigEditor.setPlainText( "This widget takes up all the remaining space in the top-level layout.") buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) mainLayout = QVBoxLayout() mainLayout.setMenuBar(self.menuBar) mainLayout.addWidget(self.horizontalGroupBox) mainLayout.addWidget(self.gridGroupBox) mainLayout.addWidget(self.formGroupBox) mainLayout.addWidget(bigEditor) mainLayout.addWidget(buttonBox) self.setLayout(mainLayout) self.setWindowTitle("Basic Layouts")
def __init__(self): super(ChangeChannel, self).__init__() self.setModal(True) self.stop_recording = QCheckBox(self) self.channel = QSpinBox(self) self.channel.setRange(0, 9999) self.button_boxes = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_boxes.accepted.connect(self.accepted) self.button_boxes.rejected.connect(lambda: self.close()) self.layout = QFormLayout(self) self.layout.addRow("Channel:", self.channel) self.layout.addRow("Stop recording if in progress:", self.stop_recording) self.layout.addRow(self.button_boxes) self.setWindowTitle("Change TiVo channel") self.resize(320, 100)
def __init__(self, parent=None) -> None: super().__init__(parent) # Sets the title and size of the dialog box self.setWindowTitle('Connect to a new WIFI') self.resize(200, 100) # Set the window to modal, and the user can only close the main # interface after closing the popover self.setWindowModality(Qt.ApplicationModal) # Table layout used to layout QLabel and QLineEdit and QSpinBox grid = QGridLayout() grid.addWidget(QLabel('SSID', parent=self), 0, 0, 1, 1) self.SSIDName = QLineEdit(parent=self) self.SSIDName.setText('SSID') grid.addWidget(self.SSIDName, 0, 1, 1, 1) grid.addWidget(QLabel('password', parent=self), 1, 0, 1, 1) self.WIFIpassword = QLineEdit(parent=self) self.WIFIpassword.setText('password') grid.addWidget(self.WIFIpassword, 1, 1, 1, 1) grid.addWidget( QLabel( 'Please enter the SSID and password of the new wifi your ' 'device will connect.After connected,\n' 'the device will no longer be on this LAN and info in the list ' 'will be refreshed in 5 mins.', parent=self), 2, 0, 2, 2) # Create ButtonBox, and the user confirms and cancels buttonbox = QDialogButtonBox(parent=self) buttonbox.setOrientation(Qt.Horizontal) buttonbox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) 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 = QSpacerItem(20, 48, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(spacer) # ButtonBox layout.addWidget(buttonbox) self.setLayout(layout)
def get_connector(self, importee): """Shows a QDialog to select a connector for the given source file. Mimics similar routine in `spine_io.widgets.import_widget.ImportDialog` Args: importee (str): Path to file acting as an importee Returns: Asynchronous data reader class for the given importee """ connector_list = [CSVConnector, ExcelConnector, GdxConnector] # add others as needed connector_names = [c.DISPLAY_NAME for c in connector_list] dialog = QDialog(self._toolbox) dialog.setLayout(QVBoxLayout()) connector_list_wg = QListWidget() connector_list_wg.addItems(connector_names) # Set current item in `connector_list_wg` based on file extension _filename, file_extension = os.path.splitext(importee) if file_extension.lower().startswith(".xls"): row = connector_list.index(ExcelConnector) elif file_extension.lower() == ".csv": row = connector_list.index(CSVConnector) elif file_extension.lower() == ".gdx": row = connector_list.index(GdxConnector) else: row = None if row: connector_list_wg.setCurrentRow(row) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.button(QDialogButtonBox.Ok).clicked.connect(dialog.accept) button_box.button(QDialogButtonBox.Cancel).clicked.connect(dialog.reject) connector_list_wg.doubleClicked.connect(dialog.accept) dialog.layout().addWidget(connector_list_wg) dialog.layout().addWidget(button_box) _dirname, filename = os.path.split(importee) dialog.setWindowTitle("Select connector for '{}'".format(filename)) answer = dialog.exec_() if answer: row = connector_list_wg.currentIndex().row() return connector_list[row]
def __init__(self, geo_widget): super().__init__(geo_widget) self.setWindowTitle("Map") self.map_widget = QQuickWidget( resizeMode=QQuickWidget.SizeRootObjectToView) self.map_widget.rootContext().setContextProperty( "controller", geo_widget) filename = os.fspath(Path(__file__).resolve().parent / "coord_map.qml") url = QUrl.fromLocalFile(filename) self.map_widget.setSource(url) button_box = QDialogButtonBox() button_box.setOrientation(Qt.Horizontal) button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) lay = QVBoxLayout(self) lay.addWidget(self.map_widget) lay.addWidget(button_box) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject)
class RenameWindow(QDialog): new_name = Signal(str, str) def __init__(self, filename): super().__init__() self.title = 'Rename File' # self.left = 10 # self.top = 10 # self.width = 200 # self.height = 100 self.filename = filename self.initUI() def initUI(self): self.setWindowTitle(self.title) # self.setGeometry(self.left, self.top, self.width, self.height) self.textbox = QLineEdit(self) self.textbox.setText(self.filename) self.ok_button = QPushButton('Ok') self.ok_button.clicked.connect(self.on_click) self.cancel_button = QPushButton('Cancel') self.cancel_button.clicked.connect(self.reject) self.button_box = QDialogButtonBox() self.button_box.setOrientation(Qt.Horizontal) self.button_box.addButton(self.cancel_button, QDialogButtonBox.RejectRole) self.button_box.addButton(self.ok_button, QDialogButtonBox.AcceptRole) self.layout = QVBoxLayout() self.layout.addWidget(self.textbox) self.layout.addWidget(self.button_box) self.setLayout(self.layout) def on_click(self): self.new_name.emit(self.filename, self.textbox.text()) self.accept()
def __init__(self, parent=None, **info) -> None: super().__init__(parent) all_info = info['info'] print(f'Rear:{all_info}') self.setWindowTitle('result') self.resize(200, 100) self.setWindowModality(Qt.ApplicationModal) grid = QGridLayout() num = 0 for x in all_info.keys(): sub_name = QLabel(parent=self) sub_name.setText(x) grid.addWidget(sub_name, num, 0, 1, 1) sub_ret = QLabel(parent=self) data = all_info[x] if data['error'] == 0: sub_ret.setText('succeed') else: sub_ret.setText('error') grid.addWidget(sub_ret, num, 1, 1, 1) sub_info = QLabel(parent=self) sub_info.setText(str(all_info[x])) grid.addWidget(sub_info, num, 2, 2, 1) num += 1 buttonbox = QDialogButtonBox(parent=self) buttonbox.setOrientation(Qt.Horizontal) buttonbox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) layout = QVBoxLayout() layout.addLayout(grid) spacerItem = QSpacerItem(20, 48, QSizePolicy.Minimum, QSizePolicy.Expanding) layout.addItem(spacerItem) layout.addWidget(buttonbox) self.setLayout(layout)
def __init__(self, layout_generator, parent): super().__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) inner_widget = QWidget(self) layout = QHBoxLayout(self) layout.addStretch() layout.addWidget(inner_widget) layout.addStretch() inner_layout = QVBoxLayout(inner_widget) label = QLabel() label.setStyleSheet( "QLabel{color:white; font-weight: bold; font-size:18px;}") label.setAlignment(Qt.AlignHCenter) progress_bar = QProgressBar() progress_bar.setRange(0, layout_generator.iterations - 1) progress_bar.setTextVisible(False) button_box = QDialogButtonBox() button_box.setCenterButtons(True) previews_button = button_box.addButton("Show previews", QDialogButtonBox.NoRole) previews_button.setCheckable(True) previews_button.toggled.connect(layout_generator.set_show_previews) previews_button.toggled.connect( lambda checked: previews_button.setText( f"{'Hide' if checked else 'Show'} previews")) cancel_button = button_box.addButton("Cancel", QDialogButtonBox.NoRole) cancel_button.clicked.connect(layout_generator.stop) inner_layout.addStretch() inner_layout.addWidget(label) inner_layout.addWidget(progress_bar) inner_layout.addWidget(button_box) inner_layout.addStretch() self.setFixedSize(parent.size()) layout_generator.stopped.connect(self.close) layout_generator.progressed.connect(progress_bar.setValue) layout_generator.msg.connect(label.setText)
def __init__(self, parent=None, default_text=""): """Init Markdown editor :param default_text: Populate source edit with current comment in db. :type default_text: <str> """ super().__init__(parent) self.setWindowTitle("Cutevariant - " + self.tr("Comment editor")) self.setWindowIcon(QIcon(cm.DIR_ICONS + "app.png")) main_vlayout = QVBoxLayout() # main_vlayout.setContentsMargins(0, 0, 0, 0) self.setLayout(main_vlayout) # Setup edit view self.rich_edit = QTextEdit() # Rich text result self.source_edit = QPlainTextEdit() # Markdown content self.source_edit.setPlainText(default_text) vlayout = QVBoxLayout() vlayout.setSpacing(1) vlayout.setContentsMargins(0, 0, 0, 0) main_vlayout.addLayout(vlayout) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(self.source_edit) if parse_version(pyside_version) >= parse_version("5.14"): # RichText in Markdown is supported starting PySide 5.14 self.splitter.addWidget(self.rich_edit) # self.rich_edit.setStyleSheet( # "QWidget {background-color:'lightgray'}") self.rich_edit.setAcceptRichText(True) self.rich_edit.setAutoFormatting(QTextEdit.AutoAll) self.rich_edit.setReadOnly(True) # Update preview with Markdown content self.source_edit.textChanged.connect(self.update_rich_text) # Auto refresh rich text content now self.update_rich_text() # Setup toolbar self.toolbar = QToolBar() self.act_undo = self.toolbar.addAction(self.tr("undo"), self.source_edit.undo) self.act_undo.setIcon(FIcon(0xF054C)) self.act_undo.setShortcut(QKeySequence.Undo) self.act_redo = self.toolbar.addAction(self.tr("redo"), self.source_edit.redo) self.act_redo.setIcon(FIcon(0xF044E)) self.act_redo.setShortcut(QKeySequence.Redo) self.act_bold = self.toolbar.addAction( self.tr("bold"), lambda: self.infix("**") ) self.act_bold.setIcon(FIcon(0xF0264)) self.act_bold.setShortcut(QKeySequence("CTRL+B")) self.act_italic = self.toolbar.addAction( self.tr("italic"), lambda: self.infix("*") ) self.act_italic.setIcon(FIcon(0xF0277)) self.act_italic.setShortcut(QKeySequence("CTRL+I")) self.act_heading = self.toolbar.addAction( self.tr("insert title"), lambda: self.heading() ) self.act_heading.setShortcut(QKeySequence("CTRL+H")) self.act_heading.setIcon(FIcon(0xF0274)) self.act_unorder_list = self.toolbar.addAction( self.tr("insert list item"), self.unorder_list ) self.act_unorder_list.setIcon(FIcon(0xF0279)) self.act_quote = self.toolbar.addAction(self.tr("quote"), self.quote) self.act_quote.setIcon(FIcon(0xF027E)) self.act_link = self.toolbar.addAction(self.tr("insert link"), self.link) self.act_link.setIcon(FIcon(0xF0339)) vlayout.addWidget(self.toolbar) vlayout.addWidget(self.splitter) # Add buttons buttons = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) main_vlayout.addWidget(buttons)
class SaveDialog(QDialog): def __init__(self, main_window, nodes_dict: dict, last_export_dir: str): super(SaveDialog, self).__init__(parent=main_window) self.create_UI() self.main_window = main_window self.nodes = nodes_dict self.export_nodes = [] self.nodes_check_box_list = [] self.export_dir = last_export_dir self.package_name = '' self.set_package_name(self.export_dir) # add node-checkboxes node_keys = list(self.nodes.keys()) nodes_list_widget = self.nodes_scroll_area.takeWidget() for i in range(len(node_keys)): n = node_keys[i] node_check_box = QCheckBox(n.title) node_check_box.setObjectName('node_check_box_' + str(i)) node_check_box.setChecked(self.nodes[n]) nodes_list_widget.layout().addWidget(node_check_box) self.nodes_check_box_list.append(node_check_box) nodes_list_widget.adjustSize() self.nodes_scroll_area.setWidget(nodes_list_widget) def create_UI(self): # main layouts and widgets self.main_vertical_layout = QVBoxLayout(self) self.horizontal_layout = QHBoxLayout(self) self.nodes_vertical_layout = QVBoxLayout(self) self.nodes_vertical_layout.setAlignment(Qt.AlignTop) self.export_widget = QWidget(self) self.export_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.export_layout = QVBoxLayout(self) self.export_layout.setAlignment(Qt.AlignTop) self.export_widget.setLayout(self.export_layout) # nodes selection section self.nodes_group_box = QGroupBox(self) self.nodes_group_box.setLayout(QVBoxLayout(self)) self.nodes_group_box.setTitle('Select nodes to export') self.nodes_scroll_area = QScrollArea(self) self.nodes_list_widget = QWidget() self.nodes_list_widget.setLayout(self.nodes_vertical_layout) select_all_button = QPushButton('select all') select_all_button.clicked.connect(self.select_all) deselect_all_button = QPushButton('deselect all') deselect_all_button.clicked.connect(self.deselect_all) self.nodes_vertical_layout.addWidget(select_all_button) self.nodes_vertical_layout.addWidget(deselect_all_button) self.nodes_scroll_area.setWidget(self.nodes_list_widget) self.nodes_group_box.layout().addWidget(self.nodes_scroll_area) # export settings section self.select_package_dir_button = QPushButton('Select package dir', self) self.select_package_dir_button.clicked.connect(self.select_package_dir) self.package_dir_label = QLabel() self.export_button = QPushButton('export', self) self.export_button.clicked.connect(self.export) self.export_layout.addWidget(self.select_package_dir_button) self.export_layout.addWidget(self.package_dir_label) self.export_layout.addWidget(self.export_button) # button box self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).clicked.connect( self.close_) # merge layouts self.horizontal_layout.addWidget(self.nodes_group_box) self.horizontal_layout.addWidget(self.export_widget) self.main_vertical_layout.addLayout(self.horizontal_layout) self.main_vertical_layout.addWidget(self.button_box) self.setWindowTitle('Export Nodes') self.resize(500, 300) def select_all(self): for cb in self.nodes_check_box_list: cb.setChecked(True) def deselect_all(self): for cb in self.nodes_check_box_list: cb.setChecked(False) def select_package_dir(self): self.export_dir = QFileDialog.getExistingDirectory( self, 'Select the package folder where your nodes shall be exported at', '../packages') self.set_package_name(self.export_dir) def set_package_name(self, path: str): self.package_name = os.path.basename(path) self.package_dir_label.setText('package dir: ' + path) def get_selected_nodes(self): nodes = [] node_keys = list(self.nodes.keys()) for i in range(len(self.nodes_check_box_list)): check_box: QCheckBox = self.nodes_check_box_list[i] if check_box.isChecked(): nodes.append(node_keys[int(check_box.objectName()[15:])]) return nodes def export(self): self.export_nodes = self.get_selected_nodes() nodes_dict = {} module_name_separator = '___' nodes_list = [] node_titles_count = {} # title (str) : number (int) for i in range(len(self.export_nodes)): n: Node = self.export_nodes[i] c_w: NodeContentWidget = n.content_widget node_number = 0 title = c_w.get_node_title() if title in node_titles_count.values(): node_number = node_titles_count[title] # index node_titles_count[title] += 1 else: node_titles_count[title] = 1 node_data = c_w.get_json_data( package_name=self.package_name, module_name_separator=module_name_separator, number=node_number) nodes_list.append(node_data) nodes_dict['nodes'] = nodes_list info_dict = {'type': 'Ryven nodes package'} whole_dict = { **info_dict, **nodes_dict } # merges single two dictionaries to one json_data = json.dumps(whole_dict) print(json_data) # create dirs and save files if not os.path.isdir(self.export_dir + '/nodes'): os.mkdir(self.export_dir + '/nodes') save_file(self.export_dir + '/' + self.package_name + '.rpc', json_data) for i in range(len(self.export_nodes)): n = self.export_nodes[i] module_name = nodes_list[i]['module name'] # create node folder node_dir = self.export_dir + '/nodes/' + module_name if not os.path.isdir(node_dir): os.mkdir(node_dir) # create widgets folder widgets_dir = node_dir + '/widgets' if not os.path.isdir(widgets_dir): os.mkdir(widgets_dir) n.content_widget.save_metacode_files( node_dir=node_dir, widgets_dir=widgets_dir, module_name_separator=module_name_separator, module_name=module_name) def close_(self): self.main_window.last_exported_nodes = self.get_selected_nodes() self.main_window.last_export_path = self.export_dir self.close()
class FilterWidgetBase(QWidget): """Filter widget class.""" okPressed = Signal() cancelPressed = Signal() def __init__(self, parent): """Init class. Args: parent (QWidget) """ super().__init__(parent) # parameters self._filter_state = set() self._filter_empty_state = None self._search_text = '' self.search_delay = 200 # create ui elements self._ui_vertical_layout = QVBoxLayout(self) self._ui_list = QListView() self._ui_edit = QLineEdit() self._ui_edit.setPlaceholderText('Search') self._ui_edit.setClearButtonEnabled(True) self._ui_buttons = QDialogButtonBox(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._ui_vertical_layout.addWidget(self._ui_edit) self._ui_vertical_layout.addWidget(self._ui_list) self._ui_vertical_layout.addWidget(self._ui_buttons) # add models self._search_timer = QTimer( ) # Used to limit search so it doesn't search when typing self._search_timer.setSingleShot(True) self._filter_model = None def connect_signals(self): self._ui_list.clicked.connect(self._filter_model._handle_index_clicked) self._search_timer.timeout.connect(self._filter_list) self._ui_edit.textChanged.connect(self._text_edited) self._ui_buttons.button(QDialogButtonBox.Ok).clicked.connect( self._apply_filter) self._ui_buttons.button(QDialogButtonBox.Cancel).clicked.connect( self._cancel_filter) def save_state(self): """Saves the state of the FilterCheckboxListModel.""" self._filter_state = self._filter_model.get_selected() if self._filter_model._show_empty: self._filter_empty_state = self._filter_model._empty_selected def reset_state(self): """Sets the state of the FilterCheckboxListModel to saved state.""" self._filter_model.set_selected(self._filter_state, self._filter_empty_state) def clear_filter(self): """Selects all items in FilterCheckBoxListModel.""" self._filter_model.reset_selection() self.save_state() def has_filter(self): """Returns true if any item is filtered in FilterCheckboxListModel false otherwise.""" return not self._filter_model._all_selected def set_filter_list(self, data): """Sets the list of items to filter.""" self._filter_state = list(data) self._filter_model.set_list(self._filter_state) def _apply_filter(self): """Apply current filter and save state.""" self._filter_model.apply_filter() self.save_state() self._ui_edit.setText('') self.okPressed.emit() def _cancel_filter(self): """Cancel current edit of filter and set the state to the stored state.""" self._filter_model.remove_filter() self.reset_state() self._ui_edit.setText('') self.cancelPressed.emit() def _filter_list(self): """Filter list with current text.""" self._filter_model.set_filter(self._search_text) def _text_edited(self, new_text): """Callback for edit text, starts/restarts timer. Start timer after text is edited, restart timer if text is edited before last time out. """ self._search_text = new_text self._search_timer.start(self.search_delay)
from PySide2.QtWidgets import QDialogButtonBox, QVBoxLayout, QLabel app = QApplication() dlg = QDialog() QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel def accept(): print('downloading') urllib.request.urlretrieve(url, target) print('done') dlg.close() def reject(): exit(0) buttonBox = QDialogButtonBox(QBtn) buttonBox.accepted.connect(accept) buttonBox.rejected.connect(reject) layout = QVBoxLayout() label = QLabel(dlg) label.setText( f'Equilibrium core (pyo3d) was not found on your system.\nNo problem, we can download it automatically\n\nFile will be downloaded from:\n{url} \n\nand will be saved as:\n{target}' ) layout.addWidget(label) link = QLabel(dlg) link.setText( '<a href="https://www.open-ocean.org/equilibrium-core/">More info: https://www.open-ocean.org/equilibrium-core/ </a>' ) link.setOpenExternalLinks(True)
class Dialog(QDialog): def __init__(self): super(Dialog, self).__init__() self.rotableWidgets = [] self.createRotableGroupBox() self.createOptionsGroupBox() self.createButtonBox() mainLayout = QGridLayout() mainLayout.addWidget(self.rotableGroupBox, 0, 0) mainLayout.addWidget(self.optionsGroupBox, 1, 0) mainLayout.addWidget(self.buttonBox, 2, 0) mainLayout.setSizeConstraint(QLayout.SetMinimumSize) self.mainLayout = mainLayout self.setLayout(self.mainLayout) self.setWindowTitle("Dynamic Layouts") def rotateWidgets(self): count = len(self.rotableWidgets) if count % 2 == 1: raise AssertionError("Number of widgets must be even") for widget in self.rotableWidgets: self.rotableLayout.removeWidget(widget) self.rotableWidgets.append(self.rotableWidgets.pop(0)) for i in range(count//2): self.rotableLayout.addWidget(self.rotableWidgets[count - i - 1], 0, i) self.rotableLayout.addWidget(self.rotableWidgets[i], 1, i) def buttonsOrientationChanged(self, index): self.mainLayout.setSizeConstraint(QLayout.SetNoConstraint) self.setMinimumSize(0, 0) orientation = Qt.Orientation(int(self.buttonsOrientationComboBox.itemData(index))) if orientation == self.buttonBox.orientation(): return self.mainLayout.removeWidget(self.buttonBox) spacing = self.mainLayout.spacing() oldSizeHint = self.buttonBox.sizeHint() + QSize(spacing, spacing) self.buttonBox.setOrientation(orientation) newSizeHint = self.buttonBox.sizeHint() + QSize(spacing, spacing) if orientation == Qt.Horizontal: self.mainLayout.addWidget(self.buttonBox, 2, 0) self.resize(self.size() + QSize(-oldSizeHint.width(), newSizeHint.height())) else: self.mainLayout.addWidget(self.buttonBox, 0, 3, 2, 1) self.resize(self.size() + QSize(newSizeHint.width(), -oldSizeHint.height())) self.mainLayout.setSizeConstraint(QLayout.SetDefaultConstraint) def show_help(self): QMessageBox.information(self, "Dynamic Layouts Help", "This example shows how to change layouts " "dynamically.") def createRotableGroupBox(self): self.rotableGroupBox = QGroupBox("Rotable Widgets") self.rotableWidgets.append(QSpinBox()) self.rotableWidgets.append(QSlider()) self.rotableWidgets.append(QDial()) self.rotableWidgets.append(QProgressBar()) count = len(self.rotableWidgets) for i in range(count): self.rotableWidgets[i].valueChanged[int].\ connect(self.rotableWidgets[(i+1) % count].setValue) self.rotableLayout = QGridLayout() self.rotableGroupBox.setLayout(self.rotableLayout) self.rotateWidgets() def createOptionsGroupBox(self): self.optionsGroupBox = QGroupBox("Options") buttonsOrientationLabel = QLabel("Orientation of buttons:") buttonsOrientationComboBox = QComboBox() buttonsOrientationComboBox.addItem("Horizontal", Qt.Horizontal) buttonsOrientationComboBox.addItem("Vertical", Qt.Vertical) buttonsOrientationComboBox.currentIndexChanged[int].connect(self.buttonsOrientationChanged) self.buttonsOrientationComboBox = buttonsOrientationComboBox optionsLayout = QGridLayout() optionsLayout.addWidget(buttonsOrientationLabel, 0, 0) optionsLayout.addWidget(self.buttonsOrientationComboBox, 0, 1) optionsLayout.setColumnStretch(2, 1) self.optionsGroupBox.setLayout(optionsLayout) def createButtonBox(self): self.buttonBox = QDialogButtonBox() closeButton = self.buttonBox.addButton(QDialogButtonBox.Close) helpButton = self.buttonBox.addButton(QDialogButtonBox.Help) rotateWidgetsButton = self.buttonBox.addButton("Rotate &Widgets", QDialogButtonBox.ActionRole) rotateWidgetsButton.clicked.connect(self.rotateWidgets) closeButton.clicked.connect(self.close) helpButton.clicked.connect(self.show_help)
def __init__(self, motors={}, listOfSequenceHandler=None, sequence=None, modifySequence=False): """ Initializtion of the window for creating a new sequence :param motors: The dictionary of all the motors :param listOfSequenceHandler: The handler of the list of sequence """ QDialog.__init__(self) # Set the window icon appIcon = QIcon(icon) self.setWindowIcon(appIcon) ## Flag if the sequence is a modified one or a new one self.__modifySequence = modifySequence ## The handler of the list of sequence self.__listOfSequenceHandler = listOfSequenceHandler ## The dictionary of all the motors self.__motors = motors ## The new sequence self.__sequence = sequence ## A dictionary of the positions of the new sequence self.__wantedPositions = {} ## The layout of the create sequence window self.__layout = QVBoxLayout(self) ## The widget for the name of the sequenc self.nameEntry = QLineEdit() self.nameEntry.setText(self.__sequence.getName()) ## The label for the widget in which the name of the sequence is written self.__nameLabel = QLabel("Sequence Name") ## The list of the different moves that forms the sequence self.__listOfMoveLabels = QListWidget() moveNumber = 1 for move in self.__sequence.getMoves(): # Set text for the move label labelText = "move " + str(moveNumber) + ": " moveNumber += 1 for motor in self.__motors: labelText += self.__motors[motor].getName() + " " + \ str(move.getMotorPosition(self.__motors[motor].getName())) + ", " label = moveLabel(move, labelText, self.__motors) # insert label to the head of the list self.__listOfMoveLabels.insertItem(0, label) # Put the sliders of the create sequence window in a list ## List of sliders in the create sequence window self.listOfSliders = [] dictOfSlider = dict() for motor in self.__motors: dictOfSlider[motor] = QSlider(Qt.Horizontal) dictOfSlider[motor].setMaximum(4095) dictOfSlider[motor].setValue( self.__motors[motor].getCurrentPosition()) dictOfSlider[motor].sliderMoved.connect( self.__motors[motor].setGoalPosition) self.listOfSliders.append(dictOfSlider[motor]) ## Message to make the user put a name to the sequence self.__noNameMessage = QMessageBox() self.__noNameMessage.setIcon(QMessageBox.Warning) self.__noNameMessage.setWindowIcon(appIcon) self.__noNameMessage.setText( "Please name your sequence before saving it") self.__noNameMessage.setStandardButtons(QMessageBox.Ok) # Renable the create sequence window and closes the message self.__noNameMessage.accepted.connect(self.enableWindow) ## Warning message to make sure the user doen't want to save the sequence self.__warningMessage = QMessageBox() self.__warningMessage.setIcon(QMessageBox.Warning) self.__warningMessage.setWindowIcon(appIcon) self.__warningMessage.setText( "Are you sure you want to close this window? Your sequence will not be saved" ) self.__warningMessage.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) # Close the create sequence window and the message self.__warningMessage.accepted.connect(self.reject) # Renable the create sequence window and closes the message self.__warningMessage.rejected.connect(self.enableWindow) # Set the text for the labels ## Labels for the motors in the UI self.__motorLabels = [] for motorNumber in range(0, len(motors)): self.__motorLabels.append( QLabel("Motor " + str(motorNumber + 1) + " position")) ## Button to add a move to the sequence and procede to the next move self.nextMoveButton = QPushButton("Save Move") ## Buttons to accept or cancel the creation of a sequence self.buttonBox = QDialogButtonBox() self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) # If ok pressed add the sequence to the list self.buttonBox.accepted.connect( lambda: self.addSequenceToList(self.__modifySequence)) # If cancel pressed close the create sequence window self.buttonBox.rejected.connect(self.__warningMessage.exec) # Renable the main window when the create sequence closes self.rejected.connect(self.__listOfSequenceHandler.enableUi) self.accepted.connect(self.__listOfSequenceHandler.enableUi) self.nextMoveButton.clicked.connect(self.addMovetoSequence) self.__listOfMoveLabels.itemDoubleClicked.connect( self.moveDoubleClicked) # Build the vertical layout with the different widgets self.__layout.addWidget(self.__nameLabel) self.__layout.addWidget(self.nameEntry) self.__layout.addWidget(self.__listOfMoveLabels) for motorNumber in range(len(self.__motors)): self.__layout.addWidget(self.__motorLabels[motorNumber]) self.__layout.addWidget(self.listOfSliders[motorNumber]) self.__layout.addWidget(self.nextMoveButton) self.__layout.addWidget(self.buttonBox) # Connect the qwidgetlist to the custom right click menu self.__listOfMoveLabels.setContextMenuPolicy(Qt.CustomContextMenu) self.__listOfMoveLabels.customContextMenuRequested.connect( self.rightClickMenu)
def setup(self): self.setAttribute(Qt.WA_DeleteOnClose) fixed = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) rightCenter = (Qt.AlignRight | Qt.AlignVCenter) # all the input boxes self.inputGrid = QGridLayout() self.inputGrid.setSpacing(5) h_spc = self.inputGrid.horizontalSpacing() v_spc = self.inputGrid.verticalSpacing() # RGB self.redInput = QSpinBox() self.grnInput = QSpinBox() self.bluInput = QSpinBox() self.rgbInputs = [self.redInput, self.grnInput, self.bluInput] self.redLabel = QLabel('&R:') self.redLabel.setToolTip('Red') self.grnLabel = QLabel('&G:') self.grnLabel.setToolTip('Green') self.bluLabel = QLabel('&B:') self.bluLabel.setToolTip('Blue') self.rgbLabels = [self.redLabel, self.grnLabel, self.bluLabel] self.redLabel.setBuddy(self.redInput) self.grnLabel.setBuddy(self.grnInput) self.bluLabel.setBuddy(self.bluInput) # HSV self.hueInput = QSpinBox() self.satInput = QSpinBox() self.valInput = QSpinBox() self.hsvInputs = [self.hueInput, self.satInput, self.valInput] self.hueInput.setWrapping(True) self.hueLabel = QLabel('&H:') self.hueLabel.setToolTip('Hue') self.satLabel = QLabel('&S:') self.satLabel.setToolTip('Saturation') self.valLabel = QLabel('&V:') self.valLabel.setToolTip('Value') self.hsvLabels = [self.hueLabel, self.satLabel, self.valLabel] self.hueLabel.setBuddy(self.hueInput) self.satLabel.setBuddy(self.satInput) self.valLabel.setBuddy(self.valInput) # CMYK self.cInput = QSpinBox() self.mInput = QSpinBox() self.yInput = QSpinBox() self.kInput = QSpinBox() self.cmykInputs = [self.cInput, self.mInput, self.yInput, self.kInput] self.cLabel = QLabel('&C:') self.cLabel.setToolTip('Cyan') self.mLabel = QLabel('&M:') self.mLabel.setToolTip('Magenta') self.yLabel = QLabel('&Y:') self.yLabel.setToolTip('Yellow') self.kLabel = QLabel('&K:') self.kLabel.setToolTip('Black') self.cmykLabels = [self.cLabel, self.mLabel, self.yLabel, self.kLabel] self.cLabel.setBuddy(self.cInput) self.mLabel.setBuddy(self.mInput) self.yLabel.setBuddy(self.yInput) self.kLabel.setBuddy(self.kInput) for i in self.rgbInputs + self.hsvInputs + self.cmykInputs: i.setRange(0, 255) i.setFixedSize(35, 22) i.setAlignment(Qt.AlignCenter) i.setButtonSymbols(QAbstractSpinBox.NoButtons) self.hueInput.setRange(0, 359) # HTML self.htmlInput = QLineEdit() self.htmlInput.setFixedSize(35 + 22 + h_spc, 22) # spans 2 cols self.htmlInput.setPlaceholderText('html') self.htmlInput.setAlignment(Qt.AlignCenter) regex = QRegExp('[0-9A-Fa-f]{1,6}') valid = QRegExpValidator(regex) self.htmlInput.setValidator(valid) self.htmlLabel = QLabel('&#') self.htmlLabel.setToolTip('Web color') self.htmlLabel.setBuddy(self.htmlInput) self.inputLabels = (self.rgbLabels + self.hsvLabels + self.cmykLabels + [ self.htmlLabel, ]) for i in self.inputLabels: i.setFixedSize(22, 22) i.setAlignment(rightCenter) #i.setFrameShape(QFrame.Box) self.inputs = self.rgbInputs + self.hsvInputs + self.cmykInputs for i in self.inputs: i.valueChanged.connect(self._colorEdited) self.htmlInput.editingFinished.connect(self._colorEdited) # picker button self.pickButton = QPushButton('&Pick') self.pickButton.setToolTip('Pick a color from the screen') self.pickButton.setFixedSize(35, 22) self.pickButton.clicked.connect(self.pickColor) # color display self.colorDisplay = QFrame() self.colorDisplay.setFixedSize(55, 4 * 22 + 3 * v_spc) # spans 4 rows self.colorDisplay.setFrameShape(QFrame.Panel) self.colorDisplay.setFrameShadow(QFrame.Sunken) self.colorDisplay.setAutoFillBackground(True) # show button / random button self.showButton = QPushButton('Sho&w') self.showButton.setToolTip('Show named colors on color wheel') self.showButton.setFixedSize(35, 22) self.showButton.setCheckable(True) self.showButton.clicked.connect(self.showColors) self.rndButton = QPushButton('R&and') self.rndButton.setToolTip('Select a random color') self.rndButton.setFixedSize(35, 22) self.rndButton.clicked.connect(self.randomColor) # color wheel self.colorWheel = wheel() self.colorWheel.setFixedSize(256, 256) #265, 265) self.colorWheel.currentColorChanged.connect(self.setColor) # named colors combo box self.colorNamesCB = QComboBox() self.colorNamesCB.setFixedSize(70 + 66 + 4 * h_spc, 22) # spans 5 cols #self.colorNamesCB.addItem('- Color Names -') self.cNameLabel = QLabel('&Named:') self.cNameLabel.setBuddy(self.colorNamesCB) self.cNameLabel.setAlignment(rightCenter) #self.cNameLabel.setFrameShape(QFrame.Box) self.cNameLabel.setFixedSize(55, 22) lst = [i for i in QColor.colorNames() if str(i) != 'transparent'] lst = [(i, QColor(i)) for i in lst] lst.append(('Cosmic latte', '#fff8e7')) lst.append(('rebeccapurple', '#663399')) self.addNamedColors(lst) self.colorNamesCB.currentIndexChanged.connect(self._colorEdited) self.inputs += [self.htmlInput, self.colorWheel, self.colorNamesCB] # ok/cancel buttons self.dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.dialogButtons.accepted.connect(self.closeValid) self.dialogButtons.rejected.connect(self.closeInvalid) self.dialogButtons.setCenterButtons(True) # pass QColorDialog.NoButtons, False to setOption to remove # assemble grid! # 0 1 2 3 4 5 6 # # color wheeeeeeeeeeeeellll 0 # disp r: rrr h: hhh c: ccc 1 # disp g: ggg s: sss m: mmm 2 # disp b: bbb v: vvv y: yyy 3 # disp ## -html- pic k: kkk 4 # name coooommmboooobox rnd 5 #.addWidget(widget, row, col, rspan, cspan) self.inputGrid.addWidget(self.colorWheel, 0, 0, 1, 7) self.inputGrid.addWidget(self.colorDisplay, 1, 0, 4, 1) for i, lab in enumerate(self.rgbLabels, 1): self.inputGrid.addWidget(lab, i, 1, 1, 1) self.inputGrid.addWidget(self.htmlLabel, 4, 1, 1, 1) for i, wid in enumerate(self.rgbInputs, 1): self.inputGrid.addWidget(wid, i, 2) self.inputGrid.addWidget(self.htmlInput, 4, 2, 1, 2) for i, lab in enumerate(self.hsvLabels, 1): self.inputGrid.addWidget(lab, i, 3, 1, 1) for i, wid in enumerate(self.hsvInputs, 1): self.inputGrid.addWidget(wid, i, 4, 1, 1) self.inputGrid.addWidget(self.pickButton, 4, 4, 1, 1) for i, lab in enumerate(self.cmykLabels, 1): self.inputGrid.addWidget(lab, i, 5, 1, 1) for i, wid in enumerate(self.cmykInputs, 1): self.inputGrid.addWidget(wid, i, 6, 1, 1) self.inputGrid.addWidget(self.colorNamesCB, 5, 1, 1, 5) self.inputGrid.addWidget(self.cNameLabel, 5, 0, 1, 1) self.inputGrid.addWidget(self.showButton, 5, 6, 1, 1) self.inputGrid.addWidget(self.rndButton, 5, 6, 1, 1) self.inputGrid.addWidget(self.dialogButtons, 6, 0, 1, 7) self.setWindowTitle('Select color') ico = self.style().standardIcon(QStyle.SP_DialogResetButton) self.setWindowIcon(ico) self.setLayout(self.inputGrid) self.setFixedSize(self.sizeHint()) self.useRandom() #False)
def __init__(self): super(AdomanyFormDialog, self).__init__() self.mezo_nevek = [] self.mezo_ertekek = [] self.layout = QFormLayout() self.setLayout(self.layout) reg_datum = QRegExp('(19[0-9]{2}\\-([0][1-9]|[1][0-2])\\-([0][1-9]|[1-2][0-9]|3[0-1]))|(20[0-9]{2}\\-([0][1-9]|[1][0-2])\\-([0][1-9]|[1-2][0-9]|3[0-1]))') datumvalidator = QRegExpValidator(reg_datum) self.jogcim_completer = QCompleter() self.get_jogcimdata() fizmod_completer = QCompleter() self.fizmod_model = QStringListModel() fizmod_completer.setModel(self.fizmod_model) self.get_fizmoddata() self.mezo_nevek.append("Dátum") self.mezo_nevek.append("Nyugta száma") self.mezo_nevek.append("Befizető") self.mezo_nevek.append("Jogcím") self.mezo_nevek.append("Összeg") self.mezo_nevek.append("Fizetési mód") self.mezo_nevek.append("Megjegyzés") for i in range(len(self.mezo_nevek)): if (self.mezo_nevek[i] == "Dátum"): datum = QLineEdit() datum.setText(QDate.currentDate().toString("yyyy-MM-dd")) datum.setValidator(datumvalidator) self.mezo_ertekek.append(datum) if (self.mezo_nevek[i] == "Nyugta száma"): nyugta = QLineEdit() nyugta.setText("0") self.mezo_ertekek.append(nyugta) if (self.mezo_nevek[i] == "Befizető"): self.befizeto = QLineEdit() self.befizeto.setText("Vendég") self.mezo_ertekek.append(self.befizeto) if (self.mezo_nevek[i] == "Jogcím"): self.jogcim = QLineEdit() self.jogcim.setCompleter(self.jogcim_completer) self.mezo_ertekek.append(self.jogcim) if (self.mezo_nevek[i] == "Összeg"): self.osszeg = QLineEdit() self.mezo_ertekek.append(self.osszeg) if (self.mezo_nevek[i] == "Fizetési mód"): self.fizmod = QLineEdit() self.fizmod.setCompleter(fizmod_completer) self.fizmod.setText("Készpénz") self.mezo_ertekek.append(self.fizmod) if (self.mezo_nevek[i] == "Megjegyzés"): megjegyzes = QLineEdit() self.mezo_ertekek.append(megjegyzes) self.layout.addRow(f"{self.mezo_nevek[i]}", self.mezo_ertekek[i]) buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) self.layout.addWidget(buttonbox)
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)
class LoginDialog(QDialog): def __init__(self, parent=None): super(LoginDialog, self).__init__(parent) # formatting self.setWindowTitle("Login") # validator regexp = QtCore.QRegExp('[A-Za-z0-9_]+') validator = QtGui.QRegExpValidator(regexp) # widgets self.usernameInput = QLineEdit() self.usernameInput.setValidator(validator) self.passwordInput = QLineEdit() self.passwordInput.setValidator(validator) self.passwordInput.setEchoMode(QLineEdit.Password) # OK and Cancel buttons self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.buttons.button(QDialogButtonBox.Ok).setText('Login') self.buttons.button(QDialogButtonBox.Cancel).setText('Quit') self.buttons.setCenterButtons(True) # signals self.usernameInput.textChanged.connect(self.check_input) self.usernameInput.textChanged.emit(self.usernameInput.text()) self.passwordInput.textChanged.connect(self.check_input) self.passwordInput.textChanged.emit(self.passwordInput.text()) # layout self.mainLayout = QVBoxLayout(self) self.mainLayout.addWidget(self.usernameInput) self.mainLayout.addWidget(self.passwordInput) self.mainLayout.addWidget(self.buttons) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) # self.buttons.setEnabled(False) self.usernameInput.setFocus() def check_input(self, *args, **kwargs): sender = self.sender() validator = sender.validator() state = validator.validate(sender.text(), 0)[0] if state == QtGui.QValidator.Acceptable: color = '#ffffff' elif state == QtGui.QValidator.Intermediate: color = '#ffffff' else: color = '#f6989d' # red sender.setStyleSheet('QLineEdit { background-color: %s }' % color) # get current data from the dialog def getUsernameInput(self): return self.usernameInput.text() # get current data from the dialog def getPasswordInput(self): return self.passwordInput.text() # static method to create the dialog and return (date, time, accepted) @staticmethod def run(parent=None): dialog = LoginDialog(parent) result = dialog.exec_() username = dialog.getUsernameInput() password = dialog.getPasswordInput() return username, password, result == QDialog.Accepted
def __init__(self, parent, object_class_item, db_mngr, *db_maps): """ Args: parent (SpineDBEditor): data store widget object_class_item (ObjectClassItem) db_mngr (SpineDBManager) *db_maps: database mappings """ super().__init__(parent) self.object_class_item = object_class_item self.db_mngr = db_mngr self.db_maps = db_maps self.db_map = db_maps[0] self.db_maps_by_codename = { db_map.codename: db_map for db_map in db_maps } self.db_combo_box = QComboBox(self) self.header_widget = QWidget(self) self.group_name_line_edit = QLineEdit(self) header_layout = QHBoxLayout(self.header_widget) header_layout.addWidget(QLabel(f"Group name: ")) header_layout.addWidget(self.group_name_line_edit) header_layout.addSpacing(32) header_layout.addWidget(QLabel("Database")) header_layout.addWidget(self.db_combo_box) self.non_members_tree = QTreeWidget(self) self.non_members_tree.setHeaderLabel("Non members") self.non_members_tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.non_members_tree.setColumnCount(1) self.non_members_tree.setIndentation(0) self.members_tree = QTreeWidget(self) self.members_tree.setHeaderLabel("Members") self.members_tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.members_tree.setColumnCount(1) self.members_tree.setIndentation(0) self.add_button = QToolButton() self.add_button.setToolTip("<p>Add selected non-members.</p>") self.add_button.setIcon(QIcon(":/icons/menu_icons/cube_plus.svg")) self.add_button.setIconSize(QSize(24, 24)) self.add_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.add_button.setText(">>") self.remove_button = QToolButton() self.remove_button.setToolTip("<p>Remove selected members.</p>") self.remove_button.setIcon(QIcon(":/icons/menu_icons/cube_minus.svg")) self.remove_button.setIconSize(QSize(24, 24)) self.remove_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.remove_button.setText("<<") self.vertical_button_widget = QWidget() vertical_button_layout = QVBoxLayout(self.vertical_button_widget) vertical_button_layout.addStretch() vertical_button_layout.addWidget(self.add_button) vertical_button_layout.addWidget(self.remove_button) vertical_button_layout.addStretch() self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) layout = QGridLayout(self) layout.addWidget(self.header_widget, 0, 0, 1, 3, Qt.AlignHCenter) layout.addWidget(self.non_members_tree, 1, 0) layout.addWidget(self.vertical_button_widget, 1, 1) layout.addWidget(self.members_tree, 1, 2) layout.addWidget(self.button_box, 2, 0, 1, 3) self.setAttribute(Qt.WA_DeleteOnClose) self.db_combo_box.addItems(list(self.db_maps_by_codename)) self.db_map_object_ids = { db_map: { x["name"]: x["id"] for x in self.db_mngr.get_items_by_field( self.db_map, "object", "class_id", self.object_class_item.db_map_id(db_map)) } for db_map in db_maps } self.reset_list_widgets(db_maps[0].codename) self.connect_signals()
class AddOrManageObjectGroupDialog(QDialog): def __init__(self, parent, object_class_item, db_mngr, *db_maps): """ Args: parent (SpineDBEditor): data store widget object_class_item (ObjectClassItem) db_mngr (SpineDBManager) *db_maps: database mappings """ super().__init__(parent) self.object_class_item = object_class_item self.db_mngr = db_mngr self.db_maps = db_maps self.db_map = db_maps[0] self.db_maps_by_codename = { db_map.codename: db_map for db_map in db_maps } self.db_combo_box = QComboBox(self) self.header_widget = QWidget(self) self.group_name_line_edit = QLineEdit(self) header_layout = QHBoxLayout(self.header_widget) header_layout.addWidget(QLabel(f"Group name: ")) header_layout.addWidget(self.group_name_line_edit) header_layout.addSpacing(32) header_layout.addWidget(QLabel("Database")) header_layout.addWidget(self.db_combo_box) self.non_members_tree = QTreeWidget(self) self.non_members_tree.setHeaderLabel("Non members") self.non_members_tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.non_members_tree.setColumnCount(1) self.non_members_tree.setIndentation(0) self.members_tree = QTreeWidget(self) self.members_tree.setHeaderLabel("Members") self.members_tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.members_tree.setColumnCount(1) self.members_tree.setIndentation(0) self.add_button = QToolButton() self.add_button.setToolTip("<p>Add selected non-members.</p>") self.add_button.setIcon(QIcon(":/icons/menu_icons/cube_plus.svg")) self.add_button.setIconSize(QSize(24, 24)) self.add_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.add_button.setText(">>") self.remove_button = QToolButton() self.remove_button.setToolTip("<p>Remove selected members.</p>") self.remove_button.setIcon(QIcon(":/icons/menu_icons/cube_minus.svg")) self.remove_button.setIconSize(QSize(24, 24)) self.remove_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.remove_button.setText("<<") self.vertical_button_widget = QWidget() vertical_button_layout = QVBoxLayout(self.vertical_button_widget) vertical_button_layout.addStretch() vertical_button_layout.addWidget(self.add_button) vertical_button_layout.addWidget(self.remove_button) vertical_button_layout.addStretch() self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) layout = QGridLayout(self) layout.addWidget(self.header_widget, 0, 0, 1, 3, Qt.AlignHCenter) layout.addWidget(self.non_members_tree, 1, 0) layout.addWidget(self.vertical_button_widget, 1, 1) layout.addWidget(self.members_tree, 1, 2) layout.addWidget(self.button_box, 2, 0, 1, 3) self.setAttribute(Qt.WA_DeleteOnClose) self.db_combo_box.addItems(list(self.db_maps_by_codename)) self.db_map_object_ids = { db_map: { x["name"]: x["id"] for x in self.db_mngr.get_items_by_field( self.db_map, "object", "class_id", self.object_class_item.db_map_id(db_map)) } for db_map in db_maps } self.reset_list_widgets(db_maps[0].codename) self.connect_signals() def connect_signals(self): """Connect signals to slots.""" self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.db_combo_box.currentTextChanged.connect(self.reset_list_widgets) self.add_button.clicked.connect(self.add_members) self.remove_button.clicked.connect(self.remove_members) def reset_list_widgets(self, database): self.db_map = self.db_maps_by_codename[database] object_ids = self.db_map_object_ids[self.db_map] members = [] non_members = [] for obj_name, obj_id in object_ids.items(): if obj_id in self.initial_member_ids(): members.append(obj_name) elif obj_id != self.initial_entity_id(): non_members.append(obj_name) member_items = [QTreeWidgetItem([obj_name]) for obj_name in members] non_member_items = [ QTreeWidgetItem([obj_name]) for obj_name in non_members ] self.members_tree.addTopLevelItems(member_items) self.non_members_tree.addTopLevelItems(non_member_items) def initial_member_ids(self): raise NotImplementedError() def initial_entity_id(self): raise NotImplementedError() @Slot(bool) def add_members(self, checked=False): indexes = sorted([ self.non_members_tree.indexOfTopLevelItem(x) for x in self.non_members_tree.selectedItems() ], reverse=True) items = [ self.non_members_tree.takeTopLevelItem(ind) for ind in indexes ] self.members_tree.addTopLevelItems(items) @Slot(bool) def remove_members(self, checked=False): indexes = sorted([ self.members_tree.indexOfTopLevelItem(x) for x in self.members_tree.selectedItems() ], reverse=True) items = [self.members_tree.takeTopLevelItem(ind) for ind in indexes] self.non_members_tree.addTopLevelItems(items) def _check_validity(self): if not self.members_tree.topLevelItemCount(): self.parent().msg_error.emit( "Please select at least one member object.") return False return True
class ConfigureUsersDialog(QDialog): def __init__(self, users): super().__init__() self.setWindowTitle("Configure Users") self.model = TableModel(users) self.layout = QVBoxLayout() self.table_layout = QHBoxLayout() self.users_table = QTableView() self.users_table.setModel(self.model) self.users_table.horizontalHeader().setStretchLastSection(True) self.table_layout.addWidget(self.users_table) self.table_buttons_layout = QVBoxLayout() self.add_user_button = QPushButton() self.add_user_button.setText("Add User") self.add_user_button.clicked.connect(self._add_user_clicked) self.delete_user_button = QPushButton() self.delete_user_button.setText("Delete User") self.delete_user_button.clicked.connect(self._delete_user_clicked) self.table_buttons_layout.addSpacerItem( QSpacerItem(0, 0, vData=QSizePolicy.Expanding)) self.table_buttons_layout.addWidget(self.add_user_button) self.table_buttons_layout.addWidget(self.delete_user_button) self.table_buttons_layout.addSpacerItem( QSpacerItem(0, 0, vData=QSizePolicy.Expanding)) self.table_layout.addLayout(self.table_buttons_layout) self.layout.addLayout(self.table_layout) self.error_text = QLabel() self.error_text.setStyleSheet("color: red;") self.layout.addWidget(self.error_text) self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_box.accepted.connect(self._on_accepted_clicked) self.button_box.rejected.connect(self.reject) self.layout.addWidget(self.button_box) self.setLayout(self.layout) self.resize(600, 400) def _on_accepted_clicked(self): self._complete_table() if not self.model.are_users_unique(): self.error_text.setText("Name must be unique for each user") return self.error_text.setText("") self.accept() def _complete_table(self): # The currently selected cell only updates the model when 'return' is # pressed or another cell is selected. If the user is updating a value # then clicks 'OK' without pressing 'return' then the change is lost. # This is a Qt thing - the workaround is to take focus from the table. self.button_box.button(self.button_box.Ok).setFocus() def _add_user_clicked(self): self.users_table.model().insertRow(self.model.num_rows) def _delete_user_clicked(self): rows_to_remove = set() for index in self.users_table.selectedIndexes(): rows_to_remove.add(index.row()) self.users_table.model().removeRows(list(rows_to_remove)) def get_users(self): return self.model.users
def create_UI(self): # main layouts and widgets self.main_vertical_layout = QVBoxLayout(self) self.horizontal_layout = QHBoxLayout(self) self.nodes_vertical_layout = QVBoxLayout(self) self.nodes_vertical_layout.setAlignment(Qt.AlignTop) self.export_widget = QWidget(self) self.export_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.export_layout = QVBoxLayout(self) self.export_layout.setAlignment(Qt.AlignTop) self.export_widget.setLayout(self.export_layout) # nodes selection section self.nodes_group_box = QGroupBox(self) self.nodes_group_box.setLayout(QVBoxLayout(self)) self.nodes_group_box.setTitle('Select nodes to export') self.nodes_scroll_area = QScrollArea(self) self.nodes_list_widget = QWidget() self.nodes_list_widget.setLayout(self.nodes_vertical_layout) select_all_button = QPushButton('select all') select_all_button.clicked.connect(self.select_all) deselect_all_button = QPushButton('deselect all') deselect_all_button.clicked.connect(self.deselect_all) self.nodes_vertical_layout.addWidget(select_all_button) self.nodes_vertical_layout.addWidget(deselect_all_button) self.nodes_scroll_area.setWidget(self.nodes_list_widget) self.nodes_group_box.layout().addWidget(self.nodes_scroll_area) # export settings section self.select_package_dir_button = QPushButton('Select package dir', self) self.select_package_dir_button.clicked.connect(self.select_package_dir) self.package_dir_label = QLabel() self.export_button = QPushButton('export', self) self.export_button.clicked.connect(self.export) self.export_layout.addWidget(self.select_package_dir_button) self.export_layout.addWidget(self.package_dir_label) self.export_layout.addWidget(self.export_button) # button box self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).clicked.connect( self.close_) # merge layouts self.horizontal_layout.addWidget(self.nodes_group_box) self.horizontal_layout.addWidget(self.export_widget) self.main_vertical_layout.addLayout(self.horizontal_layout) self.main_vertical_layout.addWidget(self.button_box) self.setWindowTitle('Export Nodes') self.resize(500, 300)
class colorPicker(QDialog): "custom colorDialog from Orthallelous" currentColorChanged = Signal(QColor) colorSelected = Signal(QColor) def __init__(self, initial=None, parent=None): super(colorPicker, self).__init__(parent) self.setup() self.setColor(initial) def currentColor(self): return self._color def setColor(self, qcolor=None): if qcolor is None: self._color = QColor('#ffffff') else: self._color = QColor(qcolor) self._colorEdited() @staticmethod def getColor(initial=None, parent=None, title=None): dialog = colorPicker(initial, parent) if title: dialog.setWindowTitle(title) result = dialog.exec_() color = dialog._color return color def closeValid(self): "emits colorSelected signal with valid color on OK" self.currentColorChanged.emit(self._color) self.colorSelected.emit(self._color) self.close() def closeInvalid(self): "emits colorSelected signal with invalid color on Cancel" self._color = QColor() self.colorSelected.emit(QColor()) self.close() def setOption(self, option, Bool=True): if option == QColorDialog.NoButtons: if not Bool: self.dialogButtons.blockSignals(False) self.dialogButtons.setEnabled(True) self.dialogButtons.show() else: self.dialogButtons.blockSignals(True) self.dialogButtons.setEnabled(False) self.dialogButtons.hide() self.setFixedSize(self.sizeHint()) def _colorEdited(self): "internal color editing" sender, color = self.sender(), self._color for i in self.inputs: i.blockSignals(True) # get values if sender in self.rgbInputs: # RGB color.setRgb(*[i.value() for i in self.rgbInputs]) elif sender in self.hsvInputs: # HSV color.setHsv(*[i.value() for i in self.hsvInputs]) elif sender in self.cmykInputs: # CMYK color.setCmyk(*[i.value() for i in self.cmykInputs]) elif sender is self.htmlInput: # HTML color.setNamedColor('#' + str(self.htmlInput.text()).lower()) elif sender is self.colorWheel: # WHEEL color = self._color = self.colorWheel.getColor() elif sender is self.colorNamesCB: # NAMED dat = self.colorNamesCB.itemData(self.colorNamesCB.currentIndex()) try: color = self._color = QColor(dat.toString()) # PyQt except: color = self._color = QColor(str(dat)) # PySide self.colorNamesCB.setToolTip(self.colorNamesCB.currentText()) else: pass # set values for i, j in zip(color.getRgb()[:-1], self.rgbInputs): j.setValue(i) for i, j in zip(color.getHsv()[:-1], self.hsvInputs): j.setValue(i) for i, j in zip(color.getCmyk()[:-1], self.cmykInputs): j.setValue(i) self.htmlInput.setText(color.name()[1:]) self.colorWheel.setColor(color) idx = self.colorNamesCB.findData(color.name()) self.colorNamesCB.setCurrentIndex(idx) # will be blank if not in list pal = self.colorDisplay.palette() pal.setColor(self.colorDisplay.backgroundRole(), color) self.colorDisplay.setPalette(pal) #self.colorDisplay.setStyleSheet('background:' + color.name()) for i in self.inputs: i.blockSignals(False) self.currentColorChanged.emit(color) def pickColor(self): "pick a color on the screen, part 1" # screenshot desktop self._img = QApplication.primaryScreen().grabWindow(0) self._view = QGraphicsView(self) scene = QGraphicsScene(self) # display screenshot at full size self._view.setWindowFlags(Qt.FramelessWindowHint) self._view.setWindowFlags(Qt.WindowType_Mask) self._view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scene.addPixmap(self._img) #; self._view.setScene(scene) self._mag = magnifier() self._mag.setBackground(self._img) self._mag.setSize(11, 11) scene.addItem(self._mag) self._view.setScene(scene) self._appview = QApplication self._appview.setOverrideCursor(Qt.CrossCursor) self._view.showFullScreen() self._view.mousePressEvent = self._pickedColor def _pickedColor(self, event): "pick a color on the screen, part 2" color = QColor(self._img.toImage().pixel(event.globalPos())) self._view.hide() self._appview.restoreOverrideCursor() self._color = color self._colorEdited() self._mag = self._appview = self._view = self._img = None def showColors(self): "show location of colors on color wheel" if self.showButton.isChecked(): self.colorWheel.showNamedColors(True) else: self.colorWheel.showNamedColors(False) def useRandom(self, state=True): "toggles show colors button and random color button" if state: self.showButton.blockSignals(True) self.showButton.setChecked(False) self.showButton.hide() self.showColors() self.rndButton.blockSignals(False) self.rndButton.show() else: self.showButton.blockSignals(False) self.showButton.show() self.rndButton.blockSignals(True) self.rndButton.hide() def randomColor(self): "select a random color" rand = random.randint col = QColor() col.setHsv(rand(0, 359), rand(0, 255), rand(0, 255)) #col.setRgb(rand(0, 255), rand(0, 255), rand(0, 255)) self.setColor(col) return col def getNamedColors(self): "returns a list [(name, #html)] from the named colors combobox" lst = [] for i in range(self.colorNamesCB.count()): name = str(self.colorNamesCB.itemText(i)) try: # PyQt html = str(self.colorNamesCB.itemData(i).toString()) except AttributeError: # PySide html = str(self.colorNamesCB.itemData(i)) lst.append((name, html)) return lst def addNamedColors(self, lst): "add a list [('name', '#html'), ] of named colors (repeats removed)" col = self.getNamedColors() + lst lst = [(i[0], QColor(i[1])) for i in col] sen = set() add = sen.add # http://stackoverflow.com/a/480227 uni = [x for x in lst if not (x[1].name() in sen or add(x[1].name()))] self.colorNamesCB.clear() for i, j in sorted(uni, key=lambda q: q[1].getHsv()): icon = QPixmap(16, 16) icon.fill(j) self.colorNamesCB.addItem(QIcon(icon), i, j.name()) self.colorWheel.setNamedColors([(i, j.name()) for i, j in uni]) self.cNameLabel.setToolTip('Named colors\n{:,} colors'.format( len(uni))) def setup(self): self.setAttribute(Qt.WA_DeleteOnClose) fixed = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) rightCenter = (Qt.AlignRight | Qt.AlignVCenter) # all the input boxes self.inputGrid = QGridLayout() self.inputGrid.setSpacing(5) h_spc = self.inputGrid.horizontalSpacing() v_spc = self.inputGrid.verticalSpacing() # RGB self.redInput = QSpinBox() self.grnInput = QSpinBox() self.bluInput = QSpinBox() self.rgbInputs = [self.redInput, self.grnInput, self.bluInput] self.redLabel = QLabel('&R:') self.redLabel.setToolTip('Red') self.grnLabel = QLabel('&G:') self.grnLabel.setToolTip('Green') self.bluLabel = QLabel('&B:') self.bluLabel.setToolTip('Blue') self.rgbLabels = [self.redLabel, self.grnLabel, self.bluLabel] self.redLabel.setBuddy(self.redInput) self.grnLabel.setBuddy(self.grnInput) self.bluLabel.setBuddy(self.bluInput) # HSV self.hueInput = QSpinBox() self.satInput = QSpinBox() self.valInput = QSpinBox() self.hsvInputs = [self.hueInput, self.satInput, self.valInput] self.hueInput.setWrapping(True) self.hueLabel = QLabel('&H:') self.hueLabel.setToolTip('Hue') self.satLabel = QLabel('&S:') self.satLabel.setToolTip('Saturation') self.valLabel = QLabel('&V:') self.valLabel.setToolTip('Value') self.hsvLabels = [self.hueLabel, self.satLabel, self.valLabel] self.hueLabel.setBuddy(self.hueInput) self.satLabel.setBuddy(self.satInput) self.valLabel.setBuddy(self.valInput) # CMYK self.cInput = QSpinBox() self.mInput = QSpinBox() self.yInput = QSpinBox() self.kInput = QSpinBox() self.cmykInputs = [self.cInput, self.mInput, self.yInput, self.kInput] self.cLabel = QLabel('&C:') self.cLabel.setToolTip('Cyan') self.mLabel = QLabel('&M:') self.mLabel.setToolTip('Magenta') self.yLabel = QLabel('&Y:') self.yLabel.setToolTip('Yellow') self.kLabel = QLabel('&K:') self.kLabel.setToolTip('Black') self.cmykLabels = [self.cLabel, self.mLabel, self.yLabel, self.kLabel] self.cLabel.setBuddy(self.cInput) self.mLabel.setBuddy(self.mInput) self.yLabel.setBuddy(self.yInput) self.kLabel.setBuddy(self.kInput) for i in self.rgbInputs + self.hsvInputs + self.cmykInputs: i.setRange(0, 255) i.setFixedSize(35, 22) i.setAlignment(Qt.AlignCenter) i.setButtonSymbols(QAbstractSpinBox.NoButtons) self.hueInput.setRange(0, 359) # HTML self.htmlInput = QLineEdit() self.htmlInput.setFixedSize(35 + 22 + h_spc, 22) # spans 2 cols self.htmlInput.setPlaceholderText('html') self.htmlInput.setAlignment(Qt.AlignCenter) regex = QRegExp('[0-9A-Fa-f]{1,6}') valid = QRegExpValidator(regex) self.htmlInput.setValidator(valid) self.htmlLabel = QLabel('&#') self.htmlLabel.setToolTip('Web color') self.htmlLabel.setBuddy(self.htmlInput) self.inputLabels = (self.rgbLabels + self.hsvLabels + self.cmykLabels + [ self.htmlLabel, ]) for i in self.inputLabels: i.setFixedSize(22, 22) i.setAlignment(rightCenter) #i.setFrameShape(QFrame.Box) self.inputs = self.rgbInputs + self.hsvInputs + self.cmykInputs for i in self.inputs: i.valueChanged.connect(self._colorEdited) self.htmlInput.editingFinished.connect(self._colorEdited) # picker button self.pickButton = QPushButton('&Pick') self.pickButton.setToolTip('Pick a color from the screen') self.pickButton.setFixedSize(35, 22) self.pickButton.clicked.connect(self.pickColor) # color display self.colorDisplay = QFrame() self.colorDisplay.setFixedSize(55, 4 * 22 + 3 * v_spc) # spans 4 rows self.colorDisplay.setFrameShape(QFrame.Panel) self.colorDisplay.setFrameShadow(QFrame.Sunken) self.colorDisplay.setAutoFillBackground(True) # show button / random button self.showButton = QPushButton('Sho&w') self.showButton.setToolTip('Show named colors on color wheel') self.showButton.setFixedSize(35, 22) self.showButton.setCheckable(True) self.showButton.clicked.connect(self.showColors) self.rndButton = QPushButton('R&and') self.rndButton.setToolTip('Select a random color') self.rndButton.setFixedSize(35, 22) self.rndButton.clicked.connect(self.randomColor) # color wheel self.colorWheel = wheel() self.colorWheel.setFixedSize(256, 256) #265, 265) self.colorWheel.currentColorChanged.connect(self.setColor) # named colors combo box self.colorNamesCB = QComboBox() self.colorNamesCB.setFixedSize(70 + 66 + 4 * h_spc, 22) # spans 5 cols #self.colorNamesCB.addItem('- Color Names -') self.cNameLabel = QLabel('&Named:') self.cNameLabel.setBuddy(self.colorNamesCB) self.cNameLabel.setAlignment(rightCenter) #self.cNameLabel.setFrameShape(QFrame.Box) self.cNameLabel.setFixedSize(55, 22) lst = [i for i in QColor.colorNames() if str(i) != 'transparent'] lst = [(i, QColor(i)) for i in lst] lst.append(('Cosmic latte', '#fff8e7')) lst.append(('rebeccapurple', '#663399')) self.addNamedColors(lst) self.colorNamesCB.currentIndexChanged.connect(self._colorEdited) self.inputs += [self.htmlInput, self.colorWheel, self.colorNamesCB] # ok/cancel buttons self.dialogButtons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.dialogButtons.accepted.connect(self.closeValid) self.dialogButtons.rejected.connect(self.closeInvalid) self.dialogButtons.setCenterButtons(True) # pass QColorDialog.NoButtons, False to setOption to remove # assemble grid! # 0 1 2 3 4 5 6 # # color wheeeeeeeeeeeeellll 0 # disp r: rrr h: hhh c: ccc 1 # disp g: ggg s: sss m: mmm 2 # disp b: bbb v: vvv y: yyy 3 # disp ## -html- pic k: kkk 4 # name coooommmboooobox rnd 5 #.addWidget(widget, row, col, rspan, cspan) self.inputGrid.addWidget(self.colorWheel, 0, 0, 1, 7) self.inputGrid.addWidget(self.colorDisplay, 1, 0, 4, 1) for i, lab in enumerate(self.rgbLabels, 1): self.inputGrid.addWidget(lab, i, 1, 1, 1) self.inputGrid.addWidget(self.htmlLabel, 4, 1, 1, 1) for i, wid in enumerate(self.rgbInputs, 1): self.inputGrid.addWidget(wid, i, 2) self.inputGrid.addWidget(self.htmlInput, 4, 2, 1, 2) for i, lab in enumerate(self.hsvLabels, 1): self.inputGrid.addWidget(lab, i, 3, 1, 1) for i, wid in enumerate(self.hsvInputs, 1): self.inputGrid.addWidget(wid, i, 4, 1, 1) self.inputGrid.addWidget(self.pickButton, 4, 4, 1, 1) for i, lab in enumerate(self.cmykLabels, 1): self.inputGrid.addWidget(lab, i, 5, 1, 1) for i, wid in enumerate(self.cmykInputs, 1): self.inputGrid.addWidget(wid, i, 6, 1, 1) self.inputGrid.addWidget(self.colorNamesCB, 5, 1, 1, 5) self.inputGrid.addWidget(self.cNameLabel, 5, 0, 1, 1) self.inputGrid.addWidget(self.showButton, 5, 6, 1, 1) self.inputGrid.addWidget(self.rndButton, 5, 6, 1, 1) self.inputGrid.addWidget(self.dialogButtons, 6, 0, 1, 7) self.setWindowTitle('Select color') ico = self.style().standardIcon(QStyle.SP_DialogResetButton) self.setWindowIcon(ico) self.setLayout(self.inputGrid) self.setFixedSize(self.sizeHint()) self.useRandom() #False)
def init_ui(self): self.setFixedWidth(500) self.setWindowTitle(_('Event properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_main_title = QLabel(_('Main title')) self.item_main_title = QLineEdit() self.layout.addRow(self.label_main_title, self.item_main_title) self.label_sub_title = QLabel(_('Sub title')) self.item_sub_title = QTextEdit() self.item_sub_title.setMaximumHeight(100) self.layout.addRow(self.label_sub_title, self.item_sub_title) self.label_start_date = QLabel(_('Start date')) self.item_start_date = QDateTimeEdit() self.item_start_date.setDisplayFormat('yyyy.MM.dd HH:mm:ss') self.layout.addRow(self.label_start_date, self.item_start_date) self.label_end_date = QLabel(_('End date')) # self.item_end_date = QCalendarWidget() self.item_end_date = QDateTimeEdit() self.item_end_date.setDisplayFormat('yyyy.MM.dd HH:mm:ss') self.layout.addRow(self.label_end_date, self.item_end_date) self.label_location = QLabel(_('Location')) self.item_location = QLineEdit() self.layout.addRow(self.label_location, self.item_location) self.label_type = QLabel(_('Event type')) self.item_type = AdvComboBox() self.item_type.addItems(RaceType.get_titles()) self.layout.addRow(self.label_type, self.item_type) self.label_relay_legs = QLabel(_('Relay legs')) self.item_relay_legs = QSpinBox() self.item_relay_legs.setMinimum(1) self.item_relay_legs.setMaximum(20) self.item_relay_legs.setValue(3) self.layout.addRow(self.label_relay_legs, self.item_relay_legs) self.item_type.currentTextChanged.connect(self.change_type) self.label_refery = QLabel(_('Chief referee')) self.item_refery = QLineEdit() self.layout.addRow(self.label_refery, self.item_refery) self.label_secretary = QLabel(_('Secretary')) self.item_secretary = QLineEdit() self.layout.addRow(self.label_secretary, self.item_secretary) self.label_url = QLabel(_('URL')) self.item_url = QLineEdit() self.layout.addRow(self.label_url, self.item_url) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.set_values_from_model() self.show()
class NetworkSettingsDialog(QDialog): def __init__(self, parent=None): super(NetworkSettingsDialog, self).__init__(parent) self.parent = parent self.setModal(True) self.setWindowTitle("Hálózati beállítások") self.resize(400, 300) self.layout = QVBoxLayout() self.setLayout(self.layout) adatok = QGridLayout() self.layout.addLayout(adatok) self.ip = QLineEdit() self.token = QLineEdit() self.station = QLineEdit() self.valtozott = False self.uj_station = False self.is_exist_config() self.check_config() adatok.addWidget(QLabel("IP cím: "), 0, 0) self.ip.setDisabled(True) adatok.addWidget(self.ip, 0, 1) adatok.addWidget(QLabel("Token: "), 1, 0) self.token.setDisabled(True) adatok.addWidget(self.token, 1, 1) adatok.addWidget(QLabel("Állomás azonosító: "), 2, 0) self.station.setDisabled(True) self.station.editingFinished.connect(self.change_name) adatok.addWidget(self.station, 2, 1) self.space = QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(self.space) self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonbox.addButton("Módosít", QDialogButtonBox.ActionRole) self.buttonbox.button(QDialogButtonBox.Ok).setText('Mentés') self.buttonbox.button(QDialogButtonBox.Ok).setDisabled(True) self.buttonbox.button(QDialogButtonBox.Cancel).setText('Mégsem') self.buttonbox.clicked.connect(self.buttonbox_click) self.layout.addWidget(self.buttonbox) def is_exist_config(self): ip_fizikai = get_ip_address() if os.path.exists('config.ini'): # Van config.ini, ki kell értékelni config.read('config.ini') station_id = config['DEFAULT'].get('station id') if (station_id is None) or len(station_id) < 4: self.valtozott = True msg = QMessageBox() msg.setStyleSheet("fonz-size: 20px") msg.setWindowTitle("Hibás állomás név!") msg.setText( '<html style="font-size: 14px; color: red">Nem megfelelő állomás-azonosító!<br></html>' + '<html style="font-size: 16px">Kérem módosítsa a beállításokat!</html>' ) msg.exec_() station = secrets.token_hex(8) config.set('DEFAULT', 'station id', station) self.station.setText(station) ip_config = config['DEFAULT'].get('station ip') if ip_fizikai != ip_config: self.valtozott = True msg = QMessageBox() msg.setStyleSheet("fonz-size: 20px") msg.setWindowTitle("Hibás beállítás!") msg.setText( '<html style="font-size: 14px; color: red">A fizikai IP cím eltér a konfigurációtól!<br></html>' + '<html style="font-size: 16px">Kérem módosítsa a beállításokat!</html>' ) msg.exec_() self.ip.setText(ip_fizikai) config.set('DEFAULT', 'station ip', ip_fizikai) secret = config['DEFAULT'].get('secret key') if (secret is None) or len(secret) != 32: self.valtozott = True newsecret = secrets.token_hex(16) config.set('DEFAULT', 'secret key', newsecret) self.token.setText(newsecret) with open('config.ini', 'w') as configfile: config.write(configfile) else: # Nincs config.ini, alapértékekkel inicializálni self.valtozott = True msg = QMessageBox() msg.setStyleSheet("fonz-size: 20px") msg.setWindowTitle("Hiányzó beállítás file!") msg.setText( '<html style="font-size: 14px; color: red">Nem tudtam beolvasni a konfigurációt!<br></html>' + '<html style="font-size: 16px">Kérem módosítsa a beállításokat!</html>' ) msg.exec_() kulcs = secrets.token_hex(16) station = secrets.token_hex(8) self.token.setText(kulcs) self.ip.setText(ip_fizikai) self.station.setText(station) config.set('DEFAULT', 'secret key', kulcs) config.set('DEFAULT', 'station ip', ip_fizikai) config.set('DEFAULT', 'station id', secrets.token_hex(8)) with open('config.ini', 'w') as configfile: config.write(configfile) def check_config(self): ip_config = config['DEFAULT'].get('station ip') station_id = config['DEFAULT'].get('station id') secret = config['DEFAULT'].get('secret key') self.ip.setText(ip_config) self.station.setText(station_id) self.token.setText(secret) # todo Ellenőrizni, hogy van-e, és mi van a db-ben model2 = QSqlQueryModel() query = QSqlQuery( f"SELECT * FROM reged_station where secret_key = '{secret}'", db=db) model2.setQuery(query) if model2.record(0).value(0): if self.station.text() != model2.record(0).value( 1) or self.ip.text() != model2.record(0).value( 2) or self.token.text() != model2.record(0).value(3): self.valtozott = True self.rec_id = model2.record(0).value(0) else: self.uj_station = True def change_name(self): self.valtozott = True def buttonbox_click(self, b): if b.text() == "Mentés": self.accept() elif b.text() == "Módosít": self.modify() else: self.reject() def modify(self): self.buttonbox.button(QDialogButtonBox.Ok).setDisabled(False) self.station.setDisabled(False) def accept(self): if self.uj_station: now = QDateTime.currentDateTime() network = QSqlTableModel() network.setTable("reged_station") rec_net = network.record() rec_net.remove(0) rec_net.setValue(0, self.station.text()) rec_net.setValue(1, self.ip.text()) rec_net.setValue(2, self.token.text()) rec_net.setValue(3, now) if network.insertRecord(-1, rec_net): network.submitAll() else: db.rollback() self.uj_station = False if self.valtozott: # Módosítani a db-t és a config.ini-t # config.ini update config.set('DEFAULT', 'secret key', self.token.text()) config.set('DEFAULT', 'station ip', self.ip.text()) config.set('DEFAULT', 'station id', self.station.text()) with open('config.ini', 'w') as configfile: config.write(configfile) # db update now = QDateTime.currentDateTime().toString( "yyyy-MM-ddThh:mm:ss.sss") model3 = QSqlQueryModel() query3 = QSqlQuery( f"update reged_station set station_id='{self.station.text()}', station_ip='{self.ip.text()}', timestamp='{now}' where secret_key='{self.token.text()}'", db=db) model3.setQuery(query3) self.valtozott = False super().accept() def reject(self): # Ha valami db művelet kell if self.valtozott or self.uj_station: msg = QMessageBox() msg.setStyleSheet("fonz-size: 20px") msg.setWindowTitle("Regisztrációs eltérés!") msg.setText( '<html style="font-size: 14px; color: red">Kérem módosítás után mentse a beállításokat!<br></html>' ) msg.exec_() else: super().reject() # # if __name__ == '__main__': # app = QApplication([]) # win = NetworkSettingsDialog() # win.show() # app.exec_()
class QCartConnectDialog(QDialog): def __init__(self): super(QCartConnectDialog, self).__init__() self.accepted = False self._init_widgets() def accept(self): self.accepted = True super().accept() def reject(self): self.accepted = False super().reject() def handleRadioButtons(self): if self.connectRad.isChecked(): self.hostText.setEnabled(True) self.portText.setEnabled(True) self.hostText.setText("") self.portText.setText("") else: self.hostText.setEnabled(False) self.portText.setEnabled(False) self.hostText.setText("NEW") self.portText.setText("NEW") def _init_widgets(self): self.resize(530, 180) main_layout = QVBoxLayout() frame = QFrame() frame.setFrameShape(QFrame.NoFrame) frame.setFrameShadow(QFrame.Plain) frameLayout = QVBoxLayout() self.connectRad = QRadioButton(frame) self.createRad = QRadioButton(frame) self.connectRad.setChecked(True) self.connectRad.toggled.connect(self.handleRadioButtons) self.createRad.toggled.connect(self.handleRadioButtons) frameLayout.addWidget(self.connectRad) internalFrame = QFrame() internalFrameLayout = QHBoxLayout(internalFrame) hostLabel = QLabel() portLabel = QLabel() self.hostText = QLineEdit() self.portText = QLineEdit() internalFrameLayout.addWidget(hostLabel) internalFrameLayout.addWidget(self.hostText) internalFrameLayout.addWidget(portLabel) internalFrameLayout.addWidget(self.portText) self.portText.setMaximumSize(QSize(80, 200)) internalFrame.setLayout(internalFrameLayout) frameLayout.addWidget(internalFrame) frameLayout.addWidget(self.createRad) frame.setLayout(frameLayout) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) main_layout.addWidget(frame) main_layout.addWidget(self.buttonBox) self.setLayout(main_layout) self.setWindowTitle("Cartprograph Connect") self.connectRad.setText("Connect to Existing Cartprograph Server") self.createRad.setText("Create New Cartprograph Server") hostLabel.setText("Host") portLabel.setText("Port") @classmethod def launch(cls): dialog = cls() dialog.exec_() if dialog.accepted: return True, dialog.hostText.text(), dialog.portText.text() return False, None, None
class IconColorEditor(QDialog): """An editor to let the user select an icon and a color for an object_class. """ def __init__(self, parent): """Init class.""" super().__init__(parent) # , Qt.Popup) icon_size = QSize(32, 32) self.icon_mngr = IconListManager(icon_size) self.setWindowTitle("Select icon and color") self.icon_widget = QWidget(self) self.icon_list = QListView(self.icon_widget) self.icon_list.setViewMode(QListView.IconMode) self.icon_list.setIconSize(icon_size) self.icon_list.setResizeMode(QListView.Adjust) self.icon_list.setItemDelegate(_IconPainterDelegate(self)) self.icon_list.setMovement(QListView.Static) self.icon_list.setMinimumHeight(400) icon_widget_layout = QVBoxLayout(self.icon_widget) icon_widget_layout.addWidget(QLabel("Font Awesome icons")) self.line_edit = QLineEdit() self.line_edit.setPlaceholderText("Search icons for...") icon_widget_layout.addWidget(self.line_edit) icon_widget_layout.addWidget(self.icon_list) self.color_dialog = QColorDialog(self) self.color_dialog.setWindowFlags(Qt.Widget) self.color_dialog.setOption(QColorDialog.NoButtons, True) self.color_dialog.setOption(QColorDialog.DontUseNativeDialog, True) self.button_box = QDialogButtonBox(self) self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) top_widget = QWidget(self) top_layout = QHBoxLayout(top_widget) top_layout.addWidget(self.icon_widget) top_layout.addWidget(self.color_dialog) layout = QVBoxLayout(self) layout.addWidget(top_widget) layout.addWidget(self.button_box) self.proxy_model = QSortFilterProxyModel(self) self.proxy_model.setSourceModel(self.icon_mngr.model) self.proxy_model.filterAcceptsRow = self._proxy_model_filter_accepts_row self.icon_list.setModel(self.proxy_model) self.setAttribute(Qt.WA_DeleteOnClose) self.connect_signals() def _proxy_model_filter_accepts_row(self, source_row, source_parent): """Overridden method to filter icons according to search terms. """ text = self.line_edit.text() if not text: return QSortFilterProxyModel.filterAcceptsRow( self.proxy_model, source_row, source_parent) searchterms = self.icon_mngr.model.index( source_row, 0, source_parent).data(Qt.UserRole + 1) return any([text in term for term in searchterms]) def connect_signals(self): """Connect signals to slots.""" self.line_edit.textEdited.connect(self.proxy_model.invalidateFilter) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) def set_data(self, data): icon_code, color_code = interpret_icon_id(data) self.icon_mngr.init_model() for i in range(self.proxy_model.rowCount()): index = self.proxy_model.index(i, 0) if index.data(Qt.UserRole) == icon_code: self.icon_list.setCurrentIndex(index) break self.color_dialog.setCurrentColor(QColor(color_code)) def data(self): icon_code = self.icon_list.currentIndex().data(Qt.UserRole) color_code = self.color_dialog.currentColor().rgb() return make_icon_id(icon_code, color_code)
class CreateSequenceWindow(QDialog): """ Window for creating a new sequence """ def __init__(self, motors={}, listOfSequenceHandler=None, sequence=None, modifySequence=False): """ Initializtion of the window for creating a new sequence :param motors: The dictionary of all the motors :param listOfSequenceHandler: The handler of the list of sequence """ QDialog.__init__(self) # Set the window icon appIcon = QIcon(icon) self.setWindowIcon(appIcon) ## Flag if the sequence is a modified one or a new one self.__modifySequence = modifySequence ## The handler of the list of sequence self.__listOfSequenceHandler = listOfSequenceHandler ## The dictionary of all the motors self.__motors = motors ## The new sequence self.__sequence = sequence ## A dictionary of the positions of the new sequence self.__wantedPositions = {} ## The layout of the create sequence window self.__layout = QVBoxLayout(self) ## The widget for the name of the sequenc self.nameEntry = QLineEdit() self.nameEntry.setText(self.__sequence.getName()) ## The label for the widget in which the name of the sequence is written self.__nameLabel = QLabel("Sequence Name") ## The list of the different moves that forms the sequence self.__listOfMoveLabels = QListWidget() moveNumber = 1 for move in self.__sequence.getMoves(): # Set text for the move label labelText = "move " + str(moveNumber) + ": " moveNumber += 1 for motor in self.__motors: labelText += self.__motors[motor].getName() + " " + \ str(move.getMotorPosition(self.__motors[motor].getName())) + ", " label = moveLabel(move, labelText, self.__motors) # insert label to the head of the list self.__listOfMoveLabels.insertItem(0, label) # Put the sliders of the create sequence window in a list ## List of sliders in the create sequence window self.listOfSliders = [] dictOfSlider = dict() for motor in self.__motors: dictOfSlider[motor] = QSlider(Qt.Horizontal) dictOfSlider[motor].setMaximum(4095) dictOfSlider[motor].setValue( self.__motors[motor].getCurrentPosition()) dictOfSlider[motor].sliderMoved.connect( self.__motors[motor].setGoalPosition) self.listOfSliders.append(dictOfSlider[motor]) ## Message to make the user put a name to the sequence self.__noNameMessage = QMessageBox() self.__noNameMessage.setIcon(QMessageBox.Warning) self.__noNameMessage.setWindowIcon(appIcon) self.__noNameMessage.setText( "Please name your sequence before saving it") self.__noNameMessage.setStandardButtons(QMessageBox.Ok) # Renable the create sequence window and closes the message self.__noNameMessage.accepted.connect(self.enableWindow) ## Warning message to make sure the user doen't want to save the sequence self.__warningMessage = QMessageBox() self.__warningMessage.setIcon(QMessageBox.Warning) self.__warningMessage.setWindowIcon(appIcon) self.__warningMessage.setText( "Are you sure you want to close this window? Your sequence will not be saved" ) self.__warningMessage.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) # Close the create sequence window and the message self.__warningMessage.accepted.connect(self.reject) # Renable the create sequence window and closes the message self.__warningMessage.rejected.connect(self.enableWindow) # Set the text for the labels ## Labels for the motors in the UI self.__motorLabels = [] for motorNumber in range(0, len(motors)): self.__motorLabels.append( QLabel("Motor " + str(motorNumber + 1) + " position")) ## Button to add a move to the sequence and procede to the next move self.nextMoveButton = QPushButton("Save Move") ## Buttons to accept or cancel the creation of a sequence self.buttonBox = QDialogButtonBox() self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) # If ok pressed add the sequence to the list self.buttonBox.accepted.connect( lambda: self.addSequenceToList(self.__modifySequence)) # If cancel pressed close the create sequence window self.buttonBox.rejected.connect(self.__warningMessage.exec) # Renable the main window when the create sequence closes self.rejected.connect(self.__listOfSequenceHandler.enableUi) self.accepted.connect(self.__listOfSequenceHandler.enableUi) self.nextMoveButton.clicked.connect(self.addMovetoSequence) self.__listOfMoveLabels.itemDoubleClicked.connect( self.moveDoubleClicked) # Build the vertical layout with the different widgets self.__layout.addWidget(self.__nameLabel) self.__layout.addWidget(self.nameEntry) self.__layout.addWidget(self.__listOfMoveLabels) for motorNumber in range(len(self.__motors)): self.__layout.addWidget(self.__motorLabels[motorNumber]) self.__layout.addWidget(self.listOfSliders[motorNumber]) self.__layout.addWidget(self.nextMoveButton) self.__layout.addWidget(self.buttonBox) # Connect the qwidgetlist to the custom right click menu self.__listOfMoveLabels.setContextMenuPolicy(Qt.CustomContextMenu) self.__listOfMoveLabels.customContextMenuRequested.connect( self.rightClickMenu) def setName(self, name): """ Sets the name of the sequence with the user input :param name: The name of the sequence :return: No return """ self.__sequence.setName(name) def getSequence(self): """ Accessor of the sequence (for tests) :return: the sequence """ return self.__sequence def getListofMoveLabels(self): """ Accessor of the list of move labels (for tests) :return: the list of move labels """ return self.__listOfMoveLabels def addSequenceToList(self, modifySequence=False): """ Add the sequence to the list of sequence :param modifySequence: bool, if true there's a selected sequence that needs to be modified if false it's a new sequence :return: No return """ # TODO: look to move this method to the list of sequence handler # TODO: don't let the user enter a sequence that has the same name as an old one self.setName(self.nameEntry.text()) if self.__sequence.getName() != "": # Load previously saved sequences try: with open('SaveSequence.json') as save: savedListOfSequences = json.load(save) except FileNotFoundError: savedListOfSequences = [] if modifySequence: # Get the item that needs to be modified # selectedSequence = self.__listOfSequenceHandler.getSelectedItems() # Find the selected sequence in the list of saved ones for sequence in savedListOfSequences: if self.__sequence.getName() in sequence: indexOfTheSequence = savedListOfSequences.index( sequence) # remove the unmodified sequence to insert the modified sequence savedListOfSequences.remove(sequence) self.__listOfSequenceHandler.addItem(self.__sequence) # Make the sequence json seriable newSequence = dict() newSequence[self.__sequence.getName()] = [] for moveNumber in range(len( self.__sequence.getMoves())): newSequence[self.__sequence.getName()].append( self.__sequence.getMoves() [moveNumber].getMovePositions()) # Append new sequence to the old ones savedListOfSequences.insert(indexOfTheSequence, newSequence) # Write the sequences to the file with open('SaveSequence.json', 'w') as outfile: json.dump(savedListOfSequences, outfile) self.accept() else: self.__listOfSequenceHandler.addItem(self.__sequence) # Make the sequence json seriable newSequence = dict() newSequence[self.__sequence.getName()] = [] for moveNumber in range(len(self.__sequence.getMoves())): newSequence[self.__sequence.getName()].append( self.__sequence.getMoves() [moveNumber].getMovePositions()) # Append new sequence to the old ones savedListOfSequences.append(newSequence) # Write the sequences to the file with open('SaveSequence.json', 'w') as outfile: json.dump(savedListOfSequences, outfile) self.accept() else: self.setEnabled(False) self.__noNameMessage.exec_() def addMovetoSequence(self): """ Add the last move to the sequence :return: No return """ move = None labelToModify = None # Check if there's a move in modifying state for row in range(self.__listOfMoveLabels.count()): if not self.__listOfMoveLabels.item(row).getMove().isNew: move = self.__listOfMoveLabels.item(row).getMove() labelToModify = self.__listOfMoveLabels.item(row) break # verify if the move is a new one if move is None: # Create the new move and set his positions move = Move(self.__motors) i = 0 for motorName in self.__motors: move.setMotorPosition(motorName, self.listOfSliders[i].value()) i += 1 self.__sequence.addMove(move) # Set text for the move label labelText = "move " + str( self.__sequence.getNumberofMoves()) + ": " i = 0 for motor in self.__motors: labelText += self.__motors[motor].getName() + " " +\ str(self.listOfSliders[i].value()) + ", " i += 1 label = moveLabel(move, labelText, self.__motors) # insert label to the head of the list self.__listOfMoveLabels.insertItem(0, label) else: # modify the move i = 0 for motorName in self.__motors: move.setMotorPosition(motorName, self.listOfSliders[i].value()) i += 1 # modify the label of the move textToEdit = labelToModify.text() listOfTextToEdit = textToEdit.split(' ') labelText = listOfTextToEdit[0] + " " + listOfTextToEdit[1] + " " i = 0 for motor in self.__motors: labelText += self.__motors[motor].getName() + " " + \ str(self.listOfSliders[i].value()) + ", " i += 1 labelToModify.setText(labelText) labelToModify.setSelected(False) labelToModify.setBackground(Qt.white) # reset the state of the move move.isNew = True # Access the move positions when double clicked on def moveDoubleClicked(self, moveItem): """ Called when a move in the sequence is double clicked :param moveItem: the move that was double clicked :return: No return """ moveItem.goToMoveOfTheLabel() self.updateSlidersPositions() def updateSlidersPositions(self): counterMotors = 0 for motor in self.__motors: self.listOfSliders[counterMotors].setValue( self.__motors[motor].getGoalPosition()) counterMotors += 1 def enableWindow(self): """ Enable the create sequence window :return: """ self.setEnabled(True) def rightClickMenu(self, event): """ The right click menu of the move list :param event: The event (here right click) that makes the menu come up :return: No return """ menu = QMenu() # Add a button in the menu that when clicked, it puts a move in modifying state menu.addAction( "Modify Move", lambda: self.modifyMove(self.__listOfMoveLabels. selectedItems()[0])) # Add a button in the menu that when clicked, it deletes a move in the list menu.addAction( "Delete Move", lambda: self.deleteMove(self.__listOfMoveLabels. selectedItems()[0])) menu.exec_(self.__listOfMoveLabels.mapToGlobal(event)) def deleteMove(self, label): """ Delete a move and its label of the sequence :param label: label of the move :return: No return """ # remove the label from the list self.__listOfMoveLabels.takeItem(self.__listOfMoveLabels.row(label)) # remove the move from the sequence self.__sequence.deleteMove(label.getMove()) # rename the labels in the list of moves for index in range(self.__sequence.getNumberofMoves() - 1, -1, -1): labelToModify = self.__listOfMoveLabels.item(index) textToEdit = labelToModify.text() listOfTextToEdit = textToEdit.split(' ') listOfTextToEdit[1] = str(self.__sequence.getNumberofMoves() - index) + ':' textToEdit = ' '.join(listOfTextToEdit) self.__listOfMoveLabels.item(index).setText(textToEdit) def modifyMove(self, label): """ Put a move to a modified state :param label: label of the move :return: No return """ # Check if there's a move in modifying state for row in range(self.__listOfMoveLabels.count()): if not self.__listOfMoveLabels.item(row).getMove().isNew: self.__listOfMoveLabels.item(row).getMove().isNew = True self.__listOfMoveLabels.item(row).setBackground( QBrush(Qt.white)) moveToModify = label.getMove() moveToModify.isNew = False label.setBackground(QBrush(Qt.darkCyan)) label.goToMoveOfTheLabel() self.updateSlidersPositions()
class AboutCutevariant(QDialog): """Display a dialog window with information about the project The window is mainly about the project license, authors, history of changes. """ def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle(self.tr("About Cutevariant")) self.setWindowIcon(QIcon(cm.DIR_ICONS + "app.png")) self.tab_widget = QTabWidget() self.header_lbl = QLabel() self.button_box = QDialogButtonBox() github_button = self.button_box.addButton("GitHub", QDialogButtonBox.HelpRole) twitter_button = self.button_box.addButton("Twitter", QDialogButtonBox.HelpRole) self.button_box.addButton(QDialogButtonBox.Ok) github_button.setIcon(FIcon(0xF02A4)) twitter_button.setIcon(FIcon(0xF0544)) vLayout = QVBoxLayout() vLayout.addWidget(self.header_lbl) vLayout.addWidget(self.tab_widget) vLayout.addWidget(self.button_box) self.setLayout(vLayout) self.addTab("LICENSE") # self.addTab("AUTHORS") # self.addTab("CREDITS") # self.addTab("CHANGELOG") self.drawHeader() # Connexions self.button_box.button(QDialogButtonBox.Ok).clicked.connect(self.close) github_button.clicked.connect(self.open_github_page) twitter_button.clicked.connect(self.open_twitter_page) self.resize(600, 400) def addTab(self, filename): """Read the given text file and load it in a new tab Files must be stored in `cutevariant/assets/`. """ text_edit = QPlainTextEdit() text_edit.setFrameShape(QFrame.NoFrame) text_edit.setReadOnly(True) text = "" if filename == "LICENSE": # Add license header text = self.tr( "Copyright (C) 2018-2020 Labsquare.org\n\n" "This program is distributed under the terms of the GNU " "General Public License v3.\n\n" ) with open(cm.DIR_ASSETS + filename, "r") as f_d: text_edit.setPlainText(text + f_d.read()) self.tab_widget.addTab(text_edit, filename) def drawHeader(self): """Draw logo/copyright in the header""" pHeight = 90 pMargin = 15 icon_path = cm.DIR_ICONS + "app.png" self.header_lbl.setMinimumHeight(pHeight) self.header_lbl.setFrameShape(QFrame.StyledPanel) self.header_lbl.setContentsMargins(0, 0, 0, 0) pixmap = QPixmap(450, pHeight) pixmap.fill(Qt.transparent) iconY = (pHeight - 64) / 2 logoRect = QRect(pMargin, iconY, 64, 64) painter = QPainter(pixmap) painter.setBrush(QBrush(Qt.red)) painter.drawPixmap( logoRect, QPixmap(icon_path).scaled( logoRect.width(), logoRect.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation, ), ) titleRect = QRect(logoRect.right() + 10, iconY, 200, pHeight) font = QFont() font.setBold(True) font.setPixelSize(16) painter.setFont(font) painter.setPen(QPen(QApplication.instance().palette().text().color())) painter.drawText(titleRect, Qt.AlignTop, "Cutevariant") font_metrics = QFontMetrics(font) font.setBold(False) font.setPixelSize(12) painter.setFont(font) painter.setPen(QPen(Qt.darkGray)) titleRect.setY(titleRect.y() + font_metrics.height()) painter.drawText( titleRect, Qt.AlignTop, f"Version %s\nGPL3 Copyright (C) 2018-2020\nLabsquare.org" % __version__, ) self.header_lbl.setPixmap(pixmap) # Painting is finished ! # Avoid Segfault: # QPaintDevice: Cannot destroy paint device that is being painted painter.end() def open_github_page(self): """Open the project page on GitHub""" QDesktopServices.openUrl(QUrl("https://github.com/labsquare/cutevariant")) def open_twitter_page(self): """Open the labsquare page on Twitter""" QDesktopServices.openUrl(QUrl("https://twitter.com/labsquare"))
def initUI(self): main_layout = QVBoxLayout(self) self.setWindowTitle('DOCXImport') self.upd_layout = QVBoxLayout() self.update_label = QLabel() self.update_label.setAlignment(Qt.AlignCenter) self.upd_layout.addWidget(self.update_label) self.get_update_button = QPushButton() self.get_update_button.clicked.connect(self.get_update) self.upd_layout.addWidget(self.get_update_button) main_layout.addLayout(self.upd_layout) if not self.update: self.update_label.hide() self.get_update_button.hide() self.details_grid = QGridLayout() self.epub2_select = QRadioButton() self.epub2_select.setText('EPUB2') self.epubType = QButtonGroup() self.epubType.addButton(self.epub2_select) self.details_grid.addWidget(self.epub2_select, 0, 0, 1, 1) self.checkbox_get_updates = QCheckBox() self.details_grid.addWidget(self.checkbox_get_updates, 0, 1, 1, 1) self.epub3_select = QRadioButton() self.epub3_select.setText('EPUB3') self.epubType.addButton(self.epub3_select) self.details_grid.addWidget(self.epub3_select, 1, 0, 1, 1) main_layout.addLayout(self.details_grid) self.checkbox_get_updates.setChecked(self.prefs['check_for_updates']) if self.prefs['epub_version'] == '2.0': self.epub2_select.setChecked(True) elif self.prefs['epub_version'] == '3.0': self.epub3_select.setChecked(True) else: self.epub2_select.setChecked(True) self.groupBox = QGroupBox() self.groupBox.setTitle('') self.verticalLayout_2 = QVBoxLayout(self.groupBox) self.docx_grid = QGridLayout() self.docx_label = QLabel() self.docx_grid.addWidget(self.docx_label, 0, 0, 1, 1) self.docx_path = QLineEdit() self.docx_grid.addWidget(self.docx_path, 1, 0, 1, 1) self.choose_docx_button = QPushButton() self.choose_docx_button.setText('...') self.docx_grid.addWidget(self.choose_docx_button, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.docx_grid) self.choose_docx_button.clicked.connect( lambda: self.fileChooser('docx', self.docx_path)) if len(self.prefs['lastDocxPath']): self.docx_path.setText(self.prefs['lastDocxPath']) self.docx_path.setEnabled(False) self.smap_grid = QGridLayout() self.checkbox_smap = QCheckBox(self.groupBox) self.smap_grid.addWidget(self.checkbox_smap, 0, 0, 1, 1) self.cust_smap_path = QLineEdit(self.groupBox) self.smap_grid.addWidget(self.cust_smap_path, 1, 0, 1, 1) self.choose_smap_button = QPushButton(self.groupBox) self.choose_smap_button.setText('...') self.smap_grid.addWidget(self.choose_smap_button, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.smap_grid) self.checkbox_smap.setChecked(self.prefs['useSmap']) self.checkbox_smap.stateChanged.connect(lambda: self.chkBoxActions( self.checkbox_smap, self.choose_smap_button)) self.choose_smap_button.clicked.connect( lambda: self.fileChooser('smap', self.cust_smap_path, self. checkbox_smap, self.choose_smap_button)) if len(self.prefs['useSmapPath']): self.cust_smap_path.setText(self.prefs['useSmapPath']) self.cust_smap_path.setEnabled(False) self.chkBoxActions(self.checkbox_smap, self.choose_smap_button) self.css_grid = QGridLayout() self.checkbox_css = QCheckBox(self.groupBox) self.css_grid.addWidget(self.checkbox_css, 0, 0, 1, 1) self.cust_css_path = QLineEdit(self.groupBox) self.css_grid.addWidget(self.cust_css_path, 1, 0, 1, 1) self.choose_css_button = QPushButton(self.groupBox) self.choose_css_button.setText('...') self.css_grid.addWidget(self.choose_css_button, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.css_grid) self.checkbox_css.setChecked(self.prefs['useCss']) self.checkbox_css.stateChanged.connect(lambda: self.chkBoxActions( self.checkbox_css, self.choose_css_button)) self.choose_css_button.clicked.connect( lambda: self.fileChooser('css', self.cust_css_path, self. checkbox_css, self.choose_css_button)) if len(self.prefs['useCssPath']): self.cust_css_path.setText(self.prefs['useCssPath']) self.cust_css_path.setEnabled(False) self.chkBoxActions(self.checkbox_css, self.choose_css_button) main_layout.addWidget(self.groupBox) self.checkbox_debug = QCheckBox() main_layout.addWidget(self.checkbox_debug) self.checkbox_debug.setChecked(self.prefs['debug']) spacerItem = QSpacerItem(20, 15, QSizePolicy.Minimum, QSizePolicy.Expanding) main_layout.addItem(spacerItem) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self._cancel_clicked) main_layout.addWidget(button_box) self.retranslateUi(self) if self.prefs['qt_geometry'] is not None: try: self.restoreGeometry( QByteArray.fromHex( self.prefs['qt_geometry'].encode('ascii'))) except: pass self.show()