def manage_properties(self): self.update() self.setWindowTitle('Properties:') layout = QGridLayout() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.button(QDialogButtonBox.Ok).setDefault(True) for idx, prop in enumerate(sorted(self.flume_object.properties.keys())): label = QLabel(prop + ':') editor = QLineEdit(self.flume_object.properties[prop]["value"]) if prop == "type": editor.setReadOnly(True) if self.flume_object.properties[prop]["required"]: label.setText(prop + ":*") pass # label.setFont(QFont) TODO editor.setToolTip(self.flume_object.properties[prop]["description"]) editor.setToolTipDuration(-1) self.new_properties[prop] = editor label.setBuddy(self.new_properties[prop]) layout.addWidget(label, idx, 0) layout.addWidget(self.new_properties[prop], idx, 1) layout.addWidget(button_box) self.setLayout(layout) button_box.accepted.connect(self.accept_prop) button_box.rejected.connect(self.reject)
def get_properties(self): self.setWindowTitle('Component type') layout = QVBoxLayout() label = QLabel() label.setText('Component type:') # combo_box.setEditable(True) # print(self.flume_object.component) for f in os.listdir('properties/' + self.flume_object.component): self.cb_component_type.addItem(f[:f.find(".")]) # self.cb_component_type.addItems('avro thrift'.split()) button_box1 = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box1.button(QDialogButtonBox.Ok).setDefault(True) layout.addWidget(label) layout.addWidget(self.cb_component_type) layout.addWidget(button_box1) self.setLayout(layout) self.resize(200, 100) button_box1.accepted.connect(self.properties_chosen) button_box1.rejected.connect(self.reject)
class GUI(QDialog): def __init__(self, settings): super(QDialog, self).__init__() self.setWindowTitle("Settings") self.setWindowIcon(QIcon('ui/icon.png')) self.setModal(True) self.setWindowFlags(Qt.WindowStaysOnTopHint) self._button_box = QDialogButtonBox( QDialogButtonBox.Ok ) self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.accept) self._tabs = QTabWidget() self._layout = QBoxLayout(QBoxLayout.TopToBottom) self._layout.addWidget(self._tabs) self._layout.addWidget(self._button_box) self.setLayout(self._layout) # setup tabs self.tab_list = {} self.widgets = {} # general tab general_tab = GeneralTab(settings) self._tabs.addTab(general_tab, general_tab.get_title()) characters_tab = CharactersTab(settings) self._tabs.addTab(characters_tab, characters_tab.get_title()) def set_show_tab(self, tab): if tab == "characters": self._tabs.setCurrentIndex(1)
def dialogExtract2csv(self): d = QDialog(self) d.setFixedWidth(450) d.setWindowTitle("Extract data to Csv") d.setVisible(True) vbox = QVBoxLayout() tabWidget = QTabWidget() for name, mod in list(self.moduleDict.items()): wid = QWidget() grid = QGridLayout() grid.setSpacing(20) wid.dateStart = QLineEdit('%s00:00' % dt.datetime.now().strftime("%Y-%m-%dT")) wid.dateEnd = QLineEdit("Now") grid.addWidget(QLabel("From"), 0, 0) grid.addWidget(wid.dateStart, 0, 1) grid.addWidget(QLabel("To"), 0, 2) grid.addWidget(wid.dateEnd, 0, 3) for i, device in enumerate(mod.devices): checkbox = QCheckBox(device.deviceLabel) checkbox.stateChanged.connect(partial(self.csvUpdateTab, name, checkbox, device)) checkbox.setCheckState(2) grid.addWidget(checkbox, 1 + i, 0, 1, 3) wid.setLayout(grid) tabWidget.addTab(wid, name) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.button(QDialogButtonBox.Ok).clicked.connect(partial(self.extract2csv, tabWidget, d)) buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(d.close) vbox.addWidget(tabWidget) vbox.addWidget(buttonBox) d.setLayout(vbox)
def __init__(self, format, parent=None): super(NumberFormatDlg, self).__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) punctuationRe = QRegExp(r"[ ,;:.]") thousandsLabel = QLabel("&Thousands separator") self.thousandsEdit = QLineEdit(format["thousandsseparator"]) thousandsLabel.setBuddy(self.thousandsEdit) self.thousandsEdit.setMaxLength(1) self.thousandsEdit.setValidator( QRegExpValidator(punctuationRe, self)) decimalMarkerLabel = QLabel("Decimal &marker") self.decimalMarkerEdit = QLineEdit(format["decimalmarker"]) decimalMarkerLabel.setBuddy(self.decimalMarkerEdit) self.decimalMarkerEdit.setMaxLength(1) self.decimalMarkerEdit.setValidator( QRegExpValidator(punctuationRe, self)) self.decimalMarkerEdit.setInputMask("X") decimalPlacesLabel = QLabel("&Decimal places") self.decimalPlacesSpinBox = QSpinBox() decimalPlacesLabel.setBuddy(self.decimalPlacesSpinBox) self.decimalPlacesSpinBox.setRange(0, 6) self.decimalPlacesSpinBox.setValue(format["decimalplaces"]) self.redNegativesCheckBox = QCheckBox("&Red negative numbers") self.redNegativesCheckBox.setChecked(format["rednegatives"]) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply| QDialogButtonBox.Close) self.format = format grid = QGridLayout() grid.addWidget(thousandsLabel, 0, 0) grid.addWidget(self.thousandsEdit, 0, 1) grid.addWidget(decimalMarkerLabel, 1, 0) grid.addWidget(self.decimalMarkerEdit, 1, 1) grid.addWidget(decimalPlacesLabel, 2, 0) grid.addWidget(self.decimalPlacesSpinBox, 2, 1) grid.addWidget(self.redNegativesCheckBox, 3, 0, 1, 2) grid.addWidget(buttonBox, 4, 0, 1, 2) self.setLayout(grid) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply) buttonBox.rejected.connect(self.reject) # self.connect(buttonBox.button(QDialogButtonBox.Apply), # SIGNAL("clicked()"), self.apply) # self.connect(buttonBox, SIGNAL("rejected()"), # self, SLOT("reject()")) self.setWindowTitle("Set Number Format (Modeless)")
def __init__(self, parent=None, group_name=''): super().__init__(parent) if not group_name: window_title = _('Create a new group of students') message = _('Please, enter the name of the new group of students ' 'you want to create:') else: window_title = _('Rename the group of students') message = _('Please, enter the new name of the group of students') self.setWindowTitle(window_title) self.group_name = group_name layout = QVBoxLayout(self) self.setLayout(layout) self._name_widget = QLineEdit(self) if group_name: self._name_widget.setText(group_name) self._name_widget.selectAll() self._name_widget.textChanged.connect(self._group_name_changed) main_line = widgets.LineContainer( self, QLabel(_('Group name')), self._name_widget) buttons = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) self._button_ok = buttons.button(QDialogButtonBox.Ok) layout.addWidget(QLabel(message)) layout.addWidget(main_line) layout.addWidget(buttons) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) self._group_name_changed(group_name)
class DialogStudentId(QDialog): """Dialog to change the student id. Example (replace `parent` by the parent widget): dialog = DialogStudentId(parent) id = dialog.exec_() """ def __init__(self, parent, ranked_students, student_listings): super().__init__(parent) self.student_listings = student_listings self.setWindowTitle(_('Change the student id')) layout = QFormLayout() self.setLayout(layout) self.combo = widgets.StudentComboBox(parent=self) self.combo.add_students(ranked_students) self.combo.editTextChanged.connect(self._check_value) self.combo.currentIndexChanged.connect(self._check_value) new_student_button = QPushButton( \ QIcon(utils.resource_path('new_id.svg')), _('New student'), parent=self) new_student_button.clicked.connect(self._new_student) self.buttons = QDialogButtonBox((QDialogButtonBox.Ok | QDialogButtonBox.Cancel)) self.buttons.addButton(new_student_button, QDialogButtonBox.ActionRole) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) layout.addRow(_('Student id:'), self.combo) layout.addRow(self.buttons) def exec_(self): """Shows the dialog and waits until it is closed. Returns a student object with the option selected by the user. The return value is None if the user cancels the dialog. """ result = super().exec_() if result == QDialog.Accepted: return self.combo.current_student() else: return None def _new_student(self): dialog = NewStudentDialog(self.student_listings, parent=self) student = dialog.exec_() if student is not None: self.combo.add_student(student, set_current=True) self.buttons.button(QDialogButtonBox.Ok).setFocus() self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) def _check_value(self, param): if self.combo.current_student() is not None: self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) else: self.buttons.button(QDialogButtonBox.Ok).setEnabled(False)
def create_settings(self): """Create the widget, organized in two parts. Notes ----- When you add widgets in config, remember to update show_settings too """ bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.idx_ok = bbox.button(QDialogButtonBox.Ok) self.idx_apply = bbox.button(QDialogButtonBox.Apply) self.idx_cancel = bbox.button(QDialogButtonBox.Cancel) bbox.clicked.connect(self.button_clicked) page_list = QListWidget() page_list.setSpacing(1) page_list.currentRowChanged.connect(self.change_widget) pages = ['General', 'Overview', 'Signals', 'Channels', 'Spectrum', 'Notes', 'Video'] for one_page in pages: page_list.addItem(one_page) self.stacked = QStackedWidget() self.stacked.addWidget(self.config) self.stacked.addWidget(self.parent.overview.config) self.stacked.addWidget(self.parent.traces.config) self.stacked.addWidget(self.parent.channels.config) self.stacked.addWidget(self.parent.spectrum.config) self.stacked.addWidget(self.parent.notes.config) self.stacked.addWidget(self.parent.video.config) hsplitter = QSplitter() hsplitter.addWidget(page_list) hsplitter.addWidget(self.stacked) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout)
def warningYesNoOptions(parent, msg, options = ()): dlg = QDialog(parent) dlg.setWindowTitle(_('Question')) layout = QVBoxLayout() dlg.setLayout(layout) label = QLabel(msg) layout.addWidget(label) for opt in options: layout.addWidget(opt['widget']) buttonBox = QDialogButtonBox(QDialogButtonBox.Yes | QDialogButtonBox.No) buttonBox.button(QDialogButtonBox.No).setDefault(True) layout.addWidget(buttonBox) buttonBox.accepted.connect(dlg.accept) buttonBox.rejected.connect(dlg.reject) ret = dlg.exec_() return (ret, {opt['id']:opt['retFunc']() for opt in options if opt['retFunc'] is not None})
def __init__(self): super().__init__() bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.idx_ok = bbox.button(QDialogButtonBox.Ok) self.idx_cancel = bbox.button(QDialogButtonBox.Cancel) bbox.clicked.connect(self.button_clicked) username = settings.value('remote/username', '') password = settings.value('remote/password') if password is None: self.password_md5 = False else: self.password_md5 = password self.username = QLineEdit(username) self.password = QLineEdit(password) self.password.setEchoMode(QLineEdit.Password) self.remember = QCheckBox('Store Values') self.remember.setToolTip('Password is stored as unsalted md5 hash') if password is None: self.remember.setCheckState(Qt.Unchecked) else: self.remember.setCheckState(Qt.Checked) self.subjid = QLineEdit() self.server = QComboBox() self.server.addItem('ieeg.org') # not implemented, also not in settings f = QFormLayout() f.addRow('Repository', self.server) f.addRow('Username', self.username) f.addRow('Password', self.password) f.addRow(self.remember) f.addRow('Subject ID', self.subjid) f.addRow(bbox) self.setLayout(f) self.show()
def dialogTimeout(self): d = QDialog(self) d.setFixedWidth(450) d.setWindowTitle("Setting Devices Timeout") d.setVisible(True) vbox = QVBoxLayout() grid = QGridLayout() grid.setSpacing(20) for i, (key, value) in enumerate(self.parent.device_dict.iteritems()): checkbox = QCheckBox(key) checkbox.stateChanged.connect(partial(self.ackTimeout, checkbox)) checkbox.setCheckState(2) grid.addWidget(checkbox, 1 + i, 0, 1, 3) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.button(QDialogButtonBox.Ok).clicked.connect(d.hide) buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(d.hide) vbox.addLayout(grid) vbox.addWidget(buttonBox) d.setLayout(vbox) return d
class LoginDialog(QDialog): def __init__(self, playerCore): super().__init__() self.player = playerCore self.ui() def ui(self): self.formGridLayout = QGridLayout() self.usernameEdit = QLineEdit() self.passwordEdit = QLineEdit() self.passwordEdit.setEchoMode(QLineEdit.Password) self.labelUsername = QLabel("Username") self.labelPassword = QLabel("Password") self.labelUsername.setBuddy(self.usernameEdit) self.labelPassword.setBuddy(self.passwordEdit) self.buttons = QDialogButtonBox() self.buttons.addButton(QDialogButtonBox.Ok) self.buttons.addButton(QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).setText("Login") self.buttons.button(QDialogButtonBox.Cancel).setText("Abort") self.buttons.button( QDialogButtonBox.Cancel).clicked.connect(self.close) self.buttons.button( QDialogButtonBox.Ok).clicked.connect(self.slotAcceptLogin) self.formGridLayout.addWidget(self.labelUsername, 0, 0) self.formGridLayout.addWidget(self.usernameEdit, 0, 1) self.formGridLayout.addWidget(self.labelPassword, 1, 0) self.formGridLayout.addWidget(self.passwordEdit, 1, 1) self.formGridLayout.addWidget(self.buttons, 2, 0, 1, 2) self.setLayout(self.formGridLayout) self.setWindowTitle('Login') self.show() def slotAcceptLogin(self): username = self.usernameEdit.text() password = self.passwordEdit.text() self.close() logged = self.player.login(username, password) if not logged: self.errorWindow = Window( 'Error', 'Login failed! Try again later.') else: self.successful = Window( 'Success', 'Welcome, {}!'.format(username))
def __init__(self, parent=None): super(NewProjectManager, self).__init__(parent, Qt.Dialog) self.setWindowTitle(translations.TR_NEW_PROJECT) self.setMinimumHeight(500) vbox = QVBoxLayout(self) vbox.addWidget(QLabel(translations.TR_CHOOSE_TEMPLATE)) vbox.addWidget(QLabel(translations.TR_TAB_PROJECTS)) hbox = QHBoxLayout() self.list_projects = QListWidget() self.list_projects.setProperty("wizard", True) hbox.addWidget(self.list_projects) self.list_templates = QListWidget() self.list_templates.setProperty("wizard", True) hbox.addWidget(self.list_templates) self.text_info = QTextBrowser() self.text_info.setProperty("wizard", True) hbox.addWidget(self.text_info) vbox.addLayout(hbox) button_box = QDialogButtonBox( QDialogButtonBox.Cancel | QDialogButtonBox.Ok) choose_button = button_box.button(QDialogButtonBox.Ok) choose_button.setText(translations.TR_CHOOSE) # hbox2 = QHBoxLayout() # cancel = QPushButton(translations.TR_CANCEL) # choose = QPushButton(translations.TR_CHOOSE) # hbox2.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding, # QSizePolicy.Fixed)) # hbox2.addWidget(cancel) # hbox2.addWidget(choose) # vbox.addLayout(button_box) vbox.addWidget(button_box) self.template_registry = IDE.get_service("template_registry") categories = self.template_registry.list_project_categories() for category in categories: self.list_projects.addItem(category) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) # cancel.clicked.connect(self.close) # choose.clicked.connect(self._start_wizard) self.list_projects.itemSelectionChanged.connect( self._project_selected) self.list_templates.itemSelectionChanged.connect( self._template_selected) self.list_projects.setCurrentRow(0)
class CueSettings(QDialog): on_apply = QtCore.pyqtSignal(dict) def __init__(self, widgets=[], cue=None, check=False, **kwargs): super().__init__(**kwargs) conf = {} if(cue is not None): conf = deepcopy(cue.properties()) self.setWindowTitle(conf['name']) self.setWindowModality(QtCore.Qt.ApplicationModal) self.setMaximumSize(635, 530) self.setMinimumSize(635, 530) self.resize(635, 530) self.sections = QTabWidget(self) self.sections.setGeometry(QtCore.QRect(5, 10, 625, 470)) wsize = QtCore.QSize(625, 470 - self.sections.tabBar().height()) for widget in widgets: widget = widget(wsize, cue) widget.set_configuration(conf) widget.enable_check(check) self.sections.addTab(widget, widget.Name) self.dialogButtons = QDialogButtonBox(self) self.dialogButtons.setGeometry(10, 490, 615, 30) self.dialogButtons.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Apply) self.dialogButtons.rejected.connect(self.reject) self.dialogButtons.accepted.connect(self.accept) apply = self.dialogButtons.button(QDialogButtonBox.Apply) apply.clicked.connect(self.apply) def accept(self): self.apply() super().accept() def apply(self): new_conf = {} for n in range(self.sections.count()): deep_update(new_conf, self.sections.widget(n).get_configuration()) self.on_apply.emit(new_conf)
def __init__(self, parent=None): super(VersaProbeDialog, self).__init__(parent) self._color = QColor(0, 0, 0, 150) self._state = False self.setWindowModality(Qt.ApplicationModal) self.setWindowFlags(self.windowFlags() | Qt.Tool | Qt.Dialog | Qt.WindowStaysOnTopHint | Qt.WindowSystemMenuHint) self.setMinimumSize(200, 200) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) b = buttonBox.button(QDialogButtonBox.Ok) b.clicked.connect(lambda: self.close()) l = QVBoxLayout() self._o = VersaProbe() self.setLayout(l) l.addWidget(self._o) l.addWidget(buttonBox)
def __init__(self, parent, student_list, column_map): super().__init__(parent) self.setWindowTitle(_('Preview the students to be loaded')) layout = QVBoxLayout(self) self.setLayout(layout) self.table = PreviewWidget(student_list, column_map, parent=self) self.button_swap = QPushButton(_('Swap first/last names'), parent=self) self.button_take_first = QPushButton( _('Take first name as full name'), parent=self) self.button_take_last = QPushButton( _('Take last name as full name'), parent=self) self.button_remove = QPushButton( _('Remove duplicate students'), parent=self) buttons = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) self.button_accept = buttons.button(QDialogButtonBox.Ok) layout.addWidget(self.table) layout.addWidget(self.button_swap) layout.addWidget(self.button_take_first) layout.addWidget(self.button_take_last) layout.addWidget(self.button_remove) layout.addWidget(buttons) layout.setAlignment(self.button_swap, Qt.AlignHCenter) layout.setAlignment(self.button_take_first, Qt.AlignHCenter) layout.setAlignment(self.button_take_last, Qt.AlignHCenter) layout.setAlignment(self.button_remove, Qt.AlignHCenter) self.button_swap.clicked.connect(self.table.swap_names) self.button_take_first.clicked.connect(self._take_first_name) self.button_take_last.clicked.connect(self._take_last_name) self.button_remove.clicked.connect(self._remove_duplicates) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) if students.StudentColumn.FIRST_NAME not in column_map: self._disable_buttons() if any(s.is_duplicate for s in student_list): self.button_accept.setEnabled(False) self.button_remove.setEnabled(True) else: self.button_remove.setEnabled(False)
class PasswordInputView(QWidget, Ui_PasswordInputWidget): """ The model of Navigation component """ def __init__(self, parent): # construct from qtDesigner super().__init__(parent) self.setupUi(self) self.button_box = QDialogButtonBox(self) self.button_box.setOrientation(Qt.Horizontal) self.button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.layout().addWidget(self.button_box) self.button_box.hide() def error(self, text): self.label_info.setText(text) self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) def clear(self): self.edit_password.clear() self.edit_secret_key.clear() def valid(self): self.label_info.setText(self.tr("Password is valid")) self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) def changeEvent(self, event): """ Intercepte LanguageChange event to translate UI :param QEvent QEvent: Event :return: """ if event.type() == QEvent.LanguageChange: self.retranslateUi(self) return super(PasswordInputView, self).changeEvent(event)
class InfoDialog(QDialog): """文件信息对话框""" get_dl_link = pyqtSignal(str, str) def __init__(self, parent=None): super().__init__(parent) self.infos = None self.initUI() self.setStyleSheet(dialog_qss_style) def update_ui(self): self.tx_dl_link.setPlaceholderText("单击获取") self.tx_name.setText(self.infos[1]) if self.infos[2]: self.setWindowTitle("文件信息") self.lb_name.setText("文件名:") self.lb_desc.setText("文件描述:") self.tx_dl_link.setText("") # 清空旧的信息 self.lb_dl_link.setVisible(True) self.tx_dl_link.setVisible(True) else: self.setWindowTitle("文件夹信息") self.lb_name.setText("文件夹名:") self.lb_desc.setText("文件夹描述:") self.lb_dl_link.setVisible(False) self.tx_dl_link.setVisible(False) if self.infos[2]: self.tx_size.setText(self.infos[2]) self.lb_size.setVisible(True) self.tx_size.setVisible(True) else: self.tx_size.setVisible(False) self.lb_size.setVisible(False) if self.infos[3]: self.lb_time.setVisible(True) self.tx_time.setVisible(True) self.tx_time.setText(self.infos[3]) else: self.lb_time.setVisible(False) self.tx_time.setVisible(False) if self.infos[4]: self.lb_dl_count.setVisible(True) self.tx_dl_count.setVisible(True) self.tx_dl_count.setText(str(self.infos[4])) else: self.tx_dl_count.setVisible(False) self.lb_dl_count.setVisible(False) if self.infos[5]: self.tx_pwd.setText(self.infos[5]) self.tx_pwd.setPlaceholderText("") else: self.tx_pwd.setText("") self.tx_pwd.setPlaceholderText("无") if self.infos[6]: self.tx_desc.setText(self.infos[6]) self.tx_desc.setPlaceholderText("") else: self.tx_desc.setText("") self.tx_desc.setPlaceholderText("无") self.tx_share_url.setText(self.infos[7]) def set_values(self, infos): self.infos = infos self.update_ui() self.exec() def call_get_dl_link(self): url = self.tx_share_url.text() pwd = self.tx_pwd.text() self.get_dl_link.emit(url, pwd) self.tx_dl_link.setPlaceholderText("后台获取中,请稍后!") def initUI(self): self.setWindowIcon(QIcon("./src/share.ico")) self.setWindowTitle("文件信息") self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.buttonBox.button(QDialogButtonBox.Close).setText("关闭") self.buttonBox.rejected.connect(self.reject) self.logo = QLabel() self.logo.setPixmap(QPixmap("./src/q9.gif")) self.logo.setAlignment(Qt.AlignCenter) self.logo.setStyleSheet("background-color:rgb(255,204,51);") self.lb_name = QLabel() self.lb_name.setText("文件名:") self.tx_name = QLineEdit() self.tx_name.setReadOnly(True) self.lb_size = QLabel() self.lb_size.setText("文件大小:") self.tx_size = QLabel() self.lb_time = QLabel() self.lb_time.setText("上传时间:") self.tx_time = QLabel() self.lb_dl_count = QLabel() self.lb_dl_count.setText("下载次数:") self.tx_dl_count = QLabel() self.lb_share_url = QLabel() self.lb_share_url.setText("分享链接:") self.tx_share_url = QLineEdit() self.tx_share_url.setReadOnly(True) self.lb_pwd = QLabel() self.lb_pwd.setText("提取码:") self.tx_pwd = QLineEdit() self.tx_pwd.setReadOnly(True) self.lb_desc = QLabel() self.lb_desc.setText("文件描述:") self.tx_desc = AutoResizingTextEdit() self.tx_desc.setReadOnly(True) self.lb_dl_link = QLabel() self.lb_dl_link.setText("下载直链:") self.tx_dl_link = AutoResizingTextEdit(self) self.tx_dl_link.setPlaceholderText("单击获取") self.tx_dl_link.clicked.connect(self.call_get_dl_link) self.tx_dl_link.setReadOnly(True) vbox = QVBoxLayout() vbox.addWidget(self.logo) vbox.addStretch(1) form = QFormLayout() form.setLabelAlignment(Qt.AlignRight) form.addRow(self.lb_name, self.tx_name) form.addRow(self.lb_size, self.tx_size) form.addRow(self.lb_time, self.tx_time) form.addRow(self.lb_dl_count, self.tx_dl_count) form.addRow(self.lb_share_url, self.tx_share_url) form.addRow(self.lb_pwd, self.tx_pwd) form.addRow(self.lb_desc, self.tx_desc) form.addRow(self.lb_dl_link, self.tx_dl_link) vbox.addLayout(form) vbox.addStretch(1) vbox.addWidget(self.buttonBox) self.setLayout(vbox)
def __init__(self, parent, worker, config, configfile): QDialog.__init__(self, parent) self.worker = worker self.config = config self.configfile = configfile self.setStyleSheet("QGroupBox { font-weight: bold; } ") self.setWindowTitle('Settings') layout = QGridLayout() # Categories self.category_list = QListWidget() category_media = QListWidgetItem(getIcon('media-playback-start'), 'Media', self.category_list) category_sync = QListWidgetItem(getIcon('view-refresh'), 'Sync', self.category_list) category_ui = QListWidgetItem(getIcon('window-new'), 'User Interface', self.category_list) category_theme = QListWidgetItem(getIcon('applications-graphics'), 'Theme', self.category_list) self.category_list.setSelectionMode(QAbstractItemView.SingleSelection) self.category_list.setCurrentRow(0) self.category_list.setMaximumWidth(self.category_list.sizeHintForColumn(0) + 15) self.category_list.setFocus() self.category_list.currentItemChanged.connect(self.s_switch_page) # Media tab page_media = QWidget() page_media_layout = QVBoxLayout() page_media_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Media settings g_media = QGroupBox('Media settings') g_media.setFlat(True) g_media_layout = QFormLayout() self.tracker_enabled = QCheckBox() self.tracker_enabled.toggled.connect(self.tracker_type_change) self.tracker_type = QComboBox() for (n, label) in utils.available_trackers: self.tracker_type.addItem(label, n) self.tracker_type.currentIndexChanged.connect(self.tracker_type_change) self.tracker_interval = QSpinBox() self.tracker_interval.setRange(5, 1000) self.tracker_interval.setMaximumWidth(60) self.tracker_process = QLineEdit() self.tracker_update_wait = QSpinBox() self.tracker_update_wait.setRange(0, 1000) self.tracker_update_wait.setMaximumWidth(60) self.tracker_update_close = QCheckBox() self.tracker_update_prompt = QCheckBox() self.tracker_not_found_prompt = QCheckBox() g_media_layout.addRow('Enable tracker', self.tracker_enabled) g_media_layout.addRow('Tracker type', self.tracker_type) g_media_layout.addRow('Tracker interval (seconds)', self.tracker_interval) g_media_layout.addRow('Process name (regex)', self.tracker_process) g_media_layout.addRow('Wait before updating (seconds)', self.tracker_update_wait) g_media_layout.addRow('Wait until the player is closed', self.tracker_update_close) g_media_layout.addRow('Ask before updating', self.tracker_update_prompt) g_media_layout.addRow('Ask to add new shows', self.tracker_not_found_prompt) g_media.setLayout(g_media_layout) # Group: Plex settings g_plex = QGroupBox('Plex Media Server') g_plex.setFlat(True) self.plex_host = QLineEdit() self.plex_port = QLineEdit() self.plex_user = QLineEdit() self.plex_passw = QLineEdit() self.plex_passw.setEchoMode(QLineEdit.Password) self.plex_obey_wait = QCheckBox() g_plex_layout = QGridLayout() g_plex_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1) g_plex_layout.addWidget(self.plex_host, 0, 1, 1, 1) g_plex_layout.addWidget(self.plex_port, 0, 2, 1, 2) g_plex_layout.addWidget(QLabel('Use "wait before updating" time'), 1, 0, 1, 1) g_plex_layout.addWidget(self.plex_obey_wait, 1, 2, 1, 1) g_plex_layout.addWidget(QLabel('myPlex login (claimed server)'), 2, 0, 1, 1) g_plex_layout.addWidget(self.plex_user, 2, 1, 1, 1) g_plex_layout.addWidget(self.plex_passw, 2, 2, 1, 2) g_plex.setLayout(g_plex_layout) # Group: Library g_playnext = QGroupBox('Library') g_playnext.setFlat(True) self.player = QLineEdit() self.player_browse = QPushButton('Browse...') self.player_browse.clicked.connect(self.s_player_browse) lbl_searchdirs = QLabel('Media directories') lbl_searchdirs.setAlignment(QtCore.Qt.AlignTop) self.searchdirs = QListWidget() self.searchdirs_add = QPushButton('Add...') self.searchdirs_add.clicked.connect(self.s_searchdirs_add) self.searchdirs_remove = QPushButton('Remove') self.searchdirs_remove.clicked.connect(self.s_searchdirs_remove) self.searchdirs_buttons = QVBoxLayout() self.searchdirs_buttons.setAlignment(QtCore.Qt.AlignTop) self.searchdirs_buttons.addWidget(self.searchdirs_add) self.searchdirs_buttons.addWidget(self.searchdirs_remove) self.searchdirs_buttons.addWidget(QSplitter()) self.library_autoscan = QCheckBox() self.scan_whole_list = QCheckBox() self.library_full_path = QCheckBox() g_playnext_layout = QGridLayout() g_playnext_layout.addWidget(QLabel('Player'), 0, 0, 1, 1) g_playnext_layout.addWidget(self.player, 0, 1, 1, 1) g_playnext_layout.addWidget(self.player_browse, 0, 2, 1, 1) g_playnext_layout.addWidget(lbl_searchdirs, 1, 0, 1, 1) g_playnext_layout.addWidget(self.searchdirs, 1, 1, 1, 1) g_playnext_layout.addLayout(self.searchdirs_buttons, 1, 2, 1, 1) g_playnext_layout.addWidget(QLabel('Rescan Library at startup'), 2, 0, 1, 2) g_playnext_layout.addWidget(self.library_autoscan, 2, 2, 1, 1) g_playnext_layout.addWidget(QLabel('Scan through whole list'), 3, 0, 1, 2) g_playnext_layout.addWidget(self.scan_whole_list, 3, 2, 1, 1) g_playnext_layout.addWidget(QLabel('Take subdirectory name into account'), 4, 0, 1, 2) g_playnext_layout.addWidget(self.library_full_path, 4, 2, 1, 1) g_playnext.setLayout(g_playnext_layout) # Media form page_media_layout.addWidget(g_media) page_media_layout.addWidget(g_plex) page_media_layout.addWidget(g_playnext) page_media.setLayout(page_media_layout) # Sync tab page_sync = QWidget() page_sync_layout = QVBoxLayout() page_sync_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Autoretrieve g_autoretrieve = QGroupBox('Autoretrieve') g_autoretrieve.setFlat(True) self.autoretrieve_off = QRadioButton('Disabled') self.autoretrieve_always = QRadioButton('Always at start') self.autoretrieve_days = QRadioButton('After n days') self.autoretrieve_days.toggled.connect(self.s_autoretrieve_days) self.autoretrieve_days_n = QSpinBox() self.autoretrieve_days_n.setRange(1, 100) g_autoretrieve_layout = QGridLayout() g_autoretrieve_layout.setColumnStretch(0, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_off, 0, 0, 1, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_always, 1, 0, 1, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_days, 2, 0, 1, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_days_n, 2, 1, 1, 1) g_autoretrieve.setLayout(g_autoretrieve_layout) # Group: Autosend g_autosend = QGroupBox('Autosend') g_autosend.setFlat(True) self.autosend_off = QRadioButton('Disabled') self.autosend_always = QRadioButton('Immediately after every change') self.autosend_minutes = QRadioButton('After n minutes') self.autosend_minutes.toggled.connect(self.s_autosend_minutes) self.autosend_minutes_n = QSpinBox() self.autosend_minutes_n.setRange(1, 1000) self.autosend_size = QRadioButton('After the queue reaches n items') self.autosend_size.toggled.connect(self.s_autosend_size) self.autosend_size_n = QSpinBox() self.autosend_size_n.setRange(2, 20) self.autosend_at_exit = QCheckBox('At exit') g_autosend_layout = QGridLayout() g_autosend_layout.setColumnStretch(0, 1) g_autosend_layout.addWidget(self.autosend_off, 0, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_always, 1, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_minutes, 2, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_minutes_n, 2, 1, 1, 1) g_autosend_layout.addWidget(self.autosend_size, 3, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_size_n, 3, 1, 1, 1) g_autosend_layout.addWidget(self.autosend_at_exit, 4, 0, 1, 1) g_autosend.setLayout(g_autosend_layout) # Group: Extra g_extra = QGroupBox('Additional options') g_extra.setFlat(True) self.auto_status_change = QCheckBox('Change status automatically') self.auto_status_change.toggled.connect(self.s_auto_status_change) self.auto_status_change_if_scored = QCheckBox('Change status automatically only if scored') self.auto_date_change = QCheckBox('Change start and finish dates automatically') g_extra_layout = QVBoxLayout() g_extra_layout.addWidget(self.auto_status_change) g_extra_layout.addWidget(self.auto_status_change_if_scored) g_extra_layout.addWidget(self.auto_date_change) g_extra.setLayout(g_extra_layout) # Sync layout page_sync_layout.addWidget(g_autoretrieve) page_sync_layout.addWidget(g_autosend) page_sync_layout.addWidget(g_extra) page_sync.setLayout(page_sync_layout) # UI tab page_ui = QWidget() page_ui_layout = QFormLayout() page_ui_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Icon g_icon = QGroupBox('Notification Icon') g_icon.setFlat(True) self.tray_icon = QCheckBox('Show tray icon') self.tray_icon.toggled.connect(self.s_tray_icon) self.close_to_tray = QCheckBox('Close to tray') self.start_in_tray = QCheckBox('Start minimized to tray') self.tray_api_icon = QCheckBox('Use API icon as tray icon') self.notifications = QCheckBox('Show notification when tracker detects new media') g_icon_layout = QVBoxLayout() g_icon_layout.addWidget(self.tray_icon) g_icon_layout.addWidget(self.close_to_tray) g_icon_layout.addWidget(self.start_in_tray) g_icon_layout.addWidget(self.tray_api_icon) g_icon_layout.addWidget(self.notifications) g_icon.setLayout(g_icon_layout) # Group: Window g_window = QGroupBox('Window') g_window.setFlat(True) self.remember_geometry = QCheckBox('Remember window size and position') self.remember_columns = QCheckBox('Remember column layouts and widths') self.columns_per_api = QCheckBox('Use different visible columns per API') g_window_layout = QVBoxLayout() g_window_layout.addWidget(self.remember_geometry) g_window_layout.addWidget(self.remember_columns) g_window_layout.addWidget(self.columns_per_api) g_window.setLayout(g_window_layout) # Group: Lists g_lists = QGroupBox('Lists') g_lists.setFlat(True) self.filter_bar_position = QComboBox() filter_bar_positions = [(FilterBar.PositionHidden, 'Hidden'), (FilterBar.PositionAboveLists, 'Above lists'), (FilterBar.PositionBelowLists, 'Below lists')] for (n, label) in filter_bar_positions: self.filter_bar_position.addItem(label, n) self.inline_edit = QCheckBox('Enable in-line editing') g_lists_layout = QFormLayout() g_lists_layout.addRow('Filter bar position:', self.filter_bar_position) g_lists_layout.addRow(self.inline_edit) g_lists.setLayout(g_lists_layout) # UI layout page_ui_layout.addWidget(g_icon) page_ui_layout.addWidget(g_window) page_ui_layout.addWidget(g_lists) page_ui.setLayout(page_ui_layout) # Theming tab page_theme = QWidget() page_theme_layout = QFormLayout() page_theme_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Episode Bar g_ep_bar = QGroupBox('Episode Bar') g_ep_bar.setFlat(True) self.ep_bar_style = QComboBox() ep_bar_styles = [(ShowsTableDelegate.BarStyleBasic, 'Basic'), (ShowsTableDelegate.BarStyle04, 'Trackma'), (ShowsTableDelegate.BarStyleHybrid, 'Hybrid')] for (n, label) in ep_bar_styles: self.ep_bar_style.addItem(label, n) self.ep_bar_style.currentIndexChanged.connect(self.s_ep_bar_style) self.ep_bar_text = QCheckBox('Show text label') g_ep_bar_layout = QFormLayout() g_ep_bar_layout.addRow('Style:', self.ep_bar_style) g_ep_bar_layout.addRow(self.ep_bar_text) g_ep_bar.setLayout(g_ep_bar_layout) # Group: Colour scheme g_scheme = QGroupBox('Color Scheme') g_scheme.setFlat(True) col_tabs = [('rows', '&Row highlights'), ('progress', '&Progress widget')] self.colors = {} self.colors['rows'] = [('is_playing', 'Playing'), ('is_queued', 'Queued'), ('new_episode', 'New Episode'), ('is_airing', 'Airing'), ('not_aired', 'Unaired')] self.colors['progress'] = [('progress_bg', 'Background'), ('progress_fg', 'Watched bar'), ('progress_sub_bg', 'Aired episodes'), ('progress_sub_fg', 'Stored episodes'), ('progress_complete', 'Complete')] self.color_buttons = [] self.syscolor_buttons = [] g_scheme_layout = QGridLayout() tw_scheme = QTabWidget() for (key, tab_title) in col_tabs: page = QFrame() page_layout = QGridLayout() col = 0 # Generate widgets from the keys and values for (key, label) in self.colors[key]: self.color_buttons.append(QPushButton()) # self.color_buttons[-1].setStyleSheet('background-color: ' + getColor(self.config['colors'][key]).name()) self.color_buttons[-1].setFocusPolicy(QtCore.Qt.NoFocus) self.color_buttons[-1].clicked.connect(self.s_color_picker(key, False)) self.syscolor_buttons.append(QPushButton('System Colors')) self.syscolor_buttons[-1].clicked.connect(self.s_color_picker(key, True)) page_layout.addWidget(QLabel(label), col, 0, 1, 1) page_layout.addWidget(self.color_buttons[-1], col, 1, 1, 1) page_layout.addWidget(self.syscolor_buttons[-1], col, 2, 1, 1) col += 1 page.setLayout(page_layout) tw_scheme.addTab(page, tab_title) g_scheme_layout.addWidget(tw_scheme) g_scheme.setLayout(g_scheme_layout) # UI layout page_theme_layout.addWidget(g_ep_bar) page_theme_layout.addWidget(g_scheme) page_theme.setLayout(page_theme_layout) # Content self.contents = QStackedWidget() self.contents.addWidget(page_media) self.contents.addWidget(page_sync) self.contents.addWidget(page_ui) self.contents.addWidget(page_theme) if pyqt_version is not 5: self.contents.layout().setMargin(0) # Bottom buttons bottombox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel ) bottombox.accepted.connect(self.s_save) bottombox.button(QDialogButtonBox.Apply).clicked.connect(self._save) bottombox.rejected.connect(self.reject) # Main layout finish layout.addWidget(self.category_list, 0, 0, 1, 1) layout.addWidget(self.contents, 0, 1, 1, 1) layout.addWidget(bottombox, 1, 0, 1, 2) layout.setColumnStretch(1, 1) self._load() self.update_colors() self.setLayout(layout)
def __init__(self, shape, parent=None): super(Settings, self).__init__(parent) self.setAttribute(Qt.WA_DeleteOnClose) # Make reference copy of variable self.shape = shape self.setWindowTitle("PyBigPixel Creator {0}-- {1}" .format(__version__, self.tr('Settings'))) lang_label = QLabel(self.tr("Languish")) self.lang_list = QComboBox() langs = [prepare.LANGUISH[key]['Lang'] for key in prepare.LANGUISH.keys()] self.lang = shape['lang'] self.lang_list.addItems(langs) self.lang_list.setCurrentIndex(self.lang_list.findText(self.lang)) shape_label = QLabel(self.tr("Shape of pixel")) self.shape_list = QComboBox() self.shape_list.addItems(self.shape['available_shapes']) self.shape_list.setCurrentIndex(self.shape_list. findText(self.shape['shape'])) plate_label = QLabel(self.tr("Number of pixels (width x height)")) plate_label_x = QLabel(" X ") self.pixel_button_width = QSpinBox() self.pixel_button_width.setRange(1, 250) self.pixel_button_width.setValue(self.shape['pixels'][0]) self.pixel_button_height = QSpinBox() self.pixel_button_height.setRange(1, 250) self.pixel_button_height.setValue(self.shape['pixels'][1]) self.background_label = QLabel(self.tr("Background color")) self.background_list = QComboBox() self.background_list.addItems(self.shape['availible_backgrounds']) self.background_list.setCurrentIndex(self.background_list. findText(self.shape['background'])) button_layout = QVBoxLayout() buttonbox = QDialogButtonBox(QDialogButtonBox.Apply | QDialogButtonBox.Cancel) button_layout.addStretch() button_layout.addWidget(buttonbox) layout = QGridLayout() layout.addWidget(lang_label, 0, 0) layout.addWidget(self.lang_list, 0, 2, 1, 2) layout.addWidget(shape_label, 1, 0) layout.addWidget(self.shape_list, 1, 2, 1, 2) layout.addWidget(self.background_label, 2, 0) layout.addWidget(self.background_list, 2, 2, 1, 2) layout.addWidget(plate_label, 3, 0) layout.addWidget(self.pixel_button_width, 3, 1, 1, 1) layout.addWidget(plate_label_x, 3, 2) layout.addWidget(self.pixel_button_height, 3, 3, 1, 1) layout.addLayout(button_layout, 4, 0, 2, 4) self.setLayout(layout) buttonbox.rejected.connect(self.close) buttonbox.button(QDialogButtonBox.Apply).clicked.connect(self.apply)
class ExportDatasetDialog(QDialog): """Dialog for choosing export dataset options.""" def __init__(self, parent): super().__init__(None, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.parent = parent self.setWindowModality(Qt.ApplicationModal) self.create_dialog() def create_dialog(self): """Create the dialog.""" self.bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.idx_ok = self.bbox.button(QDialogButtonBox.Ok) self.idx_cancel = self.bbox.button(QDialogButtonBox.Cancel) filebutton = QPushButton() filebutton.setText('Choose') self.idx_filename = filebutton self.new_format = FormMenu(['EDF', 'Wonambi']) self.all_time = FormBool('Entire length of record') self.all_chan = FormBool('All channels') self.times = {} self.times['beg'] = FormFloat() self.times['end'] = FormFloat() chan_box = QListWidget() chan_box.setSelectionMode(QAbstractItemView.ExtendedSelection) self.idx_chan = chan_box filebutton.clicked.connect(self.save_as) self.all_time.connect(self.toggle_buttons) self.all_chan.connect(self.toggle_buttons) self.bbox.clicked.connect(self.button_clicked) self.all_time.set_value(True) self.all_chan.set_value(True) form = QFormLayout() form.addRow('Filename', filebutton) #form.addRow('Format', self.new_format) form.addRow(self.all_time) form.addRow('Start time (sec)', self.times['beg']) form.addRow('End time (sec)', self.times['end']) form.addRow(self.all_chan) form.addRow('Channel(s)', self.idx_chan) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(self.bbox) vlayout = QVBoxLayout() vlayout.addLayout(form) vlayout.addStretch(1) vlayout.addLayout(btnlayout) self.setLayout(vlayout) def button_clicked(self, button): """Action when button was clicked. Parameters ---------- button : instance of QPushButton which button was pressed """ if button is self.idx_ok: #new_format = self.new_format.get_value().lower() new_format = 'edf' chan = None beg = None end = None if not self.all_time.get_value(): beg = self.times['beg'].get_value() end = self.times['end'].get_value() if not self.all_chan.get_value(): chan = self.get_channels() self.parent.info.export(new_format, filename=self.filename, chan=chan, begtime=beg, endtime=end) self.accept() if button is self.idx_cancel: self.reject() def toggle_buttons(self): """Turn buttons on and off.""" all_time_on = self.all_time.get_value() all_chan_on = self.all_chan.get_value() self.times['beg'].setEnabled(not all_time_on) self.times['end'].setEnabled(not all_time_on) self.idx_chan.setEnabled(not all_chan_on) def save_as(self): """Dialog for getting name, location of dataset export.""" filename = splitext(self.filename)[0] + '.edf' filename, _ = QFileDialog.getSaveFileName(self, 'Export dataset', filename, 'European Data Format ' '(*.edf)') if filename == '': return self.filename = filename short_filename = short_strings(basename(self.filename)) self.idx_filename.setText(short_filename) def get_channels(self): """Get the selected channel(s in order). """ selectedItems = self.idx_chan.selectedItems() selected_chan = [x.text() for x in selectedItems] chan_in_order = [] for chan in self.chan: if chan in selected_chan: chan_in_order.append(chan) return chan_in_order def update(self): """Get info from dataset before opening dialog.""" self.filename = self.parent.info.dataset.filename self.chan = self.parent.info.dataset.header['chan_name'] for chan in self.chan: self.idx_chan.addItem(chan)
class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self._info = None self._text = '' self._convertedtext = '' self._encoding = None self.mainwindow = parent self.fromVersionLabel = QLabel() self.fromVersion = QLineEdit() self.reason = QLabel() self.toVersionLabel = QLabel() self.toVersion = QLineEdit() self.lilyChooser = lilychooser.LilyChooser(toolcommand='convert-ly') self.messages = QTextBrowser() self.diff = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap) self.uni_diff = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap) self.copyCheck = QCheckBox(checked= QSettings().value('convert_ly/copy_messages', True, bool)) self.tabw = QTabWidget() self.tabw.addTab(self.messages, '') self.tabw.addTab(self.diff, '') self.tabw.addTab(self.uni_diff, '') self.buttons = QDialogButtonBox( QDialogButtonBox.Reset | QDialogButtonBox.Save | QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).clicked .connect(self.accept) self.buttons.rejected.connect(self.reject) self.buttons.button(QDialogButtonBox.Reset).clicked.connect(self.run) self.buttons.button(QDialogButtonBox.Save).clicked.connect(self.saveFile) layout = QVBoxLayout() self.setLayout(layout) grid = QGridLayout() grid.addWidget(self.fromVersionLabel, 0, 0) grid.addWidget(self.fromVersion, 0, 1) grid.addWidget(self.reason, 0, 2, 1, 3) grid.addWidget(self.toVersionLabel, 1, 0) grid.addWidget(self.toVersion, 1, 1) grid.addWidget(self.lilyChooser, 1, 3, 1, 2) layout.addLayout(grid) layout.addWidget(self.tabw) layout.addWidget(self.copyCheck) layout.addWidget(widgets.Separator()) layout.addWidget(self.buttons) app.translateUI(self) qutil.saveDialogSize(self, 'convert_ly/dialog/size', QSize(600, 300)) app.settingsChanged.connect(self.readSettings) self.readSettings() self.finished.connect(self.saveCopyCheckSetting) self.lilyChooser.currentIndexChanged.connect(self.slotLilyPondVersionChanged) self.slotLilyPondVersionChanged() def translateUI(self): self.fromVersionLabel.setText(_("From version:")) self.toVersionLabel.setText(_("To version:")) self.copyCheck.setText(_("Save convert-ly messages in document")) self.copyCheck.setToolTip(_( "If checked, the messages of convert-ly are appended as a " "comment to the end of the document.")) self.tabw.setTabText(0, _("&Messages")) self.tabw.setTabText(1, _("&Changes")) self.tabw.setTabText(2, _("&Diff")) self.buttons.button(QDialogButtonBox.Reset).setText(_("Run Again")) self.buttons.button(QDialogButtonBox.Save).setText(_("Save as file")) self.setCaption() def saveCopyCheckSetting(self): QSettings().setValue('convert_ly/copy_messages', self.copyCheck.isChecked()) def readSettings(self): font = textformats.formatData('editor').font self.diff.setFont(font) diffFont = QFont("Monospace") diffFont.setStyleHint(QFont.TypeWriter) self.uni_diff.setFont(diffFont) def slotLilyPondVersionChanged(self): self.setLilyPondInfo(self.lilyChooser.lilyPondInfo()) def setCaption(self): version = self._info and self._info.versionString() or _("<unknown>") title = _("Convert-ly from LilyPond {version}").format(version=version) self.setWindowTitle(app.caption(title)) def setLilyPondInfo(self, info): if not info: return self._info = info self.setCaption() self.toVersion.setText(info.versionString()) self.setConvertedText() self.setDiffText() self.messages.clear() def setConvertedText(self, text=''): self._convertedtext = text self.buttons.button(QDialogButtonBox.Ok).setEnabled(bool(text)) if text: self.diff.setHtml(htmldiff.htmldiff( self._text, text, _("Current Document"), _("Converted Document"), wrapcolumn=100)) else: self.diff.clear() def setDiffText(self, text=''): if text: from_filename = "current" # TODO: maybe use real filename here to_filename = "converted" # but difflib can choke on non-ascii characters, # see https://github.com/wbsoft/frescobaldi/issues/674 difflist = list(difflib.unified_diff( self._text.split('\n'), text.split('\n'), from_filename, to_filename)) diffHLstr = self.diffHighl(difflist) self.uni_diff.setHtml(diffHLstr) else: self.uni_diff.clear() def convertedText(self): return self._convertedtext or '' def setDocument(self, doc): v = documentinfo.docinfo(doc).version_string() if v: self.fromVersion.setText(v) self.reason.setText(_("(set in document)")) else: self.reason.clear() self._text = doc.toPlainText() self._encoding = doc.encoding() or 'UTF-8' self.setConvertedText() self.setDiffText() def run(self): """Runs convert-ly (again).""" fromVersion = self.fromVersion.text() toVersion = self.toVersion.text() if not fromVersion or not toVersion: self.messages.setPlainText(_( "Both 'from' and 'to' versions need to be set.")) return info = self._info command = info.toolcommand('convert-ly') command += ['-f', fromVersion, '-t', toVersion, '-'] self.job = j = job.Job(command, encoding='utf-8') if QSettings().value("lilypond_settings/no_translation", False, bool): j.environment['LANG'] = 'C' j.environment['LC_ALL'] = 'C' else: j.environment.pop('LANG', None) j.environment.pop('LC_ALL', None) j.done.connect(self.slotJobDone) app.job_queue().add_job(j, 'generic') j._process.write(self._text.encode('utf-8')) j._process.closeWriteChannel() def slotJobDone(self): j = self.job if not j.success and j.failed_to_start(): self.messages.setPlainText(_( "Could not start {convert_ly}:\n\n" "{message}\n").format(convert_ly = j.command[0], message = j.error)) return out = j.stdout() err = j.stderr() self.messages.setPlainText(err) self.setConvertedText(out) self.setDiffText(out) if not out or self._convertedtext == self._text: self.messages.append('\n' + _("The document has not been changed.")) def saveFile(self): """Save content in tab as file""" tabdata = self.getTabData(self.tabw.currentIndex()) doc = self.mainwindow.currentDocument() orgname = doc.url().toLocalFile() filename = os.path.splitext(orgname)[0] + '['+tabdata.filename+']'+'.'+tabdata.ext caption = app.caption(_("dialog title", "Save File")) filetypes = '{0} (*.txt);;{1} (*.htm);;{2} (*)'.format(_("Text Files"), _("HTML Files"), _("All Files")) filename = QFileDialog.getSaveFileName(self.mainwindow, caption, filename, filetypes)[0] if not filename: return False # cancelled with open(filename, 'wb') as f: f.write(tabdata.text.encode('utf-8')) def getTabData(self, index): """Get content of current tab from current index""" if index == 0: return FileInfo('message', 'txt', self.messages.toPlainText()) elif index == 1: return FileInfo('html-diff', 'html', self.diff.toHtml()) elif index == 2: return FileInfo('uni-diff', 'diff', self.uni_diff.toPlainText()) def diffHighl(self, difflist): """Return highlighted version of input.""" result = [] for l in difflist: if l.startswith('-'): s = '<span style="color: red; white-space: pre-wrap;">' elif l.startswith('+'): s = '<span style="color: green; white-space: pre-wrap;">' else: s = '<span style="white-space: pre-wrap;">' h = l.replace('&', '&').replace('<', '<').replace('>', '>') result.append(s + h + '</span>') return '<br>'.join(result)
class MoveFileDialog(QDialog): '''移动文件对话框''' new_infos = pyqtSignal(object) def __init__(self, infos, all_dirs_dict, parent=None): super(MoveFileDialog, self).__init__(parent) self.infos = infos self.dirs = all_dirs_dict self.initUI() self.setStyleSheet(dialog_qss_style) def initUI(self): for i in self.infos: if not i[2]: # 非文件 self.infos.remove(i) self.setWindowTitle("移动文件") self.setWindowIcon(QIcon("./src/move.ico")) self.lb_name = QLabel() self.lb_name.setText("文件路径:") self.lb_name.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.tx_name = QLineEdit() names = " | ".join([i[1] for i in self.infos]) names_tip = "\n".join([i[1] for i in self.infos]) self.tx_name.setText(names) self.tx_name.setToolTip(names_tip) # 只读 self.tx_name.setFocusPolicy(Qt.NoFocus) self.tx_name.setReadOnly(True) self.lb_new_path = QLabel() self.lb_new_path.setText("目标文件夹:") self.lb_new_path.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.tx_new_path = QComboBox() f_icon = QIcon("./src/folder.gif") for f_name, fid in self.dirs.items(): if len(f_name) > 50: # 防止文件夹名字过长? f_name = f_name[:47] + "..." self.tx_new_path.addItem(f_icon, "id:{:>8},name:{}".format(fid, f_name)) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setText("确定") self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消") self.grid = QGridLayout() self.grid.setSpacing(10) self.grid.addWidget(self.lb_name, 1, 0) self.grid.addWidget(self.tx_name, 1, 1) self.grid.addWidget(self.lb_new_path, 2, 0) self.grid.addWidget(self.tx_new_path, 2, 1) self.grid.addWidget(self.buttonBox, 3, 0, 1, 2) self.setLayout(self.grid) self.buttonBox.accepted.connect(self.btn_ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.setMinimumWidth(280) def btn_ok(self): selected = self.tx_new_path.currentText().split(",")[0].split(":")[1] self.new_infos.emit([(info[0], selected, info[1]) for info in self.infos])
def maybeHideClose(bbox: QDialogButtonBox) -> None: if isMac: b = bbox.button(QDialogButtonBox.Close) if b: bbox.removeButton(b)
def __init__(self, parent, worker, config, configfile): QDialog.__init__(self, parent) self.worker = worker self.config = config self.configfile = configfile self.setStyleSheet("QGroupBox { font-weight: bold; } ") self.setWindowTitle('Settings') layout = QGridLayout() # Categories self.category_list = QListWidget() category_media = QListWidgetItem(getIcon('media-playback-start'), 'Media', self.category_list) category_sync = QListWidgetItem(getIcon('view-refresh'), 'Sync', self.category_list) category_ui = QListWidgetItem(getIcon('window-new'), 'User Interface', self.category_list) category_theme = QListWidgetItem(getIcon('applications-graphics'), 'Theme', self.category_list) self.category_list.setSelectionMode(QAbstractItemView.SingleSelection) self.category_list.setCurrentRow(0) self.category_list.setMaximumWidth( self.category_list.sizeHintForColumn(0) + 15) self.category_list.setFocus() self.category_list.currentItemChanged.connect(self.s_switch_page) # Media tab page_media = QWidget() page_media_layout = QVBoxLayout() page_media_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Media settings g_media = QGroupBox('Media settings') g_media.setFlat(True) g_media_layout = QFormLayout() self.tracker_enabled = QCheckBox() self.tracker_enabled.toggled.connect(self.tracker_type_change) self.tracker_type = QComboBox() for (n, label) in utils.available_trackers: self.tracker_type.addItem(label, n) self.tracker_type.currentIndexChanged.connect(self.tracker_type_change) self.tracker_interval = QSpinBox() self.tracker_interval.setRange(5, 1000) self.tracker_interval.setMaximumWidth(60) self.tracker_process = QLineEdit() self.tracker_update_wait = QSpinBox() self.tracker_update_wait.setRange(0, 1000) self.tracker_update_wait.setMaximumWidth(60) self.tracker_update_close = QCheckBox() self.tracker_update_prompt = QCheckBox() self.tracker_not_found_prompt = QCheckBox() self.tracker_ignore_not_next = QCheckBox() g_media_layout.addRow('Enable tracker', self.tracker_enabled) g_media_layout.addRow('Tracker type', self.tracker_type) g_media_layout.addRow('Tracker interval (seconds)', self.tracker_interval) g_media_layout.addRow('Process name (regex)', self.tracker_process) g_media_layout.addRow('Wait before updating (seconds)', self.tracker_update_wait) g_media_layout.addRow('Wait until the player is closed', self.tracker_update_close) g_media_layout.addRow('Ask before updating', self.tracker_update_prompt) g_media_layout.addRow('Ask to add new shows', self.tracker_not_found_prompt) g_media_layout.addRow('Ignore if not next episode', self.tracker_ignore_not_next) g_media.setLayout(g_media_layout) # Group: Plex settings g_plex = QGroupBox('Plex Media Server') g_plex.setFlat(True) self.plex_host = QLineEdit() self.plex_port = QLineEdit() self.plex_user = QLineEdit() self.plex_passw = QLineEdit() self.plex_passw.setEchoMode(QLineEdit.Password) self.plex_obey_wait = QCheckBox() g_plex_layout = QGridLayout() g_plex_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1) g_plex_layout.addWidget(self.plex_host, 0, 1, 1, 1) g_plex_layout.addWidget(self.plex_port, 0, 2, 1, 2) g_plex_layout.addWidget(QLabel('Use "wait before updating" time'), 1, 0, 1, 1) g_plex_layout.addWidget(self.plex_obey_wait, 1, 2, 1, 1) g_plex_layout.addWidget(QLabel('myPlex login (claimed server)'), 2, 0, 1, 1) g_plex_layout.addWidget(self.plex_user, 2, 1, 1, 1) g_plex_layout.addWidget(self.plex_passw, 2, 2, 1, 2) g_plex.setLayout(g_plex_layout) # Group: Jellyfin settings g_jellyfin = QGroupBox('Jellyfin') g_jellyfin.setFlat(True) self.jellyfin_host = QLineEdit() self.jellyfin_port = QLineEdit() self.jellyfin_user = QLineEdit() self.jellyfin_apikey = QLineEdit() g_jellyfin_layout = QGridLayout() g_jellyfin_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1) g_jellyfin_layout.addWidget(self.jellyfin_host, 0, 1, 1, 1) g_jellyfin_layout.addWidget(self.jellyfin_port, 0, 2, 1, 2) g_jellyfin_layout.addWidget(QLabel('API and User'), 1, 0, 1, 1) g_jellyfin_layout.addWidget(self.jellyfin_apikey, 1, 1, 1, 1) g_jellyfin_layout.addWidget(self.jellyfin_user, 1, 2, 1, 2) g_jellyfin.setLayout(g_jellyfin_layout) # Group: Kodi settings g_kodi = QGroupBox('Kodi') g_kodi.setFlat(True) self.kodi_host = QLineEdit() self.kodi_port = QLineEdit() self.kodi_user = QLineEdit() self.kodi_passw = QLineEdit() self.kodi_passw.setEchoMode(QLineEdit.Password) self.kodi_obey_wait = QCheckBox() g_kodi_layout = QGridLayout() g_kodi_layout.addWidget(QLabel('Host and Port'), 0, 0, 1, 1) g_kodi_layout.addWidget(self.kodi_host, 0, 1, 1, 1) g_kodi_layout.addWidget(self.kodi_port, 0, 2, 1, 2) g_kodi_layout.addWidget(QLabel('Use "wait before updating" time'), 1, 0, 1, 1) g_kodi_layout.addWidget(self.kodi_obey_wait, 1, 2, 1, 1) g_kodi_layout.addWidget(QLabel('Kodi login'), 2, 0, 1, 1) g_kodi_layout.addWidget(self.kodi_user, 2, 1, 1, 1) g_kodi_layout.addWidget(self.kodi_passw, 2, 2, 1, 2) g_kodi.setLayout(g_kodi_layout) # Group: Library g_playnext = QGroupBox('Library') g_playnext.setFlat(True) self.player = QLineEdit() self.player_browse = QPushButton('Browse...') self.player_browse.clicked.connect(self.s_player_browse) lbl_searchdirs = QLabel('Media directories') lbl_searchdirs.setAlignment(QtCore.Qt.AlignTop) self.searchdirs = QListWidget() self.searchdirs_add = QPushButton('Add...') self.searchdirs_add.clicked.connect(self.s_searchdirs_add) self.searchdirs_remove = QPushButton('Remove') self.searchdirs_remove.clicked.connect(self.s_searchdirs_remove) self.searchdirs_buttons = QVBoxLayout() self.searchdirs_buttons.setAlignment(QtCore.Qt.AlignTop) self.searchdirs_buttons.addWidget(self.searchdirs_add) self.searchdirs_buttons.addWidget(self.searchdirs_remove) self.searchdirs_buttons.addWidget(QSplitter()) self.library_autoscan = QCheckBox() self.scan_whole_list = QCheckBox() self.library_full_path = QCheckBox() g_playnext_layout = QGridLayout() g_playnext_layout.addWidget(QLabel('Player'), 0, 0, 1, 1) g_playnext_layout.addWidget(self.player, 0, 1, 1, 1) g_playnext_layout.addWidget(self.player_browse, 0, 2, 1, 1) g_playnext_layout.addWidget(lbl_searchdirs, 1, 0, 1, 1) g_playnext_layout.addWidget(self.searchdirs, 1, 1, 1, 1) g_playnext_layout.addLayout(self.searchdirs_buttons, 1, 2, 1, 1) g_playnext_layout.addWidget(QLabel('Rescan Library at startup'), 2, 0, 1, 2) g_playnext_layout.addWidget(self.library_autoscan, 2, 2, 1, 1) g_playnext_layout.addWidget(QLabel('Scan through whole list'), 3, 0, 1, 2) g_playnext_layout.addWidget(self.scan_whole_list, 3, 2, 1, 1) g_playnext_layout.addWidget( QLabel('Take subdirectory name into account'), 4, 0, 1, 2) g_playnext_layout.addWidget(self.library_full_path, 4, 2, 1, 1) g_playnext.setLayout(g_playnext_layout) # Media form page_media_layout.addWidget(g_media) page_media_layout.addWidget(g_plex) page_media_layout.addWidget(g_jellyfin) page_media_layout.addWidget(g_kodi) page_media_layout.addWidget(g_playnext) page_media.setLayout(page_media_layout) # Sync tab page_sync = QWidget() page_sync_layout = QVBoxLayout() page_sync_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Autoretrieve g_autoretrieve = QGroupBox('Autoretrieve') g_autoretrieve.setFlat(True) self.autoretrieve_off = QRadioButton('Disabled') self.autoretrieve_always = QRadioButton('Always at start') self.autoretrieve_days = QRadioButton('After n days') self.autoretrieve_days.toggled.connect(self.s_autoretrieve_days) self.autoretrieve_days_n = QSpinBox() self.autoretrieve_days_n.setRange(1, 100) g_autoretrieve_layout = QGridLayout() g_autoretrieve_layout.setColumnStretch(0, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_off, 0, 0, 1, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_always, 1, 0, 1, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_days, 2, 0, 1, 1) g_autoretrieve_layout.addWidget(self.autoretrieve_days_n, 2, 1, 1, 1) g_autoretrieve.setLayout(g_autoretrieve_layout) # Group: Autosend g_autosend = QGroupBox('Autosend') g_autosend.setFlat(True) self.autosend_off = QRadioButton('Disabled') self.autosend_always = QRadioButton('Immediately after every change') self.autosend_minutes = QRadioButton('After n minutes') self.autosend_minutes.toggled.connect(self.s_autosend_minutes) self.autosend_minutes_n = QSpinBox() self.autosend_minutes_n.setRange(1, 1000) self.autosend_size = QRadioButton('After the queue reaches n items') self.autosend_size.toggled.connect(self.s_autosend_size) self.autosend_size_n = QSpinBox() self.autosend_size_n.setRange(2, 20) self.autosend_at_exit = QCheckBox('At exit') g_autosend_layout = QGridLayout() g_autosend_layout.setColumnStretch(0, 1) g_autosend_layout.addWidget(self.autosend_off, 0, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_always, 1, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_minutes, 2, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_minutes_n, 2, 1, 1, 1) g_autosend_layout.addWidget(self.autosend_size, 3, 0, 1, 1) g_autosend_layout.addWidget(self.autosend_size_n, 3, 1, 1, 1) g_autosend_layout.addWidget(self.autosend_at_exit, 4, 0, 1, 1) g_autosend.setLayout(g_autosend_layout) # Group: Extra g_extra = QGroupBox('Additional options') g_extra.setFlat(True) self.auto_status_change = QCheckBox('Change status automatically') self.auto_status_change.toggled.connect(self.s_auto_status_change) self.auto_status_change_if_scored = QCheckBox( 'Change status automatically only if scored') self.auto_date_change = QCheckBox( 'Change start and finish dates automatically') g_extra_layout = QVBoxLayout() g_extra_layout.addWidget(self.auto_status_change) g_extra_layout.addWidget(self.auto_status_change_if_scored) g_extra_layout.addWidget(self.auto_date_change) g_extra.setLayout(g_extra_layout) # Sync layout page_sync_layout.addWidget(g_autoretrieve) page_sync_layout.addWidget(g_autosend) page_sync_layout.addWidget(g_extra) page_sync.setLayout(page_sync_layout) # UI tab page_ui = QWidget() page_ui_layout = QFormLayout() page_ui_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Icon g_icon = QGroupBox('Notification Icon') g_icon.setFlat(True) self.tray_icon = QCheckBox('Show tray icon') self.tray_icon.toggled.connect(self.s_tray_icon) self.close_to_tray = QCheckBox('Close to tray') self.start_in_tray = QCheckBox('Start minimized to tray') self.tray_api_icon = QCheckBox('Use API icon as tray icon') self.notifications = QCheckBox( 'Show notification when tracker detects new media') g_icon_layout = QVBoxLayout() g_icon_layout.addWidget(self.tray_icon) g_icon_layout.addWidget(self.close_to_tray) g_icon_layout.addWidget(self.start_in_tray) g_icon_layout.addWidget(self.tray_api_icon) g_icon_layout.addWidget(self.notifications) g_icon.setLayout(g_icon_layout) # Group: Window g_window = QGroupBox('Window') g_window.setFlat(True) self.remember_geometry = QCheckBox('Remember window size and position') self.remember_columns = QCheckBox('Remember column layouts and widths') self.columns_per_api = QCheckBox( 'Use different visible columns per API') g_window_layout = QVBoxLayout() g_window_layout.addWidget(self.remember_geometry) g_window_layout.addWidget(self.remember_columns) g_window_layout.addWidget(self.columns_per_api) g_window.setLayout(g_window_layout) # Group: Lists g_lists = QGroupBox('Lists') g_lists.setFlat(True) self.filter_bar_position = QComboBox() filter_bar_positions = [(FilterBar.PositionHidden, 'Hidden'), (FilterBar.PositionAboveLists, 'Above lists'), (FilterBar.PositionBelowLists, 'Below lists')] for (n, label) in filter_bar_positions: self.filter_bar_position.addItem(label, n) self.inline_edit = QCheckBox('Enable in-line editing') g_lists_layout = QFormLayout() g_lists_layout.addRow('Filter bar position:', self.filter_bar_position) g_lists_layout.addRow(self.inline_edit) g_lists.setLayout(g_lists_layout) # UI layout page_ui_layout.addWidget(g_icon) page_ui_layout.addWidget(g_window) page_ui_layout.addWidget(g_lists) page_ui.setLayout(page_ui_layout) # Theming tab page_theme = QWidget() page_theme_layout = QFormLayout() page_theme_layout.setAlignment(QtCore.Qt.AlignTop) # Group: Episode Bar g_ep_bar = QGroupBox('Episode Bar') g_ep_bar.setFlat(True) self.ep_bar_style = QComboBox() ep_bar_styles = [(ShowsTableDelegate.BarStyleBasic, 'Basic'), (ShowsTableDelegate.BarStyle04, 'Trackma'), (ShowsTableDelegate.BarStyleHybrid, 'Hybrid')] for (n, label) in ep_bar_styles: self.ep_bar_style.addItem(label, n) self.ep_bar_style.currentIndexChanged.connect(self.s_ep_bar_style) self.ep_bar_text = QCheckBox('Show text label') g_ep_bar_layout = QFormLayout() g_ep_bar_layout.addRow('Style:', self.ep_bar_style) g_ep_bar_layout.addRow(self.ep_bar_text) g_ep_bar.setLayout(g_ep_bar_layout) # Group: Colour scheme g_scheme = QGroupBox('Color Scheme') g_scheme.setFlat(True) col_tabs = [('rows', '&Row highlights'), ('progress', '&Progress widget')] self.colors = {} self.colors['rows'] = [('is_playing', 'Playing'), ('is_queued', 'Queued'), ('new_episode', 'New Episode'), ('is_airing', 'Airing'), ('not_aired', 'Unaired')] self.colors['progress'] = [('progress_bg', 'Background'), ('progress_fg', 'Watched bar'), ('progress_sub_bg', 'Aired episodes'), ('progress_sub_fg', 'Stored episodes'), ('progress_complete', 'Complete')] self.color_buttons = [] self.syscolor_buttons = [] g_scheme_layout = QGridLayout() tw_scheme = QTabWidget() for (key, tab_title) in col_tabs: page = QFrame() page_layout = QGridLayout() col = 0 # Generate widgets from the keys and values for (key, label) in self.colors[key]: self.color_buttons.append(QPushButton()) # self.color_buttons[-1].setStyleSheet('background-color: ' + getColor(self.config['colors'][key]).name()) self.color_buttons[-1].setFocusPolicy(QtCore.Qt.NoFocus) self.color_buttons[-1].clicked.connect( self.s_color_picker(key, False)) self.syscolor_buttons.append(QPushButton('System Colors')) self.syscolor_buttons[-1].clicked.connect( self.s_color_picker(key, True)) page_layout.addWidget(QLabel(label), col, 0, 1, 1) page_layout.addWidget(self.color_buttons[-1], col, 1, 1, 1) page_layout.addWidget(self.syscolor_buttons[-1], col, 2, 1, 1) col += 1 page.setLayout(page_layout) tw_scheme.addTab(page, tab_title) g_scheme_layout.addWidget(tw_scheme) g_scheme.setLayout(g_scheme_layout) # UI layout page_theme_layout.addWidget(g_ep_bar) page_theme_layout.addWidget(g_scheme) page_theme.setLayout(page_theme_layout) # Content self.contents = QStackedWidget() for page in (page_media, page_sync, page_ui, page_theme): scrollable_page = QScrollArea() scrollable_page.setWidgetResizable(True) scrollable_page.setWidget(page) self.contents.addWidget(scrollable_page) if pyqt_version != 5: self.contents.layout().setMargin(0) # Bottom buttons bottombox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) bottombox.accepted.connect(self.s_save) bottombox.button(QDialogButtonBox.Apply).clicked.connect(self._save) bottombox.rejected.connect(self.reject) # Main layout finish layout.addWidget(self.category_list, 0, 0, 1, 1) layout.addWidget(self.contents, 0, 1, 1, 1) layout.addWidget(bottombox, 1, 0, 1, 2) layout.setColumnStretch(1, 1) self._load() self.update_colors() self.setLayout(layout)
class FolderDialog(QDialog): def __init__(self, parent=None): super(QDialog, self).__init__(parent) self.parent = parent self.resize(400, 300) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(5) self.verticalLayout.setContentsMargins(5, 5, 5, 5) self.labelName = QLabel(self) self.verticalLayout.addWidget(self.labelName) self.lineEditFolder = QLineEdit(self) self.verticalLayout.addWidget(self.lineEditFolder) self.labelWarning = QLabel(self) self.labelWarning.hide() self.verticalLayout.addWidget(self.labelWarning) self.labelFolder = QLabel(self) self.verticalLayout.addWidget(self.labelFolder) self.treeWidget = QTreeWidget(self) self.treeWidget.setAlternatingRowColors(True) self.treeWidget.setIconSize(QSize(12, 12)) self.treeWidget.setAnimated(True) self.treeWidget.header().setVisible(False) self.verticalLayout.addWidget(self.treeWidget) self.line = QFrame(self) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(self.line) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Save) self.buttonBox.button(QDialogButtonBox.Cancel).setText(self.tr("Cancel")) self.buttonBox.button(QDialogButtonBox.Save).setText(self.tr("Save")) self.verticalLayout.addWidget(self.buttonBox) self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.folderAdd) self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.reject) self.lineEditFolder.returnPressed.connect(self.buttonBox.button(QDialogButtonBox.Save).toggle) self.lineEditFolder.textChanged.connect(self.labelWarning.hide) self.setWindowTitle(self.tr("Add Folder")) self.labelName.setText(self.tr("Name:")) self.labelFolder.setText(self.tr("Insert:")) self.treeWidget.headerItem().setText(0, self.tr("Folder")) self.treeWidget.setIconSize(QSize(18, 18)) self.categorySorting(treeitem=self.treeWidget) def categorySorting(self, id=0, treeitem=None): db = ReaderDb() db.execute("select * from folders where type='folder' and parent=?",(id,)) folders = db.cursor.fetchall() for folder in folders: item = QTreeWidgetItem(treeitem) item.setIcon(0, QIcon(":/images/icons/folder_grey.png")) item.id = folder["id"] item.category_name = folder[1] item.setText(0, item.category_name) item.subcategory = folder["parent"] self.categorySorting(folder["id"], item) def folderAdd(self): text = self.lineEditFolder.text() db = ReaderDb() if len(text): control = db.execute("select * from folders where title=?", (text,)) if not control.fetchone(): if self.treeWidget.currentItem() == None or not len(self.treeWidget.selectedItems()): db.execute("insert into folders (title, type) values (?, 'folder')", (text,)) db.commit() db.close() else: db.execute("insert into folders (title, parent, type) values (?, ?, 'folder')", (text, self.treeWidget.currentItem().id)) db.commit() db.close() self.parent.syncSignal.emit() self.parent.categorySync() self.close() else: self.labelWarning.setText(self.tr("<span style='color:red; font-size:15px; font-weight:bold;'>Same category name cannot add!</span>")) self.labelWarning.show() else: self.labelWarning.setText(self.tr("<span style='color:red; font-size:15px; font-weight:bold; align:'center';'>You didn't write folder's name!</span>")) self.labelWarning.show()
class Dialog(QDialog): def __init__(self, mainwindow): super(Dialog, self).__init__(mainwindow) self._document = None layout = QGridLayout() self.setLayout(layout) self.versionLabel = QLabel() self.lilyChooser = lilychooser.LilyChooser() self.outputLabel = QLabel() self.outputCombo = QComboBox() self.resolutionLabel = QLabel() self.resolutionCombo = QComboBox(editable=True) self.antialiasLabel = QLabel() self.antialiasSpin = QSpinBox(minimum=1, maximum=128, value=1) self.modeLabel = QLabel() self.modeCombo = QComboBox() self.deleteCheck = QCheckBox() self.embedSourceCodeCheck = QCheckBox() self.englishCheck = QCheckBox() self.commandLineLabel = QLabel() self.commandLine = QTextEdit(acceptRichText=False) self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).setIcon(icons.get("lilypond-run")) userguide.addButton(self.buttons, "engrave_custom") self.resolutionCombo.addItems(['100', '200', '300', '600', '1200']) self.resolutionCombo.setCurrentIndex(2) self.modeCombo.addItems(['preview', 'publish', 'debug', 'incipit']) layout.addWidget(self.versionLabel, 0, 0) layout.addWidget(self.lilyChooser, 0, 1, 1, 3) layout.addWidget(self.outputLabel, 1, 0) layout.addWidget(self.outputCombo, 1, 1, 1, 3) layout.addWidget(self.resolutionLabel, 2, 0) layout.addWidget(self.resolutionCombo, 2, 1) layout.addWidget(self.antialiasLabel, 2, 2, Qt.AlignRight) layout.addWidget(self.antialiasSpin, 2, 3) layout.addWidget(self.modeLabel, 3, 0) layout.addWidget(self.modeCombo, 3, 1, 1, 3) layout.addWidget(self.deleteCheck, 4, 0, 1, 4) layout.addWidget(self.embedSourceCodeCheck, 5, 0, 1, 4) layout.addWidget(self.englishCheck, 6, 0, 1, 4) layout.addWidget(self.commandLineLabel, 7, 0, 1, 4) layout.addWidget(self.commandLine, 8, 0, 1, 4) layout.addWidget(widgets.Separator(), 9, 0, 1, 4) layout.addWidget(self.buttons, 10, 0, 1, 4) app.translateUI(self) qutil.saveDialogSize(self, "engrave/custom/dialog/size", QSize(480, 260)) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) model = listmodel.ListModel(formats, display=lambda f: f.title(), icon=lambda f: icons.file_type(f.type)) self.outputCombo.setModel(model) s = QSettings() s.beginGroup("lilypond_settings") self.englishCheck.setChecked( s.value("no_translation", False, bool)) self.deleteCheck.setChecked( s.value("delete_intermediate_files", True, bool)) if s.value("default_output_target", "pdf", str) == "svg": self.outputCombo.setCurrentIndex(3) app.jobFinished.connect(self.slotJobFinished) self.outputCombo.currentIndexChanged.connect(self.makeCommandLine) self.modeCombo.currentIndexChanged.connect(self.makeCommandLine) self.deleteCheck.toggled.connect(self.makeCommandLine) self.embedSourceCodeCheck.toggled.connect(self.makeCommandLine) self.resolutionCombo.editTextChanged.connect(self.makeCommandLine) self.antialiasSpin.valueChanged.connect(self.makeCommandLine) self.makeCommandLine() panelmanager.manager(mainwindow).layoutcontrol.widget().optionsChanged.connect(self.makeCommandLine) def translateUI(self): self.setWindowTitle(app.caption(_("Engrave custom"))) self.versionLabel.setText(_("LilyPond Version:")) self.outputLabel.setText(_("Output Format:")) self.resolutionLabel.setText(_("Resolution:")) self.antialiasLabel.setText(_("Antialias Factor:")) self.modeLabel.setText(_("Engraving mode:")) self.modeCombo.setItemText(0, _("Preview")) self.modeCombo.setItemText(1, _("Publish")) self.modeCombo.setItemText(2, _("First System Only")) self.modeCombo.setItemText(3, _("Layout Control")) self.deleteCheck.setText(_("Delete intermediate output files")) self.embedSourceCodeCheck.setText(_("Embed Source Code (LilyPond >= 2.19.39)")) self.englishCheck.setText(_("Run LilyPond with English messages")) self.commandLineLabel.setText(_("Command line:")) self.buttons.button(QDialogButtonBox.Ok).setText(_("Run LilyPond")) self.outputCombo.update() def slotJobFinished(self, doc): if doc == self._document: self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) self._document = None def setDocument(self, doc): self.lilyChooser.setLilyPondInfo(command.info(doc)) job = jobmanager.job(doc) if job and job.is_running() and not jobattributes.get(job).hidden: self._document = doc self.buttons.button(QDialogButtonBox.Ok).setEnabled(False) def makeCommandLine(self): """Reads the widgets and builds a command line.""" f = formats[self.outputCombo.currentIndex()] self.resolutionCombo.setEnabled('resolution' in f.widgets) self.antialiasSpin.setEnabled('antialias' in f.widgets) cmd = ["$lilypond"] if self.modeCombo.currentIndex() == 0: # preview mode cmd.append('-dpoint-and-click') elif self.modeCombo.currentIndex() == 1: # publish mode cmd.append('-dno-point-and-click') elif self.modeCombo.currentIndex() == 2: # incipit mode cmd.extend(['-dpreview', '-dno-print-pages']) else: # debug mode args = panelmanager.manager(self.parent()).layoutcontrol.widget().preview_options() cmd.extend(args) if self.deleteCheck.isChecked(): cmd.append('-ddelete-intermediate-files') else: cmd.append('-dno-delete-intermediate-files') if self.embedSourceCodeCheck.isChecked(): cmd.append('-dembed-source-code') d = { 'version': self.lilyChooser.lilyPondInfo().version, 'resolution': self.resolutionCombo.currentText(), 'antialias': self.antialiasSpin.value(), } cmd.append("$include") cmd.extend(f.options(d)) cmd.append("$filename") self.commandLine.setText(' '.join(cmd)) def getJob(self, document): """Returns a Job to start.""" filename, includepath = documentinfo.info(document).jobinfo(True) i = self.lilyChooser.lilyPondInfo() cmd = [] for t in self.commandLine.toPlainText().split(): if t == '$lilypond': cmd.append(i.abscommand() or i.command) elif t == '$filename': cmd.append(filename) elif t == '$include': cmd.extend('-I' + path for path in includepath) else: cmd.append(t) j = job.Job() j.directory = os.path.dirname(filename) j.command = cmd j.environment['LD_LIBRARY_PATH'] = i.libdir() if self.englishCheck.isChecked(): j.environment['LANG'] = 'C' j.environment['LC_ALL'] = 'C' j.set_title("{0} {1} [{2}]".format( os.path.basename(i.command), i.versionString(), document.documentName())) return j def keyPressEvent(self, ev): if ev.key() == Qt.Key_Return and ev.modifiers() == Qt.ControlModifier: self.accept() else: super(Dialog, self).keyPressEvent(ev)
class LocationDialog(QDialog): def __init__(self, parent=None): super(LocationDialog, self).__init__(parent) self.formatComboBox = QComboBox() self.formatComboBox.addItem("Native") self.formatComboBox.addItem("INI") self.scopeComboBox = QComboBox() self.scopeComboBox.addItem("User") self.scopeComboBox.addItem("System") self.organizationComboBox = QComboBox() self.organizationComboBox.addItem("Trolltech") self.organizationComboBox.setEditable(True) self.applicationComboBox = QComboBox() self.applicationComboBox.addItem("Any") self.applicationComboBox.addItem("Application Example") self.applicationComboBox.addItem("Assistant") self.applicationComboBox.addItem("Designer") self.applicationComboBox.addItem("Linguist") self.applicationComboBox.setEditable(True) self.applicationComboBox.setCurrentIndex(3) formatLabel = QLabel("&Format:") formatLabel.setBuddy(self.formatComboBox) scopeLabel = QLabel("&Scope:") scopeLabel.setBuddy(self.scopeComboBox) organizationLabel = QLabel("&Organization:") organizationLabel.setBuddy(self.organizationComboBox) applicationLabel = QLabel("&Application:") applicationLabel.setBuddy(self.applicationComboBox) self.locationsGroupBox = QGroupBox("Setting Locations") self.locationsTable = QTableWidget() self.locationsTable.setSelectionMode(QAbstractItemView.SingleSelection) self.locationsTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.locationsTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.locationsTable.setColumnCount(2) self.locationsTable.setHorizontalHeaderLabels(("Location", "Access")) self.locationsTable.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) self.locationsTable.horizontalHeader().resizeSection(1, 180) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.formatComboBox.activated.connect(self.updateLocationsTable) self.scopeComboBox.activated.connect(self.updateLocationsTable) self.organizationComboBox.lineEdit().editingFinished.connect(self.updateLocationsTable) self.applicationComboBox.lineEdit().editingFinished.connect(self.updateLocationsTable) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) locationsLayout = QVBoxLayout() locationsLayout.addWidget(self.locationsTable) self.locationsGroupBox.setLayout(locationsLayout) mainLayout = QGridLayout() mainLayout.addWidget(formatLabel, 0, 0) mainLayout.addWidget(self.formatComboBox, 0, 1) mainLayout.addWidget(scopeLabel, 1, 0) mainLayout.addWidget(self.scopeComboBox, 1, 1) mainLayout.addWidget(organizationLabel, 2, 0) mainLayout.addWidget(self.organizationComboBox, 2, 1) mainLayout.addWidget(applicationLabel, 3, 0) mainLayout.addWidget(self.applicationComboBox, 3, 1) mainLayout.addWidget(self.locationsGroupBox, 4, 0, 1, 2) mainLayout.addWidget(self.buttonBox, 5, 0, 1, 2) self.setLayout(mainLayout) self.updateLocationsTable() self.setWindowTitle("Open Application Settings") self.resize(650, 400) def format(self): if self.formatComboBox.currentIndex() == 0: return QSettings.NativeFormat else: return QSettings.IniFormat def scope(self): if self.scopeComboBox.currentIndex() == 0: return QSettings.UserScope else: return QSettings.SystemScope def organization(self): return self.organizationComboBox.currentText() def application(self): if self.applicationComboBox.currentText() == "Any": return '' return self.applicationComboBox.currentText() def updateLocationsTable(self): self.locationsTable.setUpdatesEnabled(False) self.locationsTable.setRowCount(0) for i in range(2): if i == 0: if self.scope() == QSettings.SystemScope: continue actualScope = QSettings.UserScope else: actualScope = QSettings.SystemScope for j in range(2): if j == 0: if not self.application(): continue actualApplication = self.application() else: actualApplication = '' settings = QSettings(self.format(), actualScope, self.organization(), actualApplication) row = self.locationsTable.rowCount() self.locationsTable.setRowCount(row + 1) item0 = QTableWidgetItem() item0.setText(settings.fileName()) item1 = QTableWidgetItem() disable = not (settings.childKeys() or settings.childGroups()) if row == 0: if settings.isWritable(): item1.setText("Read-write") disable = False else: item1.setText("Read-only") self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(disable) else: item1.setText("Read-only fallback") if disable: item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled) item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled) self.locationsTable.setItem(row, 0, item0) self.locationsTable.setItem(row, 1, item1) self.locationsTable.setUpdatesEnabled(True)
class PackageDialog(QDialog): """ Display a dialog to indicate the status of the packaging related changes currently run by pip. """ def __init__(self, parent=None): super().__init__(parent) def setup(self, to_remove, to_add, module_dir): """ Create the UI for the dialog. """ self.to_remove = to_remove self.to_add = to_add self.module_dir = module_dir self.pkg_dirs = {} # To hold locations of to-be-removed packages. self.process = None # Basic layout. self.setMinimumSize(600, 400) self.setWindowTitle(_('Third Party Package Status')) widget_layout = QVBoxLayout() self.setLayout(widget_layout) # Text area for pip output. self.text_area = QPlainTextEdit() self.text_area.setReadOnly(True) self.text_area.setLineWrapMode(QPlainTextEdit.NoWrap) widget_layout.addWidget(self.text_area) # Buttons. self.button_box = QDialogButtonBox(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.button_box.accepted.connect(self.accept) widget_layout.addWidget(self.button_box) # Kick off processing of packages. if self.to_remove: self.remove_packages() if self.to_add: self.run_pip() def remove_packages(self): """ Work out which packages need to be removed and then kick off their removal. """ dirs = [os.path.join(self.module_dir, d) for d in os.listdir(self.module_dir) if d.endswith("dist-info")] self.pkg_dirs = {} for pkg in self.to_remove: for d in dirs: # Assets on the filesystem use a normalised package name. pkg_name = pkg.replace('-', '_').lower() if os.path.basename(d).lower().startswith(pkg_name + '-'): self.pkg_dirs[pkg] = d if self.pkg_dirs: # If there are packages to remove, schedule removal. QTimer.singleShot(2, self.remove_package) def remove_package(self): """ Take a package from the pending packages to be removed, delete all its assets and schedule the removal of the remaining packages. If there are no packages to remove, move to the finished state. """ if self.pkg_dirs: package, dist = self.pkg_dirs.popitem() record = os.path.join(dist, 'RECORD') with open(record) as f: files = csv.reader(f) for row in files: to_delete = os.path.join(self.module_dir, row[0]) try: os.remove(to_delete) except Exception as ex: logger.error('Unable to remove: {}'.format(to_delete)) logger.error(ex) shutil.rmtree(dist, ignore_errors=True) # Some modules don't use the module name for the module directory # (they use a lower case variant thereof). E.g. "Fom" vs. "fom". normal_module = os.path.join(self.module_dir, package) lower_module = os.path.join(self.module_dir, package.lower()) shutil.rmtree(normal_module, ignore_errors=True) shutil.rmtree(lower_module, ignore_errors=True) self.append_data('Removed {}\n'.format(package)) QTimer.singleShot(2, self.remove_package) else: # Clean any directories not containing files. dirs = [os.path.join(self.module_dir, d) for d in os.listdir(self.module_dir)] for d in dirs: keep = False for entry in os.walk(d): if entry[2]: keep = True if not keep: shutil.rmtree(d, ignore_errors=True) # Check for end state. if not (self.to_add or self.process): self.end_state() def end_state(self): """ Set the UI to a valid end state. """ self.append_data('\nFINISHED') self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) def run_pip(self): """ Run a pip command in a subprocess and pipe the output to the dialog's text area. """ package = self.to_add.pop() args = ['-m', 'pip', 'install', package, '--target', self.module_dir] self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.readyRead.connect(self.read_process) self.process.finished.connect(self.finished) self.process.start(sys.executable, args) def finished(self): """ Called when the subprocess that uses pip to install a package is finished. """ if self.to_add: self.process = None self.run_pip() else: if not self.pkg_dirs: self.end_state() def read_process(self): """ Read data from the child process and append it to the text area. Try to keep reading until there's no more data from the process. """ data = self.process.readAll() if data: self.append_data(data.data().decode('utf-8')) QTimer.singleShot(2, self.read_process) def append_data(self, msg): """ Add data to the end of the text area. """ cursor = self.text_area.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(msg) cursor.movePosition(QTextCursor.End) self.text_area.setTextCursor(cursor)
def __init__(self, main, object): QDialog.__init__(self) self.main = main self.tmp = main.tmpDirectory self.object = object self.folderpath = "" self.layoutList = [] self.closed = False self.setWindowTitle('Layout') self.setWindowFlags(Qt.Window) self.resize(650, 500) self.setMinimumSize(QSize(0, 500)) self.setMaximumSize(QSize(16777215, 500)) horizontalLayout = QHBoxLayout(self) formLayout = QFormLayout() formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) formLayout.setFormAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop) addLabel = QLabel(self) addLabel.setMinimumSize(QSize(23, 23)) addLabel.setMaximumSize(QSize(23, 23)) addLabel.setPixmap(QPixmap(self.main.pluginDirectory+"/icons/addLayout.png")) removeLabel = QLabel(self) removeLabel.setMinimumSize(QSize(23, 23)) removeLabel.setMaximumSize(QSize(23, 23)) removeLabel.setPixmap(QPixmap(self.main.pluginDirectory+"/icons/removeLayout.png")) addLayout = QHBoxLayout() addLayout.setSizeConstraint(QLayout.SetFixedSize) addLayout.addWidget(addLabel) addLayout.addWidget(removeLabel) formLayout.setLayout(0, QFormLayout.LabelRole, addLayout) self.layoutFoldersList = QTableWidget(0, 1, self) self.layoutFoldersList.setMinimumSize(QSize(300, 400)) self.layoutFoldersList.setColumnWidth(0, 300) self.layoutFoldersList.setHorizontalHeaderLabels(["Layout-Ordner"]) self.layoutFoldersList.setEditTriggers(QAbstractItemView.NoEditTriggers) self.layoutFoldersList.setSelectionMode(QAbstractItemView.SingleSelection) self.layoutsList = QTableWidget(0, 1, self) self.layoutsList.setMinimumSize(QSize(300, 400)) self.layoutsList.setColumnWidth(0, 300) self.layoutsList.setHorizontalHeaderLabels(["Layouts"]) self.layoutsList.setSelectionMode(QAbstractItemView.SingleSelection) self.layoutsList.setEditTriggers(QAbstractItemView.NoEditTriggers) layoutLayout = QHBoxLayout() layoutLayout.setSizeConstraint(QLayout.SetMaximumSize) layoutLayout.addWidget(self.layoutFoldersList) layoutLayout.addWidget(self.layoutsList) formLayout.setLayout(1, QFormLayout.SpanningRole, layoutLayout) buttonBox = QDialogButtonBox(self) buttonBox.setStandardButtons(QDialogButtonBox.Close|QDialogButtonBox.Apply) formLayout.setWidget(2, QFormLayout.FieldRole, buttonBox) horizontalLayout.addLayout(formLayout) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.showLayout) buttonBox.button(QDialogButtonBox.Close).clicked.connect(self.cancel) self.layoutFoldersList.itemClicked.connect(self.getLayouts) addLabel.mouseReleaseEvent = self.newFolder removeLabel.mouseReleaseEvent = self.delFolder self.layoutFoldersList.keyPressEvent = self.keyPress for layout in self.main.config.options('Layouts'): l = self.main.config.get('Layouts', layout) self.layoutList.append(layout) self.layoutFoldersList.setRowCount(self.layoutFoldersList.rowCount()+1) self.layoutFoldersList.setItem(self.layoutFoldersList.rowCount()-1, 0, QTableWidgetItem(l)) #self.exec_() self.show()
class SetPwdDialog(QDialog): new_infos = pyqtSignal(object) def __init__(self, parent=None): super(SetPwdDialog, self).__init__(parent) self.infos = None self.initUI() self.update_text() self.setStyleSheet(dialog_qss_style) def set_values(self, infos): self.infos = infos self.update_text() # 更新界面 def set_tip(self): # 用于提示状态 self.setWindowTitle("请稍等……") def initUI(self): self.setWindowTitle("请稍等……") self.setWindowIcon(QIcon("./src/password.ico")) self.lb_oldpwd = QLabel() self.lb_oldpwd.setText("当前提取码:") self.lb_oldpwd.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.tx_oldpwd = QLineEdit() # 当前提取码 只读 self.tx_oldpwd.setFocusPolicy(Qt.NoFocus) self.tx_oldpwd.setReadOnly(True) self.lb_newpwd = QLabel() self.lb_newpwd.setText("新的提取码:") self.lb_newpwd.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.tx_newpwd = QLineEdit() self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setText("确定") self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消") self.grid = QGridLayout() self.grid.setSpacing(10) self.grid.addWidget(self.lb_oldpwd, 1, 0) self.grid.addWidget(self.tx_oldpwd, 1, 1) self.grid.addWidget(self.lb_newpwd, 2, 0) self.grid.addWidget(self.tx_newpwd, 2, 1) self.grid.addWidget(self.buttonBox, 3, 0, 1, 2) self.setLayout(self.grid) self.buttonBox.accepted.connect(self.btn_ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.accepted.connect(self.set_tip) self.buttonBox.rejected.connect(self.reject) self.buttonBox.rejected.connect(self.set_tip) self.setMinimumWidth(280) def update_text(self): if self.infos: if self.infos[5]: self.tx_oldpwd.setText(str(self.infos[5])) self.tx_oldpwd.setPlaceholderText("") else: self.tx_oldpwd.setText("") self.tx_oldpwd.setPlaceholderText("无") if self.infos[2]: # 文件 通过size列判断是否为文件 self.setWindowTitle("修改文件提取码") self.tx_newpwd.setPlaceholderText("2-6位字符,关闭请留空") self.tx_newpwd.setMaxLength(6) # 最长6个字符 else: # 文件夹 self.setWindowTitle("修改文件夹名提取码") self.tx_newpwd.setPlaceholderText("2-12位字符,关闭请留空") self.tx_newpwd.setMaxLength(12) # 最长12个字符 def btn_ok(self): new_pwd = self.tx_newpwd.text() if new_pwd != self.infos[5]: self.new_infos.emit( (self.infos[0], new_pwd, self.infos[2])) # 最后一位用于标示文件还是文件夹
def __init__(self, parent) -> None: super().__init__(parent) self.rapidApp = parent # type: 'RapidWindow' self.setModal(True) self.setSizeGripEnabled(False) self.dialog_detailed_result = None self.current_state = CheckNewVersionDialogState.check self.checkingLabel = QLabel(_("Checking for new version...")) self.noNewVersion = QLabel(_("You are running the latest version.")) self.failedToCheck = QLabel(_("Failed to contact the update server.")) self.url = "http://www.damonlynch.net/rapid/download.html" self.new_version_message = _( "A new version of Rapid Photo Downloader (%s) is available.") self.new_version_message = "<b>{}</b>".format(self.new_version_message) self.download_it = _( "Do you want to download the new version?") + "<br>" self.changelog_msg = _( 'Changes in the new release can be viewed <a href="%s">here</a>.') for label in (self.checkingLabel, self.noNewVersion, self.failedToCheck): label.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.newVersion = QLabel( self._makeDownloadMsg("1.2.3a10", offer_download=True, changelog_url="")) self.newVersion.setOpenExternalLinks(True) self.changelog = QLabel(self.changelog_msg) self.changelog.setOpenExternalLinks(True) self.messages = QStackedWidget() self.messages.addWidget(self.checkingLabel) self.messages.addWidget(self.noNewVersion) self.messages.addWidget(self.newVersion) self.messages.addWidget(self.failedToCheck) cancelBox = QDialogButtonBox(QDialogButtonBox.Cancel) translateDialogBoxButtons(cancelBox) cancelBox.rejected.connect(self.reject) self.downloadItBox = QDialogButtonBox(QDialogButtonBox.Yes | QDialogButtonBox.No) translateDialogBoxButtons(self.downloadItBox) # Translators: this text appears in a button - the & sets the s key in # combination with the alt key to act as the keyboard shortcut self.dlItSkipButton = QPushButton(_("&Skip this release")) self.dlItSkipButton.setDefault(False) self.downloadItBox.addButton(self.dlItSkipButton, QDialogButtonBox.RejectRole) self.dlItYesButton = self.downloadItBox.button( QDialogButtonBox.Yes) # type: QPushButton self.dlItNoButton = self.downloadItBox.button( QDialogButtonBox.No) # type: QPushButton self.downloadItBox.clicked.connect(self.downloadItClicked) closeBox = QDialogButtonBox(QDialogButtonBox.Close) translateDialogBoxButtons(closeBox) closeBox.rejected.connect(self.reject) openDownloadPageBox = QDialogButtonBox(QDialogButtonBox.Close) translateDialogBoxButtons(openDownloadPageBox) # Translators: this text appears in a button - the & sets the s key in # combination with the alt key to act as the keyboard shortcut self.openDlPageSkipButton = QPushButton(_("&Skip this release")) # Translators: this text appears in a button - the & sets the o key in # combination with the alt key to act as the keyboard shortcut self.openDlPageButton = QPushButton(_("&Open Download Page")) self.openDlPageButton.setDefault(True) openDownloadPageBox.addButton(self.openDlPageSkipButton, QDialogButtonBox.RejectRole) openDownloadPageBox.addButton(self.openDlPageButton, QDialogButtonBox.ActionRole) self.openDlCloseButton = openDownloadPageBox.button( QDialogButtonBox.Close) openDownloadPageBox.clicked.connect(self.openWebsiteClicked) self.buttons = QStackedWidget() self.buttons.addWidget(cancelBox) self.buttons.addWidget(closeBox) self.buttons.addWidget(self.downloadItBox) self.buttons.addWidget(openDownloadPageBox) self.messages.setCurrentIndex(0) self.buttons.setCurrentIndex(0) grid = QGridLayout() grid.addWidget(self.messages, 0, 0, 1, 2, Qt.AlignTop) grid.addWidget(self.buttons, 1, 0, 1, 2) self.setLayout(grid) self.setWindowTitle(_("Rapid Photo Downloader updates"))
class GeneralResidueEvolution(BasePopup): """ A popup for setting General Residue Evolution Plot specific settings in the Farseer-NMR configuration. Parameters: parent(QWidget): parent widget for popup. Methods: .get_defaults() .get_values() .set_values() """ def __init__(self, parent=None, **kw): BasePopup.__init__(self, parent, title="Residue Evolution Plot", settings_key=["revo_settings"]) self.do_revo_fit = LabelledCheckbox(self, text="Fit Parameter Evolution") self.revo_subtitle_fn = FontComboBox(self, text="Subtitle Font") self.revo_subtitle_fs = LabelledSpinBox(self, text="Subtitle Font Size", minimum=0, step=1) self.revo_subtitle_pad = LabelledDoubleSpinBox(self, text="Subtitle Padding", minimum=-100, maximum=100, step=0.1) self.revo_subtitle_weight = LabelledCombobox( self, text="Subtitle Font Weight", items=font_weights) self.revo_x_label_fn = FontComboBox(self, text="X Label Font") self.revo_x_label_fs = LabelledSpinBox(self, text="X Label Font Size", minimum=0, step=1) self.revo_x_label_pad = LabelledDoubleSpinBox(self, text="X Label Padding", minimum=-100, maximum=100, step=0.1) self.revo_x_label_weight = LabelledCombobox(self, text="X Label Font Weight", items=font_weights) self.revo_y_label_fn = FontComboBox(self, text="Y Label Font Size") self.revo_y_label_fs = LabelledSpinBox(self, text="Y Label Font Size", minimum=0, step=1) self.revo_y_label_pad = LabelledSpinBox(self, text="Y Label Padding", minimum=-100, maximum=100, step=0.1) self.revo_y_label_weight = LabelledCombobox(self, text="Y Label Font Weight", items=font_weights) self.revo_x_ticks_fn = FontComboBox(self, text="X Tick Font") self.revo_x_ticks_fs = LabelledSpinBox(self, text="X Tick Font Size", minimum=0, step=1) self.revo_x_ticks_pad = LabelledDoubleSpinBox(self, text="X Tick Padding", minimum=-100, maximum=100, step=0.1) self.revo_x_ticks_weight = LabelledCombobox(self, text="X Tick Font Weight", items=font_weights) self.revo_x_ticks_rotation = LabelledDoubleSpinBox( self, text="X Tick Rotation", minimum=0, maximum=360, step=1) self.revo_y_ticks_fn = FontComboBox(self, text="Y Tick Font") self.revo_y_ticks_fs = LabelledSpinBox(self, text="Y Tick Font Size", minimum=0, step=1) self.revo_y_ticks_pad = LabelledDoubleSpinBox(self, text="Y Tick Padding", minimum=-100, maximum=100, step=0.1) self.revo_y_ticks_weight = LabelledCombobox(self, text="Y Tick Font Weight", items=font_weights) self.revo_y_ticks_rot = LabelledSpinBox(self, text="Y Tick Rotation", minimum=0, maximum=360, step=1) self.titration_x_values = LabelledLineEdit(self, text="Titration X Values") # add widgets self.layout().addWidget(self.revo_subtitle_fn, 0, 0) self.layout().addWidget(self.revo_subtitle_fs, 1, 0) self.layout().addWidget(self.revo_subtitle_pad, 2, 0) self.layout().addWidget(self.revo_subtitle_weight, 3, 0) self.layout().addWidget(self.revo_x_label_fn, 4, 0) self.layout().addWidget(self.revo_x_label_fs, 5, 0) self.layout().addWidget(self.revo_x_label_pad, 6, 0) self.layout().addWidget(self.revo_x_label_weight, 7, 0) self.layout().addWidget(self.revo_y_label_fn, 8, 0) self.layout().addWidget(self.revo_y_label_fs, 9, 0) self.layout().addWidget(self.revo_y_label_pad, 10, 0) self.layout().addWidget(self.titration_x_values, 11, 0) self.layout().addWidget(self.revo_y_label_weight, 0, 1) self.layout().addWidget(self.revo_x_ticks_fn, 1, 1) self.layout().addWidget(self.revo_x_ticks_fs, 2, 1) self.layout().addWidget(self.revo_x_ticks_pad, 3, 1) self.layout().addWidget(self.revo_x_ticks_weight, 4, 1) self.layout().addWidget(self.revo_x_ticks_rotation, 5, 1) self.layout().addWidget(self.revo_y_ticks_fn, 6, 1) self.layout().addWidget(self.revo_y_ticks_fs, 7, 1) self.layout().addWidget(self.revo_y_ticks_pad, 8, 1) self.layout().addWidget(self.revo_y_ticks_weight, 9, 1) self.layout().addWidget(self.revo_y_ticks_rot, 10, 1) self.layout().addWidget(self.do_revo_fit, 11, 1) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.RestoreDefaults) self.buttonBox.accepted.connect(self.set_values) self.buttonBox.rejected.connect(self.reject) self.buttonBox.button( QDialogButtonBox.RestoreDefaults).clicked.connect( self.get_defaults) self.layout().addWidget(self.buttonBox, 12, 0, 1, 2) self.get_values() def get_defaults(self): # checkbox self.do_revo_fit.checkBox.setChecked( self.defaults["perform_resevo_fitting"]) # dropdown list self.revo_subtitle_fn.select(self.defaults["subtitle_fn"]) self.revo_subtitle_weight.select(self.defaults["subtitle_weight"]) self.revo_x_label_fn.select(self.defaults["x_label_fn"]) self.revo_x_label_weight.select(self.defaults["x_label_weight"]) self.revo_y_label_fn.select(self.defaults["y_label_fn"]) self.revo_y_label_weight.select(self.defaults["y_label_weight"]) self.revo_x_ticks_fn.select(self.defaults["x_ticks_fn"]) self.revo_x_ticks_weight.select(self.defaults["x_ticks_weight"]) self.revo_y_ticks_fn.select(self.defaults["y_ticks_fn"]) self.revo_y_ticks_weight.select(self.defaults["y_ticks_weight"]) # value self.revo_subtitle_fs.setValue(self.defaults["subtitle_fs"]) self.revo_subtitle_pad.setValue(self.defaults["subtitle_pad"]) self.revo_x_label_fs.setValue(self.defaults["x_label_fs"]) self.revo_x_label_pad.setValue(self.defaults["x_label_pad"]) self.revo_y_label_fs.setValue(self.defaults["y_label_fs"]) self.revo_y_label_pad.setValue(self.defaults["y_label_pad"]) self.revo_x_ticks_fs.setValue(self.defaults["x_ticks_fs"]) self.revo_x_ticks_pad.setValue(self.defaults["x_ticks_pad"]) self.revo_x_ticks_rotation.setValue(self.defaults["x_ticks_rot"]) self.revo_y_ticks_fs.setValue(self.defaults["y_ticks_fs"]) self.revo_y_ticks_pad.setValue(self.defaults["y_ticks_pad"]) self.revo_y_ticks_rot.setValue(self.defaults["y_ticks_rot"]) # text self.titration_x_values.field.setText(','.join( [str(x) for x in self.defaults["titration_x_values"]])) def set_values(self): # checkbox self.local_variables[ "perform_resevo_fitting"] = self.do_revo_fit.isChecked() # text self.local_variables["subtitle_fn"] = str( self.revo_subtitle_fn.fields.currentText()) self.local_variables["subtitle_weight"] = str( self.revo_subtitle_weight.fields.currentText()) self.local_variables["x_label_fn"] = str( self.revo_x_label_fn.fields.currentText()) self.local_variables["x_label_weight"] = str( self.revo_x_label_weight.fields.currentText()) self.local_variables["y_label_fn"] = str( self.revo_y_label_fn.fields.currentText()) self.local_variables["y_label_weight"] = str( self.revo_y_label_weight.fields.currentText()) self.local_variables["x_ticks_fn"] = str( self.revo_x_ticks_fn.fields.currentText()) self.local_variables["x_ticks_weight"] = str( self.revo_x_ticks_weight.fields.currentText()) self.local_variables["y_ticks_fn"] = str( self.revo_y_ticks_fn.fields.currentText()) self.local_variables["y_ticks_weight"] = str( self.revo_y_ticks_weight.fields.currentText()) # value self.local_variables[ "subtitle_fs"] = self.revo_subtitle_fs.field.value() self.local_variables[ "subtitle_pad"] = self.revo_subtitle_pad.field.value() self.local_variables["x_label_fs"] = self.revo_x_label_fs.field.value() self.local_variables[ "x_label_pad"] = self.revo_x_label_pad.field.value() self.local_variables["y_label_fs"] = self.revo_y_label_fs.field.value() self.local_variables[ "y_label_pad"] = self.revo_y_label_pad.field.value() self.local_variables["x_ticks_fs"] = self.revo_x_ticks_fs.field.value() self.local_variables[ "x_ticks_pad"] = self.revo_x_ticks_pad.field.value() self.local_variables[ "x_ticks_rot"] = self.revo_x_ticks_rotation.field.value() self.local_variables["y_ticks_fs"] = self.revo_y_ticks_fs.field.value() self.local_variables[ "y_ticks_pad"] = self.revo_y_ticks_pad.field.value() self.local_variables[ "y_ticks_rot"] = self.revo_y_ticks_rot.field.value() # text string list self.local_variables["titration_x_values"] = \ [float(x) for x in self.titration_x_values.field.text().split(',')] self.accept() def get_values(self): # check self.do_revo_fit.setChecked( self.local_variables["perform_resevo_fitting"]) # dropdown self.revo_subtitle_fn.select(self.local_variables["subtitle_fn"]) self.revo_subtitle_weight.select( self.local_variables["subtitle_weight"]) self.revo_x_label_fn.select(self.local_variables["x_label_fn"]) self.revo_x_label_weight.select(self.local_variables["x_label_weight"]) self.revo_y_label_fn.select(self.local_variables["y_label_fn"]) self.revo_y_label_weight.select(self.local_variables["y_label_weight"]) self.revo_x_ticks_fn.select(self.local_variables["x_ticks_fn"]) self.revo_x_ticks_weight.select(self.local_variables["x_ticks_weight"]) self.revo_y_ticks_fn.select(self.local_variables["y_ticks_fn"]) self.revo_y_ticks_weight.select(self.local_variables["y_ticks_weight"]) #value self.revo_subtitle_fs.setValue(self.local_variables["subtitle_fs"]) self.revo_subtitle_pad.setValue(self.local_variables["subtitle_pad"]) self.revo_x_label_fs.setValue(self.local_variables["x_label_fs"]) self.revo_x_label_pad.setValue(self.local_variables["x_label_pad"]) self.revo_y_label_fs.setValue(self.local_variables["y_label_fs"]) self.revo_y_label_pad.setValue(self.local_variables["y_label_pad"]) self.revo_x_ticks_fs.setValue(self.local_variables["x_ticks_fs"]) self.revo_x_ticks_pad.setValue(self.local_variables["x_ticks_pad"]) self.revo_x_ticks_rotation.setValue( self.local_variables["x_ticks_rot"]) self.revo_y_ticks_fs.setValue(self.local_variables["y_ticks_fs"]) self.revo_y_ticks_pad.setValue(self.local_variables["y_ticks_pad"]) self.revo_y_ticks_rot.setValue(self.local_variables["y_ticks_rot"]) self.revo_y_ticks_rot.setValue(self.local_variables["y_ticks_rot"]) # text list string self.titration_x_values.field.setText(','.join( [str(x) for x in self.local_variables["titration_x_values"]]))
class TorrentAddingDialog(QDialog): SELECTION_LABEL_FORMAT = 'Selected {} files ({})' def __init__(self, parent: QWidget, filename: str, torrent_info: TorrentInfo, control_thread: 'ControlManagerThread'): super().__init__(parent) self.app = QApplication.instance() self._torrent_filepath = Path(filename) self._torrent_info = torrent_info download_info = torrent_info.download_info self._control_thread = control_thread self._control = control_thread.control vbox = QVBoxLayout(self) self._download_dir = self.get_directory( self._control.last_download_dir) vbox.addWidget(QLabel('Download directory:')) vbox.addWidget(self._get_directory_browse_widget()) vbox.addWidget(QLabel('Announce URLs:')) url_tree = QTreeWidget() url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) url_tree.header().close() vbox.addWidget(url_tree) for i, tier in enumerate(torrent_info.announce_list): tier_item = QTreeWidgetItem(url_tree) tier_item.setText(0, 'Tier {}'.format(i + 1)) for url in tier: url_item = QTreeWidgetItem(tier_item) url_item.setText(0, url) url_tree.expandAll() vbox.addWidget(url_tree, 1) file_tree = QTreeWidget() file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) file_tree.setHeaderLabels(('Name', 'Size')) file_tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self._file_items = [] self._traverse_file_tree(download_info.suggested_name, download_info.file_tree, file_tree) file_tree.sortItems(0, Qt.AscendingOrder) file_tree.expandAll() file_tree.itemClicked.connect(self._update_checkboxes) vbox.addWidget(file_tree, 3) self._selection_label = QLabel( TorrentAddingDialog.SELECTION_LABEL_FORMAT.format( len(download_info.files), humanize_size(download_info.total_size))) vbox.addWidget(self._selection_label) self._ipfsadd_checkbox = QCheckBox( 'Import files to IPFS when download is complete') self._ipfsadd_checkbox.setCheckState(Qt.Unchecked) # vbox.addWidget(self._ipfsadd_checkbox) self._button_box = QDialogButtonBox(self) self._button_box.setOrientation(Qt.Horizontal) self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._button_box.button(QDialogButtonBox.Ok).clicked.connect( self.submit_torrent) self._button_box.button(QDialogButtonBox.Cancel).clicked.connect( self.close) vbox.addWidget(self._button_box) self.setWindowTitle('Add Torrent') self.setMinimumSize( QSize(self.app.desktopGeometry.width() / 3, (2 * self.app.desktopGeometry.height()) / 3)) def get_directory(self, directory: Optional[str]): dlPath = Path(self.app.settingsMgr.downloadsDir) downloadsDir = dlPath.joinpath('torrent') return directory if directory is not None else str(downloadsDir) def _traverse_file_tree(self, name: str, node: FileTreeNode, parent: QWidget): item = QTreeWidgetItem(parent) item.setCheckState(0, Qt.Checked) item.setText(0, name) if isinstance(node, FileInfo): item.setText(1, humanize_size(node.length)) item.setIcon(0, getMimeIcon('unknown')) self._file_items.append((node, item)) return item.setIcon(0, getIcon('folder-open.png')) for name, child in node.items(): self._traverse_file_tree(name, child, item) def _get_directory_browse_widget(self): widget = QWidget() hbox = QHBoxLayout(widget) hbox.setContentsMargins(0, 0, 0, 0) self._path_edit = QLineEdit(self._download_dir) self._path_edit.setReadOnly(True) hbox.addWidget(self._path_edit, 3) browse_button = QPushButton('Browse...') browse_button.clicked.connect(self._browse) hbox.addWidget(browse_button, 1) widget.setLayout(hbox) return widget def _browse(self): new_download_dir = QFileDialog.getExistingDirectory( self, 'Select download directory', self._download_dir) if not new_download_dir: return self._download_dir = new_download_dir self._path_edit.setText(new_download_dir) def _set_check_state_to_tree(self, item: QTreeWidgetItem, check_state: Qt.CheckState): for i in range(item.childCount()): child = item.child(i) child.setCheckState(0, check_state) self._set_check_state_to_tree(child, check_state) def _update_checkboxes(self, item: QTreeWidgetItem, column: int): if column != 0: return new_check_state = item.checkState(0) self._set_check_state_to_tree(item, new_check_state) while True: item = item.parent() if item is None: break has_checked_children = False has_partially_checked_children = False has_unchecked_children = False for i in range(item.childCount()): state = item.child(i).checkState(0) if state == Qt.Checked: has_checked_children = True elif state == Qt.PartiallyChecked: has_partially_checked_children = True else: has_unchecked_children = True if not has_partially_checked_children and \ not has_unchecked_children: new_state = Qt.Checked elif has_checked_children or has_partially_checked_children: new_state = Qt.PartiallyChecked else: new_state = Qt.Unchecked item.setCheckState(0, new_state) self._update_selection_label() def _update_selection_label(self): selected_file_count = 0 selected_size = 0 for node, item in self._file_items: if item.checkState(0) == Qt.Checked: selected_file_count += 1 selected_size += node.length ok_button = self._button_box.button(QDialogButtonBox.Ok) if not selected_file_count: ok_button.setEnabled(False) self._selection_label.setText('Nothing to download') else: ok_button.setEnabled(True) self._selection_label.setText( TorrentAddingDialog.SELECTION_LABEL_FORMAT.format( selected_file_count, humanize_size(selected_size))) def submit_torrent(self): p = Path(self._download_dir) try: name = self._torrent_filepath.name.replace('.torrent', '') pFinal = p.joinpath(name) pFinal.mkdir(parents=True, exist_ok=True) self._torrent_info.download_dir = str(pFinal) except Exception: messageBox('Cannot create torrent destination directory') return self._control.last_download_dir = os.path.abspath(self._download_dir) file_paths = [] for node, item in self._file_items: if item.checkState(0) == Qt.Checked: file_paths.append(node.path) if not self._torrent_info.download_info.single_file_mode: self._torrent_info.download_info.select_files( file_paths, 'whitelist') if self._ipfsadd_checkbox.checkState() == Qt.Checked: log.debug('Importing torrent to IPFS when complete') self._torrent_info.ipfsImportWhenComplete = True self._control_thread.loop.call_soon_threadsafe(self._control.add, self._torrent_info) self.close()
class ArtisanDialog(QDialog): def __init__(self, parent=None, aw=None): super(ArtisanDialog, self).__init__(parent) self.aw = aw # the Artisan application window # IMPORTANT NOTE: if dialog items have to be access after it has been closed, this Qt.WA_DeleteOnClose attribute # has to be set to False explicitly in its initializer (like in comportDlg) to avoid the early GC and one might # want to use a dialog.deleteLater() call to explicitly have the dialog and its widgets GCe # or rather use sip.delete(dialog) if the GC via .deleteLater() is prevented by a link to a parent object (parent not None) self.setAttribute(Qt.WA_DeleteOnClose, True) # if platf == 'Windows': # setting those Windows flags could be the reason for some instabilities on Windows # windowFlags = self.windowFlags() # #windowFlags &= ~Qt.WindowContextHelpButtonHint # remove help button # #windowFlags &= ~Qt.WindowMaximizeButtonHint # remove maximise button # #windowFlags &= ~Qt.WindowMinMaxButtonsHint # remove min/max combo # #windowFlags |= Qt.WindowMinimizeButtonHint # Add minimize button # windowFlags |= Qt.WindowSystemMenuHint # Adds a window system menu, and possibly a close button # windowFlags |= Qt.WindowMinMaxButtonsHint # add min/max combo # self.setWindowFlags(windowFlags) # configure standard dialog buttons self.dialogbuttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal) self.dialogbuttons.button(QDialogButtonBox.Ok).setDefault(True) self.dialogbuttons.button(QDialogButtonBox.Ok).setAutoDefault(True) self.dialogbuttons.button(QDialogButtonBox.Cancel).setDefault(False) self.dialogbuttons.button( QDialogButtonBox.Cancel).setAutoDefault(False) self.dialogbuttons.button(QDialogButtonBox.Ok).setFocusPolicy( Qt.StrongFocus) # to add to tab focus switch if self.aw.locale not in self.aw.qtbase_locales: self.dialogbuttons.button(QDialogButtonBox.Ok).setText( QApplication.translate("Button", "OK", None)) self.dialogbuttons.button(QDialogButtonBox.Cancel).setText( QApplication.translate("Button", "Cancel", None)) # add additional CMD-. shortcut to close the dialog self.dialogbuttons.button(QDialogButtonBox.Cancel).setShortcut( QKeySequence("Ctrl+.")) # add additional CMD-W shortcut to close this dialog (ESC on Mac OS X) cancelAction = QAction( self, triggered=lambda _: self.dialogbuttons.rejected.emit()) try: cancelAction.setShortcut(QKeySequence.Cancel) except: pass self.dialogbuttons.button(QDialogButtonBox.Cancel).addActions( [cancelAction]) def closeEvent(self, _): self.dialogbuttons.rejected.emit() def keyPressEvent(self, event): key = int(event.key()) #uncomment next line to find the integer value of a key #print(key) #modifiers = QApplication.keyboardModifiers() modifiers = event.modifiers() if key == 16777216 or (key == 87 and modifiers == Qt.ControlModifier): #ESCAPE or CMD-W self.close()
class Dialog(QDialog): def __init__(self, mainwindow): super(Dialog, self).__init__(mainwindow) self._document = None layout = QGridLayout() self.setLayout(layout) self.versionLabel = QLabel() self.lilyChooser = lilychooser.LilyChooser() self.outputLabel = QLabel() self.outputCombo = QComboBox() self.resolutionLabel = QLabel() self.resolutionCombo = QComboBox(editable=True) self.antialiasLabel = QLabel() self.antialiasSpin = QSpinBox(minimum=1, maximum=128, value=1) self.modeLabel = QLabel() self.modeCombo = QComboBox() self.deleteCheck = QCheckBox() self.embedSourceCodeCheck = QCheckBox() self.englishCheck = QCheckBox() self.commandLineLabel = QLabel() self.commandLine = QTextEdit(acceptRichText=False) self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).setIcon( icons.get("lilypond-run")) userguide.addButton(self.buttons, "engrave_custom") self.resolutionCombo.addItems(['100', '200', '300', '600', '1200']) self.resolutionCombo.setCurrentIndex(2) self.modeCombo.addItems(['preview', 'publish', 'debug']) layout.addWidget(self.versionLabel, 0, 0) layout.addWidget(self.lilyChooser, 0, 1, 1, 3) layout.addWidget(self.outputLabel, 1, 0) layout.addWidget(self.outputCombo, 1, 1, 1, 3) layout.addWidget(self.resolutionLabel, 2, 0) layout.addWidget(self.resolutionCombo, 2, 1) layout.addWidget(self.antialiasLabel, 2, 2, Qt.AlignRight) layout.addWidget(self.antialiasSpin, 2, 3) layout.addWidget(self.modeLabel, 3, 0) layout.addWidget(self.modeCombo, 3, 1, 1, 3) layout.addWidget(self.deleteCheck, 4, 0, 1, 4) layout.addWidget(self.embedSourceCodeCheck, 5, 0, 1, 4) layout.addWidget(self.englishCheck, 6, 0, 1, 4) layout.addWidget(self.commandLineLabel, 7, 0, 1, 4) layout.addWidget(self.commandLine, 8, 0, 1, 4) layout.addWidget(widgets.Separator(), 9, 0, 1, 4) layout.addWidget(self.buttons, 10, 0, 1, 4) app.translateUI(self) qutil.saveDialogSize(self, "engrave/custom/dialog/size", QSize(480, 260)) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) model = listmodel.ListModel(formats, display=lambda f: f.title(), icon=lambda f: icons.file_type(f.type)) self.outputCombo.setModel(model) s = QSettings() s.beginGroup("lilypond_settings") self.englishCheck.setChecked(s.value("no_translation", False, bool)) self.deleteCheck.setChecked( s.value("delete_intermediate_files", True, bool)) if s.value("default_output_target", "pdf", str) == "svg": self.outputCombo.setCurrentIndex(3) app.jobFinished.connect(self.slotJobFinished) self.outputCombo.currentIndexChanged.connect(self.makeCommandLine) self.modeCombo.currentIndexChanged.connect(self.makeCommandLine) self.deleteCheck.toggled.connect(self.makeCommandLine) self.embedSourceCodeCheck.toggled.connect(self.makeCommandLine) self.resolutionCombo.editTextChanged.connect(self.makeCommandLine) self.antialiasSpin.valueChanged.connect(self.makeCommandLine) self.makeCommandLine() panelmanager.manager( mainwindow).layoutcontrol.widget().optionsChanged.connect( self.makeCommandLine) def translateUI(self): self.setWindowTitle(app.caption(_("Engrave custom"))) self.versionLabel.setText(_("LilyPond Version:")) self.outputLabel.setText(_("Output Format:")) self.resolutionLabel.setText(_("Resolution:")) self.antialiasLabel.setText(_("Antialias Factor:")) self.modeLabel.setText(_("Engraving mode:")) self.modeCombo.setItemText(0, _("Preview")) self.modeCombo.setItemText(1, _("Publish")) self.modeCombo.setItemText(2, _("Layout Control")) self.deleteCheck.setText(_("Delete intermediate output files")) self.embedSourceCodeCheck.setText( _("Embed Source Code (LilyPond >= 2.19.39)")) self.englishCheck.setText(_("Run LilyPond with English messages")) self.commandLineLabel.setText(_("Command line:")) self.buttons.button(QDialogButtonBox.Ok).setText(_("Run LilyPond")) self.outputCombo.update() def slotJobFinished(self, doc): if doc == self._document: self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) self._document = None def setDocument(self, doc): self.lilyChooser.setLilyPondInfo(command.info(doc)) job = jobmanager.job(doc) if job and job.is_running() and not jobattributes.get(job).hidden: self._document = doc self.buttons.button(QDialogButtonBox.Ok).setEnabled(False) def makeCommandLine(self): """Reads the widgets and builds a command line.""" f = formats[self.outputCombo.currentIndex()] self.resolutionCombo.setEnabled('resolution' in f.widgets) self.antialiasSpin.setEnabled('antialias' in f.widgets) cmd = ["$lilypond"] if self.modeCombo.currentIndex() == 0: # preview mode cmd.append('-dpoint-and-click') elif self.modeCombo.currentIndex() == 1: # publish mode cmd.append('-dno-point-and-click') else: # debug mode args = panelmanager.manager( self.parent()).layoutcontrol.widget().preview_options() cmd.extend(args) if self.deleteCheck.isChecked(): cmd.append('-ddelete-intermediate-files') else: cmd.append('-dno-delete-intermediate-files') if self.embedSourceCodeCheck.isChecked(): cmd.append('-dembed-source-code') d = { 'version': self.lilyChooser.lilyPondInfo().version, 'resolution': self.resolutionCombo.currentText(), 'antialias': self.antialiasSpin.value(), } cmd.append("$include") cmd.extend(f.options(d)) cmd.append("$filename") self.commandLine.setText(' '.join(cmd)) def getJob(self, document): """Returns a Job to start.""" filename, includepath = documentinfo.info(document).jobinfo(True) i = self.lilyChooser.lilyPondInfo() cmd = [] for t in self.commandLine.toPlainText().split(): if t == '$lilypond': cmd.append(i.abscommand() or i.command) elif t == '$filename': cmd.append(filename) elif t == '$include': cmd.extend('-I' + path for path in includepath) else: cmd.append(t) j = job.Job() j.directory = os.path.dirname(filename) j.command = cmd if self.englishCheck.isChecked(): j.environment['LANG'] = 'C' j.environment['LC_ALL'] = 'C' j.set_title("{0} {1} [{2}]".format(os.path.basename(i.command), i.versionString(), document.documentName())) return j def keyPressEvent(self, ev): if ev.key() == Qt.Key_Return and ev.modifiers() == Qt.ControlModifier: self.accept() else: super(Dialog, self).keyPressEvent(ev)
class PrecomputedVolumeBrowser(QDialog): def __init__(self, history=None, parent=None): super().__init__(parent) self._history = history or [] self.selected_url = None self.setup_ui() def setup_ui(self): self.setMinimumSize(800, 200) self.setWindowTitle('Precomputed Volume Selection Dialog') main_layout = QVBoxLayout() description = QLabel(self) description.setText( 'enter base URL of volume starting with "precomputed://http..."' 'hit the "check URL" button to validate the entered address.') main_layout.addWidget(description) self.combo = QComboBox(self) self.combo.setEditable(True) self.combo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) self.combo.addItem("") for item in self._history: self.combo.addItem(item) combo_label = QLabel(parent=self) combo_label.setText("Enter volume address: ") combo_layout = QHBoxLayout() chk_button = QPushButton(self) chk_button.setText('Check URL') chk_button.clicked.connect(self.handle_chk_button_clicked) combo_layout.addWidget(combo_label) combo_layout.addWidget(self.combo) combo_layout.addWidget(chk_button) main_layout.addLayout(combo_layout) # add some debug stuff debug_label = QLabel(self) debug_label.setText('debug: ') self.debug_text = QTextBrowser(self) debug_layout = QVBoxLayout() debug_layout.addWidget(debug_label) debug_layout.addWidget(self.debug_text) main_layout.addLayout(debug_layout) self.qbuttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.qbuttons.accepted.connect(self.accept) self.qbuttons.rejected.connect(self.reject) self.qbuttons.button(QDialogButtonBox.Ok).setEnabled(False) main_layout.addWidget(self.qbuttons) self.setLayout(main_layout) def handle_chk_button_clicked(self, event): self.selected_url = self.combo.currentText() logger.debug(f"selected url: {self.selected_url}") url = self.selected_url.lstrip('precomputed://') try: rv = RESTfulPrecomputedChunkedVolume(volume_url=url) except Exception as e: # :< self.qbuttons.button(QDialogButtonBox.Ok).setEnabled(False) self.debug_text.setText("") qm = QMessageBox(self) qm.setWindowTitle('An Error Occured!') qm.setText(f"woops: {e}") qm.show() return self.debug_text.setText( f"volume encoding: {rv.get_encoding()}\n" f"available scales: {rv.available_scales}\n" f"using scale: {rv._use_scale}\n" f"data shape: {rv.get_shape()}\n" ) self.qbuttons.button(QDialogButtonBox.Ok).setEnabled(True)
class Login(QDialog): def __init__(self, parent=None, email=None, remember_credentials=True): super(Login, self).__init__(parent) self.login = None self.passwd = None self.remember = remember_credentials self.linkRegister = QLabel( '<small><a href="' + config.register_url + '">' + QApplication.translate("Plus", "Register", None) + '</a></small>') self.linkRegister.setOpenExternalLinks(True) self.linkResetPassword = QLabel( '<small><a href="' + config.reset_passwd_url + '">' + QApplication.translate("Plus", "Reset Password", None) + '</a></small>') self.linkResetPassword.setOpenExternalLinks(True) self.textName = QLineEdit(self) self.textName.setPlaceholderText( QApplication.translate("Plus", "Email", None)) if email is not None: self.textName.setText(email) self.textName.textChanged.connect(self.textChanged) self.textPass = QLineEdit(self) self.textPass.setEchoMode(QLineEdit.Password) self.textPass.setPlaceholderText( QApplication.translate("Plus", "Password", None)) self.textPass.textChanged.connect(self.textChanged) self.rememberCheckbox = QCheckBox( QApplication.translate("Plus", "Remember", None)) self.rememberCheckbox.setChecked(self.remember) self.rememberCheckbox.stateChanged.connect(self.rememberCheckChanged) self.dialogbuttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal) aw = config.app_window if aw.locale not in aw.qtbase_locales: self.dialogbuttons.button(QDialogButtonBox.Ok).setText( QApplication.translate("Button", "OK", None)) self.dialogbuttons.button(QDialogButtonBox.Cancel).setText( QApplication.translate("Button", "Cancel", None)) self.dialogbuttons.accepted.connect(self.setCredentials) self.dialogbuttons.rejected.connect(self.reject) self.dialogbuttons.button(QDialogButtonBox.Ok).setEnabled(False) self.dialogbuttons.button(QDialogButtonBox.Cancel).setDefault(True) # add additional CMD-. shortcut to close the dialog self.dialogbuttons.button(QDialogButtonBox.Cancel).setShortcut( QKeySequence("Ctrl+.")) # add additional CMD-W shortcut to close this dialog cancelAction = QAction(self, triggered=lambda _: self.reject()) try: cancelAction.setShortcut(QKeySequence.Cancel) except: pass self.dialogbuttons.button(QDialogButtonBox.Cancel).addActions( [cancelAction]) credentialsLayout = QVBoxLayout(self) credentialsLayout.addWidget(self.textName) credentialsLayout.addWidget(self.textPass) credentialsLayout.addWidget(self.rememberCheckbox) credentialsGroup = QGroupBox() credentialsGroup.setLayout(credentialsLayout) buttonLayout = QHBoxLayout() buttonLayout.addStretch() buttonLayout.addWidget(self.dialogbuttons) buttonLayout.addStretch() linkLayout = QHBoxLayout() linkLayout.addStretch() linkLayout.addWidget(self.linkRegister) linkLayout.addStretch() linkLayout.addWidget(self.linkResetPassword) linkLayout.addStretch() layout = QVBoxLayout(self) layout.addWidget(credentialsGroup) layout.addLayout(linkLayout) layout.addLayout(buttonLayout) layout.setContentsMargins(10, 10, 10, 10) layout.setSpacing(5) @pyqtSlot() def reject(self): super(Login, self).reject() @pyqtSlot(int) def rememberCheckChanged(self, i): self.remember = bool(i) @pyqtSlot(str) def textChanged(self, _): login = self.textName.text() passwd = self.textPass.text() if len(passwd) >= config.min_passwd_len and len( login ) >= config.min_login_len and "@" in login and "." in login: self.dialogbuttons.button(QDialogButtonBox.Ok).setDefault(True) self.dialogbuttons.button(QDialogButtonBox.Ok).setEnabled(True) else: self.dialogbuttons.button(QDialogButtonBox.Cancel).setDefault(True) self.dialogbuttons.button(QDialogButtonBox.Ok).setEnabled(False) @pyqtSlot() def setCredentials(self): self.login = self.textName.text() self.passwd = self.textPass.text() self.accept()
def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) self.__committimer = QTimer(self, singleShot=True) self.__committimer.timeout.connect(self.commit) self.__executor = qconcurrent.ThreadExecutor() self.__watcher = None # type: Optional[qconcurrent.FutureWatcher] self.controlArea.layout().setSpacing(-1) # reset spacing grid = QGridLayout() grid.addWidget(QLabel("File:", self), 0, 0, 1, 1) self.import_items_model = QStandardItemModel(self) self.recent_combo = QComboBox( self, objectName="recent-combo", toolTip="Recent files.", sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, minimumContentsLength=16, ) self.recent_combo.setModel(self.import_items_model) self.recent_combo.activated.connect(self.activate_recent) self.recent_combo.setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.browse_button = QPushButton( "…", icon=self.style().standardIcon(QStyle.SP_DirOpenIcon), toolTip="Browse filesystem", autoDefault=False, ) self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.browse_button.clicked.connect(self.browse) grid.addWidget(self.recent_combo, 0, 1, 1, 1) grid.addWidget(self.browse_button, 0, 2, 1, 1) self.controlArea.layout().addLayout(grid) ########### # Info text ########### box = gui.widgetBox(self.controlArea, "Info", addSpace=False) self.summary_text = QTextBrowser( verticalScrollBarPolicy=Qt.ScrollBarAsNeeded, readOnly=True, ) self.summary_text.viewport().setBackgroundRole(QPalette.NoRole) self.summary_text.setFrameStyle(QTextBrowser.NoFrame) self.summary_text.setMinimumHeight(self.fontMetrics().ascent() * 2 + 4) self.summary_text.viewport().setAutoFillBackground(False) box.layout().addWidget(self.summary_text) button_box = QDialogButtonBox( orientation=Qt.Horizontal, standardButtons=QDialogButtonBox.Cancel | QDialogButtonBox.Retry ) self.load_button = b = button_box.button(QDialogButtonBox.Retry) b.setText("Load") b.clicked.connect(self.__committimer.start) b.setEnabled(False) b.setDefault(True) self.cancel_button = b = button_box.button(QDialogButtonBox.Cancel) b.clicked.connect(self.cancel) b.setEnabled(False) b.setAutoDefault(False) self.import_options_button = QPushButton( "Import Options…", enabled=False, autoDefault=False, clicked=self._activate_import_dialog ) self.recent_combo.currentIndexChanged.connect( lambda idx: self.import_options_button.setEnabled(idx != -1) or self.load_button.setEnabled(idx != -1) ) button_box.addButton( self.import_options_button, QDialogButtonBox.ActionRole ) button_box.setStyleSheet( "button-layout: {:d};".format(QDialogButtonBox.MacLayout) ) self.controlArea.layout().addWidget(button_box) self._restoreState() if self.current_item() is not None: self._invalidate() self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
class RenameForm(QDialog): """ This class implements the form used to rename nodes during refactor operations. """ def __init__(self, node, parent=None): """ Initialize the form dialog. :type node: AbstractNode :type parent: QWidget """ super().__init__(parent) self.node = node self.renameField = StringField(self) self.renameField.setFixedWidth(200) self.renameField.setValue(self.node.text()) self.invalidName = QLabel('\'\' is not a valid predicate name', self) self.invalidName.setProperty('class', 'invalid') self.invalidName.setVisible(False) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.mainLayout = QFormLayout(self) self.mainLayout.addRow('Name', self.renameField) self.mainLayout.addRow(self.invalidName) self.mainLayout.addRow(self.buttonBox) self.setWindowTitle('Rename') self.setWindowIcon(QIcon(':/images/eddy')) self.setFixedSize(self.sizeHint()) connect(self.buttonBox.accepted, self.validate) connect(self.buttonBox.rejected, self.reject) connect(self.renameField.textChanged, self.nameChanged) #################################################################################################################### # # # SLOTS # # # #################################################################################################################### @pyqtSlot() def nameChanged(self): """ Executed whenever the text in the rename field changes. """ button = self.buttonBox.button(QDialogButtonBox.Ok) empty = isEmpty(self.renameField.value()) button.setDisabled(empty) self.invalidName.setVisible(empty) self.setFixedSize(self.sizeHint()) @pyqtSlot() def validate(self): """ Validate the form and trigger accept() if the form is valid. """ if isEmpty(self.renameField.value()): msgbox = QMessageBox(self) msgbox.setIconPixmap(QPixmap(':/icons/warning')) msgbox.setWindowIcon(QIcon(':/images/eddy')) msgbox.setWindowTitle('Invalid predicate') msgbox.setText('You specified an invalid predicate name!') msgbox.setStandardButtons(QMessageBox.Ok) msgbox.exec_() return # This will strip out leading/trailing whitespaces. self.renameField.setValue(self.renameField.value()) self.accept()
def initUI(self): self.setWindowTitle("设置") logo = QLabel() # logo logo.setPixmap(QPixmap("./src/logo2.gif")) logo.setStyleSheet("background-color:rgb(255,255,255);") logo.setAlignment(Qt.AlignCenter) self.download_threads_lb = QLabel("同时下载文件数") # about self.download_threads_var = QLineEdit() self.download_threads_var.setPlaceholderText("范围:1-9") self.download_threads_var.setToolTip("范围:1-9") self.download_threads_var.setInputMask("D") self.max_size_lb = QLabel("分卷大小(MB)") self.max_size_var = QLineEdit() self.max_size_var.setPlaceholderText("普通用户最大100,vip用户根据具体情况设置") self.max_size_var.setToolTip("普通用户最大100,vip用户根据具体情况设置") self.max_size_var.setInputMask("D99") self.timeout_lb = QLabel("请求超时(秒)") self.timeout_var = QLineEdit() self.timeout_var.setPlaceholderText("范围:1-99") self.timeout_var.setToolTip("范围:1-99") self.timeout_var.setInputMask("D9") self.upload_delay_lb = QLabel("上传延时(秒)") self.upload_delay_var = QLineEdit() self.upload_delay_var.setPlaceholderText("范围:1-99") self.upload_delay_var.setToolTip("范围:1-99") self.upload_delay_var.setInputMask("D9") self.dl_path_lb = QLabel("下载保存路径") self.dl_path_var = MyLineEdit(self) self.dl_path_var.clicked.connect(self.set_download_path) self.time_fmt_box = QCheckBox("使用[年-月-日]时间格式") self.to_tray_box = QCheckBox("关闭到系统托盘") self.watch_clipboard_box = QCheckBox("监听系统剪切板") self.debug_box = QCheckBox("开启调试日志") self.set_pwd_box = QCheckBox("上传文件自动设置密码") self.set_pwd_var = AutoResizingTextEdit() self.set_pwd_var.setPlaceholderText(" 2-8 位数字或字母") self.set_pwd_var.setToolTip("2-8 位数字或字母") self.set_desc_box = QCheckBox("上传文件自动设置描述") self.set_desc_var = AutoResizingTextEdit() self.big_file_box = QCheckBox(f"允许上传超过 {self.max_size}MB 的大文件") self.time_fmt_box.toggle() self.time_fmt_box.stateChanged.connect(self.change_time_fmt) self.to_tray_box.stateChanged.connect(self.change_to_tray) self.watch_clipboard_box.stateChanged.connect( self.change_watch_clipboard) self.debug_box.stateChanged.connect(self.change_debug) self.set_pwd_box.stateChanged.connect(self.change_set_pwd) self.set_pwd_var.editingFinished.connect(self.check_pwd) self.set_desc_box.stateChanged.connect(self.change_set_desc) self.big_file_box.stateChanged.connect(self.change_big_file) buttonBox = QDialogButtonBox() buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Reset | QDialogButtonBox.Save | QDialogButtonBox.Cancel) buttonBox.button(QDialogButtonBox.Reset).setText("重置") buttonBox.button(QDialogButtonBox.Save).setText("保存") buttonBox.button(QDialogButtonBox.Cancel).setText("取消") buttonBox.button(QDialogButtonBox.Reset).clicked.connect( lambda: self.set_values(reset=True)) buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.slot_save) buttonBox.rejected.connect(self.reject) form = QFormLayout() form.setLabelAlignment(Qt.AlignRight) form.setSpacing(10) form.addRow(self.download_threads_lb, self.download_threads_var) form.addRow(self.timeout_lb, self.timeout_var) form.addRow(self.upload_delay_lb, self.upload_delay_var) form.addRow(self.max_size_lb, self.max_size_var) form.addRow(self.dl_path_lb, self.dl_path_var) vbox = QVBoxLayout() vbox.addWidget(logo) vbox.addStretch(1) vbox.addLayout(form) vbox.addStretch(1) hbox = QHBoxLayout() hbox.addWidget(self.time_fmt_box) hbox.addWidget(self.to_tray_box) hbox.addWidget(self.watch_clipboard_box) hbox.addWidget(self.debug_box) vbox.addLayout(hbox) vbox.addStretch(1) hbox_2 = QHBoxLayout() hbox_2.addWidget(self.set_pwd_box) hbox_2.addWidget(self.set_pwd_var) vbox.addLayout(hbox_2) vbox.addStretch(1) hbox_3 = QHBoxLayout() hbox_3.addWidget(self.set_desc_box) hbox_3.addWidget(self.set_desc_var) vbox.addLayout(hbox_3) vbox.addWidget(self.big_file_box) vbox.addStretch(2) vbox.addWidget(buttonBox) self.setLayout(vbox) self.setMinimumWidth(500)
def __init__(self, widget, name, text=""): super(Edit, self).__init__(widget) self._name = name layout = QVBoxLayout() self.setLayout(layout) self.topLabel = QLabel() self.text = QTextEdit(cursorWidth=2, acceptRichText=False) self.titleLabel = QLabel() self.titleEntry = QLineEdit() self.shortcutLabel = QLabel() self.shortcutButton = ShortcutButton(clicked=self.editShortcuts) layout.addWidget(self.topLabel) layout.addWidget(self.text) grid = QGridLayout() layout.addLayout(grid) grid.addWidget(self.titleLabel, 0, 0) grid.addWidget(self.titleEntry, 0, 1) grid.addWidget(self.shortcutLabel, 1, 0) grid.addWidget(self.shortcutButton, 1, 1) layout.addWidget(widgets.Separator()) b = QDialogButtonBox(accepted=self.accept, rejected=self.reject) layout.addWidget(b) buttons = QDialogButtonBox.Ok | QDialogButtonBox.Cancel if name and name in builtin.builtin_snippets: b.setStandardButtons(buttons | QDialogButtonBox.RestoreDefaults) b.button(QDialogButtonBox.RestoreDefaults).clicked.connect(self.slotDefaults) else: b.setStandardButtons(buttons) userguide.addButton(b, "snippet_editor") # PyQt5.10 en sip4.14.5 delete the Highlighter, even though it is # constructed with a parent, that's why we save it in an unused attribute. self._highlighter = highlight.Highlighter(self.text.document()) Matcher(self.text) gadgets.indenter.Indenter(self.text) self.text.installEventFilter(cursorkeys.handler) wordboundary.handler.install_textedit(self.text) completer.Completer(self.text) if name: self.titleEntry.setText(snippets.title(name, False) or '') self.text.setPlainText(snippets.text(name)) ac = self.parent().parent().snippetActions self.setShortcuts(ac.shortcuts(name)) else: self.text.setPlainText(text) self.setShortcuts(None) app.translateUI(self) self.readSettings() app.settingsChanged.connect(self.readSettings) qutil.saveDialogSize(self, "snippettool/editor/size", QSize(400, 300)) self.show()
class UploadDialog(QDialog): """文件上传对话框""" new_infos = pyqtSignal(object) def __init__(self): super().__init__() self.cwd = os.getcwd() self._folder_id = -1 self._folder_name = "LanZouCloud" self.set_pwd = False self.set_desc = False self.pwd = '' self.desc = '' self.allow_big_file = False self.max_size = 100 self.selected = [] self.initUI() self.set_size() self.setStyleSheet(dialog_qss_style) def set_pwd_desc_bigfile(self, set_pwd, pwd, set_desc, desc, allow_big_file, max_size): self.set_pwd = set_pwd self.set_desc = set_desc self.pwd = pwd self.desc = desc self.allow_big_file = allow_big_file self.max_size = max_size if self.allow_big_file: self.btn_chooseMultiFile.setToolTip("") else: self.btn_chooseMultiFile.setToolTip(f"文件大小上线 {self.max_size}MB") def set_values(self, folder_name, folder_id, files): self.setWindowTitle("上传文件至 ➩ " + str(folder_name)) self._folder_id = folder_id self._folder_name = folder_name if files: self.selected = files self.show_selected() self.exec() def initUI(self): self.setWindowTitle("上传文件") self.setWindowIcon(QIcon("./src/upload.ico")) self.logo = QLabel() self.logo.setPixmap(QPixmap("./src/logo3.gif")) self.logo.setStyleSheet("background-color:rgb(0,153,255);") self.logo.setAlignment(Qt.AlignCenter) # btn 1 self.btn_chooseDir = QPushButton("选择文件夹", self) self.btn_chooseDir.setObjectName("btn_chooseDir") self.btn_chooseDir.setObjectName("btn_chooseDir") self.btn_chooseDir.setIcon(QIcon("./src/folder.gif")) # btn 2 self.btn_chooseMultiFile = QPushButton("选择多文件", self) self.btn_chooseDir.setObjectName("btn_chooseMultiFile") self.btn_chooseMultiFile.setObjectName("btn_chooseMultiFile") self.btn_chooseMultiFile.setIcon(QIcon("./src/file.ico")) # btn 3 self.btn_deleteSelect = QPushButton("移除", self) self.btn_deleteSelect.setObjectName("btn_deleteSelect") self.btn_deleteSelect.setIcon(QIcon("./src/delete.ico")) self.btn_deleteSelect.setToolTip("按 Delete 移除选中文件") # 列表 self.list_view = MyListView() self.list_view.drop_files.connect(self.add_drop_files) self.list_view.setViewMode(QListView.ListMode) self.slm = QStandardItem() self.model = QStandardItemModel() self.list_view.setModel(self.model) self.model.removeRows(0, self.model.rowCount()) # 清除旧的选择 self.list_view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.list_view.setSelectionBehavior(QAbstractItemView.SelectRows) self.list_view.setSelectionMode(QAbstractItemView.ExtendedSelection) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setText("确定") self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消") vbox = QVBoxLayout() hbox_head = QHBoxLayout() hbox_button = QHBoxLayout() hbox_head.addWidget(self.btn_chooseDir) hbox_head.addStretch(1) hbox_head.addWidget(self.btn_chooseMultiFile) hbox_button.addWidget(self.btn_deleteSelect) hbox_button.addStretch(1) hbox_button.addWidget(self.buttonBox) vbox.addWidget(self.logo) vbox.addLayout(hbox_head) vbox.addWidget(self.list_view) vbox.addLayout(hbox_button) self.setLayout(vbox) self.setMinimumWidth(350) # 设置信号 self.btn_chooseDir.clicked.connect(self.slot_btn_chooseDir) self.btn_chooseMultiFile.clicked.connect(self.slot_btn_chooseMultiFile) self.btn_deleteSelect.clicked.connect(self.slot_btn_deleteSelect) self.buttonBox.accepted.connect(self.slot_btn_ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.clear_old) self.buttonBox.rejected.connect(self.reject) def set_size(self): if self.selected: h = 18 if len(self.selected) > 18 else 10 w = 40 for i in self.selected: i_len = len(i) if i_len > 100: w = 100 break if i_len > w: w = i_len self.resize(120 + w * 7, h * 30) else: self.resize(400, 300) def clear_old(self): self.selected = [] self.model.removeRows(0, self.model.rowCount()) self.set_size() def show_selected(self): self.model.removeRows(0, self.model.rowCount()) for item in self.selected: if os.path.isfile(item): self.model.appendRow( QStandardItem(QIcon("./src/file.ico"), item)) else: self.model.appendRow( QStandardItem(QIcon("./src/folder.gif"), item)) self.set_size() def backslash(self): """Windows backslash""" tasks = {} for item in self.selected: furl = os.path.normpath(item) tasks[furl] = UpJob(furl=furl, id=self._folder_id, folder=self._folder_name, set_pwd=self.set_pwd, pwd=self.pwd, set_desc=self.set_desc, desc=self.desc) return tasks def slot_btn_ok(self): tasks = self.backslash() if self.selected: self.new_infos.emit(tasks) self.clear_old() def slot_btn_deleteSelect(self): _indexes = self.list_view.selectionModel().selection().indexes() if not _indexes: return indexes = [] for i in _indexes: # 获取所选行号 indexes.append(i.row()) indexes = set(indexes) for i in sorted(indexes, reverse=True): self.selected.remove(self.model.item(i, 0).text()) self.model.removeRow(i) self.set_size() def add_drop_files(self, files): for item in files: if item not in self.selected: self.selected.append(item) self.show_selected() def slot_btn_chooseDir(self): dir_choose = QFileDialog.getExistingDirectory(self, "选择文件夹", self.cwd) # 起始路径 if dir_choose == "": return if dir_choose not in self.selected: self.selected.append(dir_choose) self.show_selected() def slot_btn_chooseMultiFile(self): files, _ = QFileDialog.getOpenFileNames(self, "选择多文件", self.cwd, "All Files (*)") if len(files) == 0: return for _file in files: if _file not in self.selected: if os.path.getsize(_file) <= self.max_size * 1048576: self.selected.append(_file) elif self.allow_big_file: self.selected.append(_file) self.show_selected() def keyPressEvent(self, e): if e.key() == Qt.Key_Delete: # delete self.slot_btn_deleteSelect()
class OWLTranslationForm(QDialog): """ This class implements the form used to perform Graphol -> OWL ontology translation. """ def __init__(self, scene, filepath, parent=None): """ Initialize the form dialog. :type scene: DiagramScene :type filepath: str :type parent: QWidget """ super().__init__(parent) self.scene = scene self.filepath = filepath self.worker = None self.workerThread = None self.iriField = StringField(self) self.iriField.setFixedWidth(300) self.iriField.setValidator(QRegExpValidator(QRegExp('[\w:\/\[\]=?%#~\.\-\+]*'), self)) self.prefixField = StringField(self) self.prefixField.setFixedWidth(300) self.prefixField.setValidator(QRegExpValidator(QRegExp('[\w]*'), self)) self.syntaxField = ComboBox(self) for syntax in OWLSyntax: self.syntaxField.addItem(syntax.value, syntax) self.syntaxField.setCurrentIndex(0) self.progressBar = QProgressBar(self) self.progressBar.setAlignment(Qt.AlignHCenter) self.progressBar.setRange(0, 100) self.progressBar.setValue(0) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) self.buttonBox.button(QDialogButtonBox.Ok).setDisabled(True) self.mainLayout = QFormLayout(self) self.mainLayout.addRow('IRI', self.iriField) self.mainLayout.addRow('Prefix', self.prefixField) self.mainLayout.addRow('Syntax', self.syntaxField) self.mainLayout.addRow(self.progressBar) self.mainLayout.addRow(self.buttonBox) self.setWindowTitle('OWL Translation') self.setWindowIcon(QIcon(':/images/eddy')) self.setFixedSize(self.sizeHint()) connect(self.buttonBox.accepted, self.run) connect(self.buttonBox.rejected, self.reject) connect(self.iriField.textChanged, self.iriChanged) #################################################################################################################### # # # SLOTS # # # #################################################################################################################### @pyqtSlot(Exception) def errored(self, exception): """ Executed whenever the translation errors. :type exception: Exception """ if isinstance(exception, MalformedDiagramError): msgbox = QMessageBox(self) msgbox.setIconPixmap(QPixmap(':/icons/warning')) msgbox.setWindowIcon(QIcon(':/images/eddy')) msgbox.setWindowTitle('Malformed Diagram') msgbox.setText('Malformed expression detected on {}: {}'.format(exception.item, exception)) msgbox.setInformativeText('Do you want to see the error in the diagram?') msgbox.setStandardButtons(QMessageBox.Yes|QMessageBox.No) S = QSpacerItem(400, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) L = msgbox.layout() L.addItem(S, L.rowCount(), 0, 1, L.columnCount()) msgbox.exec_() if msgbox.result() == QMessageBox.Yes: for view in self.scene.views(): if isinstance(view, MainView): view.centerOn(exception.item) else: msgbox = QMessageBox(self) msgbox.setIconPixmap(QPixmap(':/icons/error')) msgbox.setWindowIcon(QIcon(':/images/eddy')) msgbox.setWindowTitle('Unhandled exception!') msgbox.setStandardButtons(QMessageBox.Close) msgbox.setText('Diagram translation could not be completed!') msgbox.setInformativeText('Please <a href="{}">submit a bug report</a> with detailed information.'.format(BUG_TRACKER)) msgbox.setDetailedText(''.join(traceback.format_exception(type(exception), exception, exception.__traceback__))) S = QSpacerItem(400, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) L = msgbox.layout() L.addItem(S, L.rowCount(), 0, 1, L.columnCount()) msgbox.exec_() self.workerThread.quit() self.reject() @pyqtSlot() def completed(self): """ Executed whenever the translation completes. """ self.workerThread.quit() file = File(path=self.filepath) file.write(string=self.worker.export(syntax=self.syntaxField.currentData())) msgbox = QMessageBox(self) msgbox.setIconPixmap(QPixmap(':/icons/info')) msgbox.setWindowIcon(QIcon(':/images/eddy')) msgbox.setText('Translation completed!') msgbox.setInformativeText('Do you want to open the OWL ontology?') msgbox.setStandardButtons(QMessageBox.Yes|QMessageBox.No) S = QSpacerItem(400, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) L = msgbox.layout() L.addItem(S, L.rowCount(), 0, 1, L.columnCount()) msgbox.exec_() if msgbox.result() == QMessageBox.Yes: openPath(self.filepath) self.accept() @pyqtSlot(int, int) def progress(self, current, total): """ Update the progress bar showing the translation advancement. :type current: int :type total: int """ self.progressBar.setRange(0, total) self.progressBar.setValue(current) @pyqtSlot() def iriChanged(self): """ Executed whenever the value of the prefix field changes. """ button = self.buttonBox.button(QDialogButtonBox.Ok) button.setEnabled(not isEmpty(self.iriField.value())) @pyqtSlot() def run(self): """ Perform the Graphol -> OWL translation in a separate thread. """ ontoIRI = self.iriField.value() ontoPrefix = self.prefixField.value() self.buttonBox.setEnabled(False) self.syntaxField.setEnabled(False) if not ontoIRI.endswith('#'): ontoIRI = '{0}#'.format(ontoIRI) self.workerThread = QThread() self.worker = OWLExporter(scene=self.scene, ontoIRI=ontoIRI, ontoPrefix=ontoPrefix) self.worker.moveToThread(self.workerThread) connect(self.worker.completed, self.completed) connect(self.worker.errored, self.errored) connect(self.worker.progress, self.progress) connect(self.workerThread.started, self.worker.work) self.workerThread.start()
class TorrentCreatingDialog(QDialog): SELECTION_LABEL_FORMAT = 'Selected {} files ({})' def _get_directory_browse_widget(self): widget = QWidget() hbox = QHBoxLayout(widget) hbox.setContentsMargins(0, 0, 0, 0) self._path_edit = QLineEdit(self) self._path_edit.setReadOnly(True) hbox.addWidget(self._path_edit, 4) browse_button = QPushButton('Browse...') browse_button.clicked.connect(self._browse) hbox.addWidget(browse_button, 1) widget.setLayout(hbox) return widget def _browse(self): new_download_dir = QFileDialog.getExistingDirectory( self, 'Select download directory', self.path) if not new_download_dir: return self._download_dir = new_download_dir self._path_edit.setText(new_download_dir) def __init__(self, parent: QWidget, path): super().__init__(parent) # download_info = torrent_info.download_info vbox = QVBoxLayout(self) vbox.addWidget(QLabel('Path to file:')) vbox.addWidget(self._get_directory_browse_widget()) vbox.addWidget(QLabel('Tracker:')) self._path_edit = QLineEdit(self) self._path_edit.setReadOnly(False) vbox.addWidget(self._path_edit, 4) self._button_box = QDialogButtonBox(self) self._button_box.setOrientation(Qt.Horizontal) self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._button_box.button(QDialogButtonBox.Ok).clicked.connect( self.submit_torrent) self._button_box.button(QDialogButtonBox.Cancel).clicked.connect( self.close) vbox.addWidget(self._button_box) # self.setFixedSize(250, 200) self.setWindowTitle('Create torrent') self.path = path def _set_check_state_to_tree(self, item: QTreeWidgetItem, check_state: Qt.CheckState): for i in range(item.childCount()): child = item.child(i) child.setCheckState(0, check_state) self._set_check_state_to_tree(child, check_state) def _update_checkboxes(self, item: QTreeWidgetItem, column: int): if column != 0: return new_check_state = item.checkState(0) self._set_check_state_to_tree(item, new_check_state) while True: item = item.parent() if item is None: break has_checked_children = False has_partially_checked_children = False has_unchecked_children = False for i in range(item.childCount()): state = item.child(i).checkState(0) if state == Qt.Checked: has_checked_children = True elif state == Qt.PartiallyChecked: has_partially_checked_children = True else: has_unchecked_children = True if not has_partially_checked_children and not has_unchecked_children: new_state = Qt.Checked elif has_checked_children or has_partially_checked_children: new_state = Qt.PartiallyChecked else: new_state = Qt.Unchecked item.setCheckState(0, new_state) self._update_selection_label() def _update_selection_label(self): selected_file_count = 0 selected_size = 0 for node, item in self._file_items: if item.checkState(0) == Qt.Checked: selected_file_count += 1 selected_size += node.length ok_button = self._button_box.button(QDialogButtonBox.Ok) if not selected_file_count: ok_button.setEnabled(False) self._selection_label.setText('Nothing to download') else: ok_button.setEnabled(True) # self._selection_label.setText(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format( # selected_file_count, humanize_size(selected_size))) def submit_torrent(self): # self._torrent_info.download_dir = self._download_dir # self._control.last_download_dir = os.path.abspath(self._download_dir) # # file_paths = [] # for node, item in self._file_items: # if item.checkState(0) == Qt.Checked: # file_paths.append(node.path) # if not self._torrent_info.download_info.single_file_mode: # self._torrent_info.download_info.select_files(file_paths, 'whitelist') # # self._control_thread.loop.call_soon_threadsafe(self._control.add, self._torrent_info) # # self.close() pass
class PreferencesDialog(QDialog): def __init__(self): super().__init__() self.setWindowTitle('Preferences') self.windows_size_lineedit = QLineEdit() self.windows_size_lineedit.setFixedWidth(_LINEEDIT_WIDTH) self.windows_size_lineedit.setValidator(QDoubleValidator()) self.windows_size_lineedit.setAlignment(Qt.AlignRight) self.overlap_factor_lineedit = QLineEdit() self.overlap_factor_lineedit.setFixedWidth(_LINEEDIT_WIDTH) self.overlap_factor_lineedit.setValidator(QDoubleValidator()) self.overlap_factor_lineedit.setAlignment(Qt.AlignRight) buttons = QDialogButtonBox.RestoreDefaults | QDialogButtonBox.Ok | QDialogButtonBox.Cancel self.button_box = QDialogButtonBox(buttons) self.button_box.rejected.connect(self.reject) self.button_box.accepted.connect(self.accept) self.button_box.button( QDialogButtonBox.RestoreDefaults).clicked.connect( self.restore_defaults) self.distance_setting = AxisSettings('mm') self.force_setting = AxisSettings('N') self.density_setting = AxisSettings('kg/m<sup>3</sup>') self.ssa_setting = AxisSettings('m<sup>2</sup>/m<sup>3</sup>') self.setMinimumWidth(500) self.init_ui() def init_ui(self): layout = QFormLayout() layout.setHorizontalSpacing(20) content_layout = QHBoxLayout() content_layout.addWidget(self.windows_size_lineedit) content_layout.addWidget(QLabel('mm')) layout.addRow('Window Size', content_layout) content_layout = QHBoxLayout() content_layout.addWidget(self.overlap_factor_lineedit) content_layout.addWidget(QLabel('%')) layout.addRow('Overlap Factor', content_layout) derivations_box = QGroupBox('Derivatives') derivations_box.setLayout(layout) layout = QFormLayout() layout.setVerticalSpacing(0) layout.setHorizontalSpacing(20) setting = self.distance_setting layout.addRow('Distance Axis', setting.upper_layout) layout.addRow('', setting.lower_layout) setting.lower_layout.setContentsMargins(0, 0, 0, _GAP) setting = self.force_setting layout.addRow('Force Axis', setting.upper_layout) layout.addRow('', setting.lower_layout) setting.lower_layout.setContentsMargins(0, 0, 0, _GAP) setting = self.density_setting layout.addRow('Density Axis', setting.upper_layout) layout.addRow('', setting.lower_layout) setting.lower_layout.setContentsMargins(0, 0, 0, _GAP) setting = self.ssa_setting layout.addRow('SSA Axis', setting.upper_layout) layout.addRow('', setting.lower_layout) axes_box = QGroupBox('Plot Axes') axes_box.setLayout(layout) layout = QVBoxLayout() layout.addWidget(derivations_box) layout.addWidget(axes_box) layout.addWidget(self.button_box) self.setLayout(layout) def modifyPreferences(self, preferences): self._set_values(preferences) result = self.exec() if result == QDialog.Accepted: preferences.window_size = float(self.windows_size_lineedit.text()) preferences.overlap = float(self.overlap_factor_lineedit.text()) preferences.distance_axis_fix = self.distance_setting.fix_enabled preferences.distance_axis_from = self.distance_setting.from_value preferences.distance_axis_to = self.distance_setting.to_value preferences.force_axis_fix = self.force_setting.fix_enabled preferences.force_axis_from = self.force_setting.from_value preferences.force_axis_to = self.force_setting.to_value preferences.density_axis_fix = self.density_setting.fix_enabled preferences.density_axis_from = self.density_setting.from_value preferences.density_axis_to = self.density_setting.to_value preferences.ssa_axis_fix = self.ssa_setting.fix_enabled preferences.ssa_axis_from = self.ssa_setting.from_value preferences.ssa_axis_to = self.ssa_setting.to_value return True return False def _set_values(self, prefs): self.windows_size_lineedit.setText(str(prefs.window_size)) self.overlap_factor_lineedit.setText(str(prefs.overlap)) self.distance_setting.set_values(prefs.distance_axis_fix, prefs.distance_axis_from, prefs.distance_axis_to) self.force_setting.set_values(prefs.force_axis_fix, prefs.force_axis_from, prefs.force_axis_to) self.density_setting.set_values(prefs.density_axis_fix, prefs.density_axis_from, prefs.density_axis_to) self.ssa_setting.set_values(prefs.ssa_axis_fix, prefs.ssa_axis_from, prefs.ssa_axis_to) def restore_defaults(self): defaults = Preferences() self._set_values(defaults)
class NewVersionCheckDialog(QDialog): """ Dialog that shows to the user that the program is either checking for a new version or the results of such a check. The idea is to not create a temporary dialog to show it is checking and then another to show the results. As such, it has different states. Each state is associated with different buttons and a different message. """ def __init__(self, parent) -> None: super().__init__(parent) self.rapidApp = parent # type: 'RapidWindow' self.setModal(True) self.setSizeGripEnabled(False) self.dialog_detailed_result = None self.current_state = CheckNewVersionDialogState.check self.checkingLabel = QLabel(_("Checking for new version...")) self.noNewVersion = QLabel(_("You are running the latest version.")) self.failedToCheck = QLabel(_("Failed to contact the update server.")) self.url = "http://www.damonlynch.net/rapid/download.html" self.new_version_message = _( "A new version of Rapid Photo Downloader (%s) is available.") self.new_version_message = "<b>{}</b>".format(self.new_version_message) self.download_it = _( "Do you want to download the new version?") + "<br>" self.changelog_msg = _( 'Changes in the new release can be viewed <a href="%s">here</a>.') for label in (self.checkingLabel, self.noNewVersion, self.failedToCheck): label.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.newVersion = QLabel( self._makeDownloadMsg("1.2.3a10", offer_download=True, changelog_url="")) self.newVersion.setOpenExternalLinks(True) self.changelog = QLabel(self.changelog_msg) self.changelog.setOpenExternalLinks(True) self.messages = QStackedWidget() self.messages.addWidget(self.checkingLabel) self.messages.addWidget(self.noNewVersion) self.messages.addWidget(self.newVersion) self.messages.addWidget(self.failedToCheck) cancelBox = QDialogButtonBox(QDialogButtonBox.Cancel) translateDialogBoxButtons(cancelBox) cancelBox.rejected.connect(self.reject) self.downloadItBox = QDialogButtonBox(QDialogButtonBox.Yes | QDialogButtonBox.No) translateDialogBoxButtons(self.downloadItBox) # Translators: this text appears in a button - the & sets the s key in # combination with the alt key to act as the keyboard shortcut self.dlItSkipButton = QPushButton(_("&Skip this release")) self.dlItSkipButton.setDefault(False) self.downloadItBox.addButton(self.dlItSkipButton, QDialogButtonBox.RejectRole) self.dlItYesButton = self.downloadItBox.button( QDialogButtonBox.Yes) # type: QPushButton self.dlItNoButton = self.downloadItBox.button( QDialogButtonBox.No) # type: QPushButton self.downloadItBox.clicked.connect(self.downloadItClicked) closeBox = QDialogButtonBox(QDialogButtonBox.Close) translateDialogBoxButtons(closeBox) closeBox.rejected.connect(self.reject) openDownloadPageBox = QDialogButtonBox(QDialogButtonBox.Close) translateDialogBoxButtons(openDownloadPageBox) # Translators: this text appears in a button - the & sets the s key in # combination with the alt key to act as the keyboard shortcut self.openDlPageSkipButton = QPushButton(_("&Skip this release")) # Translators: this text appears in a button - the & sets the o key in # combination with the alt key to act as the keyboard shortcut self.openDlPageButton = QPushButton(_("&Open Download Page")) self.openDlPageButton.setDefault(True) openDownloadPageBox.addButton(self.openDlPageSkipButton, QDialogButtonBox.RejectRole) openDownloadPageBox.addButton(self.openDlPageButton, QDialogButtonBox.ActionRole) self.openDlCloseButton = openDownloadPageBox.button( QDialogButtonBox.Close) openDownloadPageBox.clicked.connect(self.openWebsiteClicked) self.buttons = QStackedWidget() self.buttons.addWidget(cancelBox) self.buttons.addWidget(closeBox) self.buttons.addWidget(self.downloadItBox) self.buttons.addWidget(openDownloadPageBox) self.messages.setCurrentIndex(0) self.buttons.setCurrentIndex(0) grid = QGridLayout() grid.addWidget(self.messages, 0, 0, 1, 2, Qt.AlignTop) grid.addWidget(self.buttons, 1, 0, 1, 2) self.setLayout(grid) self.setWindowTitle(_("Rapid Photo Downloader updates")) def _makeDownloadMsg(self, new_version_number: str, offer_download: bool, changelog_url: str) -> str: s1 = self.new_version_message % new_version_number s2 = self.changelog_msg % changelog_url s = "{}<br><br>{}".format(s1, s2) if offer_download: return "<br><br>".join((s, self.download_it)) else: return s def displayUserMessage( self, new_state: CheckNewVersionDialogState, version: Optional[str] = None, download_page: Optional[str] = None, changelog_url: Optional[str] = None, ) -> None: self.current_state = new_state if new_state == CheckNewVersionDialogState.check: self.messages.setCurrentIndex(0) self.buttons.setCurrentIndex(0) elif new_state == CheckNewVersionDialogState.failed_to_contact: self.messages.setCurrentIndex(3) self.buttons.setCurrentIndex(1) elif new_state == CheckNewVersionDialogState.have_latest_version: self.messages.setCurrentIndex(1) self.buttons.setCurrentIndex(1) else: assert new_state in ( CheckNewVersionDialogState.open_website, CheckNewVersionDialogState.prompt_for_download, ) assert version is not None assert changelog_url is not None self.new_version_number = version self.url = download_page offer_download = new_state == CheckNewVersionDialogState.prompt_for_download self.newVersion.setText( self._makeDownloadMsg(version, offer_download=offer_download, changelog_url=changelog_url)) self.messages.setCurrentIndex(2) if offer_download: self.buttons.setCurrentIndex(2) yesButton = self.downloadItBox.button( QDialogButtonBox.Yes) # type: QPushButton yesButton.setDefault(True) else: self.buttons.setCurrentIndex(3) def reset(self) -> None: """ Reset appearance to default checking... """ self.current_state = CheckNewVersionDialogState.check self.messages.setCurrentIndex(0) self.buttons.setCurrentIndex(0) def downloadItClicked(self, button) -> None: if button == self.dlItYesButton: self.setResult(QDialog.Accepted) self.dialog_detailed_result = CheckNewVersionDialogResult.download super().accept() elif button == self.dlItNoButton: self.setResult(QDialog.Rejected) self.dialog_detailed_result = CheckNewVersionDialogResult.do_not_download super().reject() else: assert button == self.dlItSkipButton self.setResult(QDialog.Rejected) self.dialog_detailed_result = CheckNewVersionDialogResult.skip super().reject() def openWebsiteClicked(self, button) -> None: if button == self.openDlPageButton: self.setResult(QDialog.Accepted) self.dialog_detailed_result = CheckNewVersionDialogResult.open_website super().accept() elif button == self.openDlCloseButton: self.setResult(QDialog.Rejected) self.dialog_detailed_result = CheckNewVersionDialogResult.do_not_download super().reject() else: assert button == self.openDlPageSkipButton self.setResult(QDialog.Rejected) self.dialog_detailed_result = CheckNewVersionDialogResult.skip super().reject()
class MetaAugmenterGUI(QDialog): def __init__(self, parent_window=None): super().__init__(parent=parent_window) self.first_image = None self.first_mask = None self.initUI() def initUI(self): layout = QGridLayout() layout.setColumnStretch(0, 80) layout.setColumnStretch(1, 20) layout.setHorizontalSpacing(3) layout.setVerticalSpacing(3) OpenFileOrFolderWidget.finalize_text_change = self.check_input self.open_input_button = OpenFileOrFolderWidget( parent_window=self, add_timer_to_changetext=True, show_ok_or_not_icon=True, label_text='Path to the raw dataset') layout.addWidget(self.open_input_button, 0, 0, 1, 2) OpenFileOrFolderWidget.finalize_text_change = self.check_labels self.open_labels_button = OpenFileOrFolderWidget( parent_window=self, add_timer_to_changetext=True, show_ok_or_not_icon=True, label_text='Segmentation masks/labels') layout.addWidget(self.open_labels_button, 1, 0, 1, 2) self.label_nb_inputs_over_outputs = QLabel('') layout.addWidget(self.label_nb_inputs_over_outputs, 2, 0, 1, 2) self.nb_inputs = 0 self.nb_outputs = 0 self.setLayout(layout) groupBox = QGroupBox('Pre-processing settings') groupBox.setEnabled(True) self.model_builder_layout = QGridLayout() self.model_builder_layout.setHorizontalSpacing(3) self.model_builder_layout.setVerticalSpacing(3) input_channel_label = QLabel('input channel of interest') self.model_builder_layout.addWidget(input_channel_label, 5, 0) self.input_channel_of_interest = QComboBox() self.input_channel_of_interest.currentIndexChanged.connect( self._input_channel_changed) self.model_builder_layout.addWidget(self.input_channel_of_interest, 5, 1) input_channel_reduction_rule_label = QLabel( 'rule to reduce nb of input channels (if needed)') self.model_builder_layout.addWidget(input_channel_reduction_rule_label, 6, 0) self.channel_input_reduction_rule = QComboBox() self.channel_input_reduction_rule.addItem( 'copy the input channel of interest to all available channels') self.channel_input_reduction_rule.addItem( 'remove supernumerary input channels (keep other channels unchanged)' ) self.model_builder_layout.addWidget(self.channel_input_reduction_rule, 6, 1, 1, 2) input_channel_augmentation_rule_label = QLabel( 'rule to increase nb of input channels (if needed)') self.model_builder_layout.addWidget( input_channel_augmentation_rule_label, 7, 0) self.channel_input_augmentation_rule = QComboBox() self.channel_input_augmentation_rule.addItem( 'copy the input channel of interest to all channels') self.channel_input_augmentation_rule.addItem( 'copy the input channel of interest to missing channels only') self.channel_input_augmentation_rule.addItem( 'add empty channels (0 filled)') self.model_builder_layout.addWidget( self.channel_input_augmentation_rule, 7, 1, 1, 2) output_channel_label = QLabel('output channel of interest') self.model_builder_layout.addWidget(output_channel_label, 8, 0) self.output_channel_of_interest = QComboBox() self.output_channel_of_interest.currentIndexChanged.connect( self._output_channel_changed) self.model_builder_layout.addWidget(self.output_channel_of_interest, 8, 1) output_channel_reduction_rule_label = QLabel( 'rule to reduce nb of output channels (if needed)') self.model_builder_layout.addWidget( output_channel_reduction_rule_label, 9, 0) # maybe rather put than in model input self.channel_output_reduction_rule = QComboBox() self.channel_output_reduction_rule.addItem( 'copy the output channel of interest to all available channels') self.channel_output_reduction_rule.addItem( 'remove supernumerary output channels (keep other channels unchanged)' ) self.model_builder_layout.addWidget(self.channel_output_reduction_rule, 9, 1, 1, 2) output_channel_augmentation_rule_label = QLabel( 'rule to increase nb of output channels (if needed)') self.model_builder_layout.addWidget( output_channel_augmentation_rule_label, 10, 0) self.channel_output_augmentation_rule = QComboBox() self.channel_output_augmentation_rule.addItem( 'copy the output channel of interest to all channels') self.channel_output_augmentation_rule.addItem( 'copy the output channel of interest to missing channels only') self.channel_output_augmentation_rule.addItem( 'add empty channels (0 filled)') self.model_builder_layout.addWidget( self.channel_output_augmentation_rule, 10, 1, 1, 2) crop_info_label = QLabel( 'If ROI should be used for training, please draw a rect over below images' ) self.model_builder_layout.addWidget(crop_info_label, 12, 0, 1, 3) input_preview_label = QLabel('input preview (channel of interest)') self.model_builder_layout.addWidget(input_preview_label, 14, 0, 1, 3) self.image_cropper_UI = crop_or_preview() self.model_builder_layout.addWidget(self.image_cropper_UI, 15, 0, 1, 3) output_preview_label = QLabel('output preview (channel of interest)') self.model_builder_layout.addWidget(output_preview_label, 14, 1, 1, 3) self.mask_preview = crop_or_preview(preview_only=True) self.model_builder_layout.addWidget(self.mask_preview, 15, 1, 1, 3) groupBox.setLayout(self.model_builder_layout) layout.addWidget(groupBox, 3, 0, 1, 2) # OK and Cancel buttons self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) layout.addWidget(self.buttons) def _output_channel_changed(self): if self.first_mask is not None and self.first_mask.has_c(): if self.output_channel_of_interest.currentIndex() != -1: channel_img = self.first_mask.imCopy( c=self.output_channel_of_interest.currentIndex()) self.mask_preview.set_image(channel_img) else: self.mask_preview.set_image(self.first_mask) def _input_channel_changed(self): if self.first_image is not None and self.first_image.has_c(): if self.input_channel_of_interest.currentIndex() != -1: channel_img = self.first_image.imCopy( c=self.input_channel_of_interest.currentIndex()) self.image_cropper_UI.set_image(channel_img) else: self.image_cropper_UI.set_image(self.first_image) def _update_inputs_and_outputs_nb(self): info_text = 'everything seems fine' if self.nb_outputs == 0 or self.nb_inputs == 0 or self.nb_outputs != self.nb_inputs: info_text = 'there seems to be a pb\n with your input/label data\n please check' self.label_nb_inputs_over_outputs.setText( str(self.nb_inputs) + ' / ' + str(self.nb_outputs) + " " + info_text) def check_input(self): print('in 2', self.open_input_button.text()) txt = self.open_input_button.text() if '*' in txt: # then check if files do exist and try to open them file_list = self.open_input_button.get_list_using_glob() if file_list is not None and file_list: import os self.first_image, can_read = self._can_read_file( file_list[0], self.input_channel_of_interest) self.open_input_button.set_icon_ok(can_read) if can_read: self.nb_inputs = len(file_list) else: self.nb_inputs = 0 if self.open_labels_button.text() is not None: if self._can_read_mask(file_list[0]): self.nb_outputs = self.nb_inputs else: self.nb_outputs = 0 else: self.open_input_button.set_icon_ok(False) self.nb_inputs = 0 self.first_image = None if self.open_labels_button.text() is not None: self.open_labels_button.set_icon_ok(False) self.nb_outputs = 0 else: import os file_list = DataGenerator.get_list_of_images( self.open_input_button.text()) if file_list: self.first_image, can_read = self._can_read_file( file_list[0], self.input_channel_of_interest) self.open_input_button.set_icon_ok(can_read) self.nb_inputs = len(file_list) if self.open_labels_button.text() is not None: if self._can_read_mask(file_list[0]): self.nb_outputs = self.nb_inputs else: self.nb_outputs = 0 else: self.nb_inputs = 0 self.first_image = None self.open_input_button.set_icon_ok(False) if self.open_labels_button.text() is not None: self.open_labels_button.set_icon_ok(False) self.nb_outputs = 0 print('error no files matching "', self.open_input_button.text(), '"') self._update_inputs_and_outputs_nb() self.image_cropper_UI.set_image( self.first_image) # not smart to load it twice TODO def _can_read_mask(self, path): import os mask_path = os.path.join( os.path.splitext(path)[0], 'handCorrection.png') if os.path.isfile(mask_path): if self._can_read_file(path, self.output_channel_of_interest): print('TA structure') # TODO replace by logger self.open_labels_button.set_icon_ok(True) return True else: print('unknown structure') self.open_labels_button.set_icon_ok(False) else: mask_path = os.path.join( os.path.splitext(path)[0], 'handCorrection.tif') if os.path.isfile(mask_path): if self._can_read_file(path, self.output_channel_of_interest): print('TA structure') self.open_labels_button.set_icon_ok(True) return True else: print('unknown structure') self.open_labels_button.set_icon_ok(False) else: self.open_labels_button.set_icon_ok(False) return False def _can_read_file(self, path, channels_to_update=None): try: img = Img(path) try: print(img.has_c(), channels_to_update, img.shape, img.shape[-1]) if img.has_c() and channels_to_update is not None: # empty channel combo channels_to_update.clear() # add new channels to combo for chan in range(img.shape[-1]): channels_to_update.addItem(str(chan)) # deselect it channels_to_update.setCurrentIndex(-1) channels_to_update.update() if not img.has_c(): channels_to_update.clear() channels_to_update.setCurrentIndex(-1) channels_to_update.update() except: import traceback import logging logging.error(traceback.format_exc()) return img, True except: print('could not read image ' + path) return None, False def check_labels(self): txt = self.open_labels_button.text() if txt is not None and '*' in txt: file_list = self.open_labels_button.get_list_using_glob() if file_list is not None and file_list: import os self.first_mask, can_read = self._can_read_file( file_list[0], self.output_channel_of_interest) self.open_labels_button.set_icon_ok(can_read) if can_read: self.nb_outputs = len(file_list) else: self.nb_outputs = 0 else: self.first_mask = None self.open_labels_button.set_icon_ok(False) self.nb_outputs = 0 else: import os file_list = DataGenerator.get_list_of_images( self.open_labels_button.text()) if file_list: self.first_mask, can_read = self._can_read_file( file_list[0], self.output_channel_of_interest) self.open_labels_button.set_icon_ok(can_read) if can_read: self.nb_outputs = len(file_list) else: self.nb_outputs = 0 else: self.first_mask = None self.open_labels_button.set_icon_ok(False) self.nb_outputs = 0 print('error no files matching "', self.open_input_button.text(), '"') self._update_inputs_and_outputs_nb() self.mask_preview.set_image(self.first_mask) def getParams(self): # will that work and do I need to show the channel input_channel_of_interest = self.input_channel_of_interest.currentIndex( ) if input_channel_of_interest == -1: input_channel_of_interest = None else: input_channel_of_interest = int( self.input_channel_of_interest.currentText()) output_channel_of_interest = self.output_channel_of_interest.currentIndex( ) if output_channel_of_interest == -1: output_channel_of_interest = None else: output_channel_of_interest = int( self.output_channel_of_interest.currentText()) return json.dumps({ 'inputs': [self.open_input_button.text()], 'outputs': [self.open_labels_button.text()], 'input_channel_reduction_rule': self.channel_input_reduction_rule.currentText(), 'input_channel_augmentation_rule': self.channel_input_augmentation_rule.currentText(), 'output_channel_reduction_rule': self.channel_output_reduction_rule.currentText(), 'output_channel_augmentation_rule': self.channel_output_augmentation_rule.currentText(), 'input_channel_of_interest': input_channel_of_interest, 'output_channel_of_interest': output_channel_of_interest, 'crop_parameters': self.image_cropper_UI.get_crop_parameters() }) # get all the params for augmentation @staticmethod def getDataAndParameters(parent=None): dialog = MetaAugmenterGUI(parent) result = dialog.exec_() augment = dialog.getParams() return (augment, result == QDialog.Accepted) def activate_ok_button_if_all_si_fine(self): all_ok = False self.buttons.button(QDialogButtonBox.Ok).setEnabled( all_ok ) # do that always in all GUIs where it's required to avoid issues...
class LoginWindowView: def __init__(self, window): self.main_widget = window def __del__(self): #if self.main_widget in : self.user_list_widget.deleteLater() self.user_scroll.deleteLater() self.main_widget.deleteLater() ''' self.user_list_widget.destroy() self.user_scroll.destroy() self.main_widget.destroy() print("Ds") if self.user_scroll in self: self.user_scroll.destroy() if self.v_lay_user_list_widget in self: self.v_lay_user_list_widget.deleteLater() if self.new_user_label in self: self.new_user_label.deleteLater() if self.label_user_list in self: for i in range(0, len(self.label_user_list)): self.label_user_list[i].deleteLater() if self.dialog in self: self.dialog.destroy() if self.line1_username in self: self.line1_username.deleteLater() if self.line2_host in self: self.line2_host.deleteLater() if self.line3_db in self: self.line3_db.deleteLater() if self.line2_host in self: self.line2_host.deleteLater() if self.buttonOK in self: self.buttonOK.deleteLater() if self.buttonTest in self: self.buttonTest.deleteLater() if self.dialog_layout in self: self.dialog_layout.deleteLater() if self.passWindow in self: self.passWindow.destroy() if self.line_pass in self: self.line_pass.deleteLater() if self.passWindow_buttons in self: self.passWindow_buttons.destroy() if self.login_window in self: self.login_window.destroy() if self.line1_login_window in self: self.line1_login_window.deleteLater() if self.button_delete_login_window in self: self.button_delete_login_window.deleteLater() if self.button_login_window in self: self.button_login_window.destroy() ''' def initDraw(self, width, height): self.main_widget.setMinimumWidth(width) self.main_widget.setMinimumHeight(height) self.user_scroll = QScrollArea(self.main_widget) self.user_scroll.setWidgetResizable(True) self.user_list_widget = QWidget(self.user_scroll) self.user_list_size = [300, 400] self.centeringUserListWidget() self.label_user_list = [] #self.user_list_widget.setStyleSheet("background-color:#F00") self.user_list_widget.setStyleSheet( "background-color: rgba(0, 0, 0, 0.1)") self.v_lay_user_list_widget = QVBoxLayout() self.user_list_widget.setLayout(self.v_lay_user_list_widget) #self.background_user_button = "background-color: rgba(0, 0, 0, 0.1)" self.background_user_button = "background-color: #EEE" self.new_user_label = QLabel(self.user_list_widget) self.new_user_label.setText("+ Dodaj nowego użytkownika") self.new_user_label.setFixedHeight(40) self.new_user_label.setFixedWidth(self.user_list_size[0] - 40) #self.new_user_label.move(10, 0) self.new_user_label.setStyleSheet(self.background_user_button) #self.new_user_label.mousePressEvent = self.clickedButton self.v_lay_user_list_widget.addWidget(self.new_user_label) #self.v_lay_user_list_widget.addStretch() def centeringUserListWidget(self): win = [self.main_widget.width(), self.main_widget.height()] self.user_scroll.setGeometry( int((win[0] - self.user_list_size[0]) / 2), int((win[1] - self.user_list_size[1]) / 2), self.user_list_size[0], self.user_list_size[1]) def drawUserList(self, userList): if len(self.label_user_list) != 0: for i in range(0, len(self.label_user_list)): self.label_user_list[i].deleteLater() self.label_user_list = [] if len(userList) == 0: self.v_lay_user_list_widget.addStretch() else: for row in userList: temp = QPushButton(self.user_list_widget) temp.setText(row[0] + "@" + row[1]) temp.setFixedHeight(40) temp.setFixedWidth(self.user_list_size[0] - 40) temp.setStyleSheet(self.background_user_button) #temp.setStyleSheet("background-color:rgba(255, 0, 0, 0)") self.label_user_list.append(temp) ''' for row in self.label_user_list: self.v_lay_user_list_widget.addWidget(row) .clicked.connect(lambda: self.test(tempi)) tempi += 1 ''' for i in range(0, len(self.label_user_list)): self.v_lay_user_list_widget.addWidget(self.label_user_list[i]) self.v_lay_user_list_widget.addStretch() self.user_scroll.setWidget(self.user_list_widget) def clickedButton(self, event): print("ClicketButton") def test(self): temp = self.user_list_widget.sender() for i in range(0, len(self.label_user_list)): if self.label_user_list == temp: print() print(temp, " - ", temp.text()) def newUserWindow(self): self.dialog = QWidget() self.dialog.setFixedWidth(400) self.dialog.setFixedHeight(250) self.dialog_layout = QGridLayout() self.dialog_layout.setSpacing(10) self.dialog.setWindowTitle("Dodawanie nowego użytkownika") lab1_username = QLabel(self.dialog) lab1_username.setText("Podaj nazwę użytkownika:") self.line1_username = QLineEdit(self.dialog) self.line1_username.setPlaceholderText("np. Mietek") lab2_host = QLabel(self.dialog) lab2_host.setText("Podaj adres serwera:") self.line2_host = QLineEdit(self.dialog) self.line2_host.setPlaceholderText("np. localhost") lab3_db = QLabel(self.dialog) lab3_db.setText("Podaj nazwę bazy:") self.line3_db = QLineEdit(self.dialog) self.line3_db.setPlaceholderText("np. Tajna baza NASA") self.buttonOK = QPushButton(self.dialog) self.buttonOK.setText("Dodaj") buttonCancel = QPushButton(self.dialog) buttonCancel.setText("Anuluj") self.buttonTest = QPushButton(self.dialog) self.buttonTest.setText("Testuj połączenie") buttonCancel.clicked.connect(self.newUserWindowCancelButton) self.dialog_layout.addWidget(lab1_username, 1, 0) self.dialog_layout.addWidget(self.line1_username, 1, 1, 1, 2) self.dialog_layout.addWidget(lab2_host, 2, 0) self.dialog_layout.addWidget(self.line2_host, 2, 1, 1, 2) self.dialog_layout.addWidget(lab3_db, 3, 0) self.dialog_layout.addWidget(self.line3_db, 3, 1, 1, 2) self.dialog_layout.addWidget(self.buttonTest, 4, 2) self.dialog_layout.addWidget(self.buttonOK, 5, 1) self.dialog_layout.addWidget(buttonCancel, 5, 2) self.line1_username.text() self.dialog.setLayout(self.dialog_layout) self.dialog.show() def newUserWindowCancelButton(self): self.dialog.close() self.dialog.destroy() def passwordWindow(self, parent): self.passWindow = QDialog(parent) passWindow_label = QLabel(self.passWindow) passWindow_label.setText("Podaj Hasło") self.line_pass = QLineEdit(self.passWindow) self.line_pass.setEchoMode(QLineEdit.Password) self.passWindow.setFixedHeight(120) self.passWindow.setFixedWidth(300) passWindow_v_lay = QVBoxLayout(self.passWindow) self.passWindow.setLayout(passWindow_v_lay) passWindow_v_lay.addWidget(passWindow_label) passWindow_v_lay.addWidget(self.line_pass) self.passWindow_buttons = QDialogButtonBox(self.passWindow) self.passWindow_buttons.addButton(QDialogButtonBox.Ok) self.passWindow_buttons.addButton(QDialogButtonBox.Cancel) self.passWindow_buttons.button( QDialogButtonBox.Cancel).clicked.connect( self.passWindowCancelEvent) passWindow_v_lay.addWidget(self.passWindow_buttons) self.passWindow.show() def passWindowCancelEvent(self, event): self.passWindow.close() self.passWindow.destroy() def messageOK(self, text, text2=None, parrent=None): message = QMessageBox(parrent) message.setText(text) message.setInformativeText(text2) message.setIcon(QMessageBox.Information) message.show() def messageBad(self, text, text2=None, parrent=None): message = QMessageBox(parrent) message.setText(text) message.setInformativeText(text2) message.setIcon(QMessageBox.Critical) message.show() def messageNeutral(self, text, text2=None, parrent=None): message = QMessageBox(parrent) message.setText(text) message.setInformativeText(text2) message.show() def loginWindow(self, username, host, db): self.login_window = QDialog() self.login_window.setWindowTitle("Logowanie do " + username + "@" + host) self.login_window.setFixedWidth(300) self.login_window.setFixedHeight(200) self.data_login_window = [username, host, db] label1_login_window = QLabel(self.login_window) label2_login_window = QLabel(self.login_window) label3_login_window = QLabel(self.login_window) label1_login_window.setText("<h2>Chcesz się zalogować do:</h2>") label2_login_window.setText("Nazwa użytkownika:\t" + username + "\nHost:\t\t\t" + host + "\nBaza:\t\t\t" + db) label3_login_window.setText("Podaj hasło:") self.line1_login_window = QLineEdit(self.login_window) self.line1_login_window.setEchoMode(QLineEdit.Password) self.button_delete_login_window = QPushButton(self.login_window) self.button_delete_login_window.setText("Usuń to konto") self.button_login_window = QDialogButtonBox(self.login_window) self.button_login_window.addButton(self.button_delete_login_window, QDialogButtonBox.AcceptRole) self.button_login_window.addButton(QDialogButtonBox.Ok) self.button_login_window.addButton(QDialogButtonBox.Cancel) self.button_login_window.button( QDialogButtonBox.Cancel).clicked.connect( self.loginWindowCancelEvent) #self.button_login_window.(QDialogButtonBox.MacLayout) v_lay_login_window = QVBoxLayout(self.login_window) self.login_window.setLayout(v_lay_login_window) v_lay_login_window.addWidget(label1_login_window) v_lay_login_window.addWidget(label2_login_window) v_lay_login_window.addWidget(label3_login_window) v_lay_login_window.addWidget(self.line1_login_window) v_lay_login_window.addStretch() v_lay_login_window.addWidget(self.button_login_window) self.login_window.show() def loginWindowCancelEvent(self, event): self.login_window.close() self.login_window.destroy()
def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) self.__committimer = QTimer(self, singleShot=True) self.__committimer.timeout.connect(self.commit) self.__executor = qconcurrent.ThreadExecutor() self.__watcher = None # type: Optional[qconcurrent.FutureWatcher] self.controlArea.layout().setSpacing(-1) # reset spacing grid = QGridLayout() grid.addWidget(QLabel("File:", self), 0, 0, 1, 1) self.import_items_model = QStandardItemModel(self) self.recent_combo = QComboBox( self, objectName="recent-combo", toolTip="Recent files.", sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon, minimumContentsLength=16, ) self.recent_combo.setModel(self.import_items_model) self.recent_combo.activated.connect(self.activate_recent) self.recent_combo.setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) self.browse_button = QPushButton( "…", icon=self.style().standardIcon(QStyle.SP_DirOpenIcon), toolTip="Browse filesystem", autoDefault=False, ) self.browse_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.browse_button.clicked.connect(self.browse) grid.addWidget(self.recent_combo, 0, 1, 1, 1) grid.addWidget(self.browse_button, 0, 2, 1, 1) self.controlArea.layout().addLayout(grid) ########### # Info text ########### box = gui.widgetBox(self.controlArea, "Info", addSpace=False) self.summary_text = QTextBrowser( verticalScrollBarPolicy=Qt.ScrollBarAsNeeded, readOnly=True, ) self.summary_text.viewport().setBackgroundRole(QPalette.NoRole) self.summary_text.setFrameStyle(QTextBrowser.NoFrame) self.summary_text.setMinimumHeight(self.fontMetrics().ascent() * 2 + 4) self.summary_text.viewport().setAutoFillBackground(False) box.layout().addWidget(self.summary_text) button_box = QDialogButtonBox( orientation=Qt.Horizontal, standardButtons=QDialogButtonBox.Cancel | QDialogButtonBox.Retry ) self.load_button = b = button_box.button(QDialogButtonBox.Retry) b.setText("Load") b.clicked.connect(self.__committimer.start) b.setEnabled(False) b.setDefault(True) self.cancel_button = b = button_box.button(QDialogButtonBox.Cancel) b.clicked.connect(self.cancel) b.setEnabled(False) b.setAutoDefault(False) self.import_options_button = QPushButton( "Import Options…", enabled=False, autoDefault=False, clicked=self._activate_import_dialog ) def update_buttons(cbindex): self.import_options_button.setEnabled(cbindex != -1) self.load_button.setEnabled(cbindex != -1) self.recent_combo.currentIndexChanged.connect(update_buttons) button_box.addButton( self.import_options_button, QDialogButtonBox.ActionRole ) button_box.setStyleSheet( "button-layout: {:d};".format(QDialogButtonBox.MacLayout) ) self.controlArea.layout().addWidget(button_box) self._restoreState() if self.current_item() is not None: self._invalidate() self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
class PackageDialog(QDialog): """Display the output of the pip commands needed to remove or install packages Because the QProcess mechanism we're using is asynchronous, we have to manage the pip requests via `pip_queue`. When one request is signalled as finished we start the next. """ def __init__(self, parent=None): super().__init__(parent) self.pip_queue = [] def setup(self, to_remove, to_add): """ Create the UI for the dialog. """ # Basic layout. self.setMinimumSize(600, 400) self.setWindowTitle(_("Third Party Package Status")) widget_layout = QVBoxLayout() self.setLayout(widget_layout) # Text area for pip output. self.text_area = QPlainTextEdit() self.text_area.setReadOnly(True) self.text_area.setLineWrapMode(QPlainTextEdit.NoWrap) widget_layout.addWidget(self.text_area) # Buttons. self.button_box = QDialogButtonBox(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.button_box.accepted.connect(self.accept) widget_layout.addWidget(self.button_box) # # Set up the commands to be issues to pip. Since we'll be popping # from the list (as LIFO) we'll add the installs first so the # removes are the first to happen # if to_add: self.pip_queue.append(("install", to_add)) if to_remove: self.pip_queue.append(("remove", to_remove)) QTimer.singleShot(2, self.next_pip_command) def next_pip_command(self): """Run the next pip command, finishing if there is none""" if self.pip_queue: command, packages = self.pip_queue.pop() self.run_pip(command, packages) else: self.finish() def finish(self): """ Set the UI to a valid end state. """ self.text_area.appendPlainText("\nFINISHED") self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) def run_pip(self, command, packages): """ Run a pip command in a subprocess and pipe the output to the dialog's text area. """ if command == "remove": pip_fn = venv.remove_user_packages elif command == "install": pip_fn = venv.install_user_packages else: raise RuntimeError( "Invalid pip command: %s %s" % (command, packages) ) pip_fn( packages, slots=venv.Slots( output=self.text_area.appendPlainText, finished=self.next_pip_command, ), )
class PackageDialog(QDialog): """ Display a dialog to indicate the status of the packaging related changes currently run by pip. """ def __init__(self, parent=None): super().__init__(parent) def setup(self, to_remove, to_add, module_dir): """ Create the UI for the dialog. """ self.to_remove = to_remove self.to_add = to_add self.module_dir = module_dir self.pkg_dirs = {} # To hold locations of to-be-removed packages. self.process = None # Basic layout. self.setMinimumSize(600, 400) self.setWindowTitle(_("Third Party Package Status")) widget_layout = QVBoxLayout() self.setLayout(widget_layout) # Text area for pip output. self.text_area = QPlainTextEdit() self.text_area.setReadOnly(True) self.text_area.setLineWrapMode(QPlainTextEdit.NoWrap) widget_layout.addWidget(self.text_area) # Buttons. self.button_box = QDialogButtonBox(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).setEnabled(False) self.button_box.accepted.connect(self.accept) widget_layout.addWidget(self.button_box) # Kick off processing of packages. if self.to_remove: self.remove_packages() if self.to_add: self.run_pip() def remove_packages(self): """ Work out which packages need to be removed and then kick off their removal. """ dirs = [ os.path.join(self.module_dir, d) for d in os.listdir(self.module_dir) if d.endswith("dist-info") or d.endswith("egg-info") ] self.pkg_dirs = {} for pkg in self.to_remove: for d in dirs: # Assets on the filesystem use a normalised package name. pkg_name = pkg.replace("-", "_").lower() if os.path.basename(d).lower().startswith(pkg_name + "-"): self.pkg_dirs[pkg] = d if self.pkg_dirs: # If there are packages to remove, schedule removal. QTimer.singleShot(2, self.remove_package) def remove_package(self): """ Take a package from the pending packages to be removed, delete all its assets and schedule the removal of the remaining packages. If there are no packages to remove, move to the finished state. """ if self.pkg_dirs: package, info = self.pkg_dirs.popitem() if info.endswith("dist-info"): # Modern record = os.path.join(info, "RECORD") with open(record) as f: files = csv.reader(f) for row in files: to_delete = os.path.join(self.module_dir, row[0]) try: os.remove(to_delete) except Exception as ex: logger.error("Unable to remove: " + to_delete) logger.error(ex) shutil.rmtree(info, ignore_errors=True) # Some modules don't use the module name for the module # directory (they use a lower case variant thereof). E.g. # "Fom" vs. "fom". normal_module = os.path.join(self.module_dir, package) lower_module = os.path.join(self.module_dir, package.lower()) shutil.rmtree(normal_module, ignore_errors=True) shutil.rmtree(lower_module, ignore_errors=True) self.append_data("Removed {}\n".format(package)) else: # Egg try: record = os.path.join(info, "installed-files.txt") with open(record) as f: files = f.readlines() for row in files: to_delete = os.path.join(info, row.strip()) try: os.remove(to_delete) except Exception as ex: logger.error("Unable to remove: " + to_delete) logger.error(ex) shutil.rmtree(info, ignore_errors=True) # Some modules don't use the module name for the module # directory (they use a lower case variant thereof). E.g. # "Fom" vs. "fom". normal_module = os.path.join(self.module_dir, package) lower_module = os.path.join(self.module_dir, package.lower()) shutil.rmtree(normal_module, ignore_errors=True) shutil.rmtree(lower_module, ignore_errors=True) self.append_data("Removed {}\n".format(package)) except Exception as ex: msg = ("UNABLE TO REMOVE PACKAGE: {} (check the logs for" " more information.)").format(package) self.append_data(msg) logger.error("Unable to remove package: " + package) logger.error(ex) QTimer.singleShot(2, self.remove_package) else: # Clean any directories not containing files. dirs = [ os.path.join(self.module_dir, d) for d in os.listdir(self.module_dir) ] for d in dirs: keep = False for entry in os.walk(d): if entry[2]: keep = True if not keep: shutil.rmtree(d, ignore_errors=True) # Remove the bin directory (and anything in it) since we don't # use these assets. shutil.rmtree(os.path.join(self.module_dir, "bin"), ignore_errors=True) # Check for end state. if not (self.to_add or self.process): self.end_state() def end_state(self): """ Set the UI to a valid end state. """ self.append_data("\nFINISHED") self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) def run_pip(self): """ Run a pip command in a subprocess and pipe the output to the dialog's text area. """ package = self.to_add.pop() args = ["-m", "pip", "install", package, "--target", self.module_dir] self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.readyRead.connect(self.read_process) self.process.finished.connect(self.finished) logger.info("{} {}".format(sys.executable, " ".join(args))) self.process.start(sys.executable, args) def finished(self): """ Called when the subprocess that uses pip to install a package is finished. """ if self.to_add: self.process = None self.run_pip() else: if not self.pkg_dirs: self.end_state() def read_process(self): """ Read data from the child process and append it to the text area. Try to keep reading until there's no more data from the process. """ data = self.process.readAll() if data: self.append_data(data.data().decode("utf-8")) QTimer.singleShot(2, self.read_process) def append_data(self, msg): """ Add data to the end of the text area. """ cursor = self.text_area.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(msg) cursor.movePosition(QTextCursor.End) self.text_area.setTextCursor(cursor)
class TextItemDlg(QDialog): def __init__(self, item=None, position=None, scene=None, parent=None): super(QDialog, self).__init__(parent) self.item = item self.position = position self.scene = scene self.editor = QTextEdit() self.editor.setAcceptRichText(False) self.editor.setTabChangesFocus(True) editorLabel = QLabel("&Text:") editorLabel.setBuddy(self.editor) self.fontComboBox = QFontComboBox() self.fontComboBox.setCurrentFont(QFont("Times", PointSize)) fontLabel = QLabel("&Font:") fontLabel.setBuddy(self.fontComboBox) self.fontSpinBox = QSpinBox() self.fontSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter) self.fontSpinBox.setRange(6, 280) self.fontSpinBox.setValue(PointSize) fontSizeLabel = QLabel("&Size:") fontSizeLabel.setBuddy(self.fontSpinBox) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok| QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) if self.item is not None: self.editor.setPlainText(self.item.toPlainText()) self.fontComboBox.setCurrentFont(self.item.font()) self.fontSpinBox.setValue(self.item.font().pointSize()) layout = QGridLayout() layout.addWidget(editorLabel, 0, 0) layout.addWidget(self.editor, 1, 0, 1, 6) layout.addWidget(fontLabel, 2, 0) layout.addWidget(self.fontComboBox, 2, 1, 1, 2) layout.addWidget(fontSizeLabel, 2, 3) layout.addWidget(self.fontSpinBox, 2, 4, 1, 2) layout.addWidget(self.buttonBox, 3, 0, 1, 6) self.setLayout(layout) self.fontComboBox.currentFontChanged.connect(self.updateUi) self.fontSpinBox.valueChanged.connect(self.updateUi) self.editor.textChanged.connect(self.updateUi) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.setWindowTitle("Page Designer - {0} Text Item".format( "Add" if self.item is None else "Edit")) self.updateUi() def updateUi(self): font = self.fontComboBox.currentFont() font.setPointSize(self.fontSpinBox.value()) self.editor.document().setDefaultFont(font) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( bool(self.editor.toPlainText())) def accept(self): if self.item is None: self.item = TextItem("", self.position, self.scene) font = self.fontComboBox.currentFont() font.setPointSize(self.fontSpinBox.value()) self.item.setFont(font) self.item.setPlainText(self.editor.toPlainText()) self.item.update() global Dirty Dirty = True QDialog.accept(self)
class AboutDialog(QDialog): check_update = pyqtSignal(str, bool) def __init__(self, parent=None): super(AboutDialog, self).__init__(parent) self._ver = '' self._github = 'https://github.com/rachpt/lanzou-gui' self._api_url = 'https://github.com/zaxtyson/LanZouCloud-API' self._gitee = 'https://gitee.com/rachpt/lanzou-gui' self._home_page = 'https://rachpt.cn/lanzou-gui/' self.initUI() self.setStyleSheet(others_style) def set_values(self, version): self._ver = version self.lb_name_text.setText(f"{version} (点击检查更新)") # 更新版本 def show_update(self, ver, msg): self.lb_new_ver = QLabel("新版") # 检测新版 self.lb_new_ver_msg = QLabel() self.lb_new_ver_msg.setOpenExternalLinks(True) self.lb_new_ver_msg.setWordWrap(True) if ver != '0': self.lb_name_text.setText(f"{self._ver} ➡ {ver}") self.lb_new_ver_msg.setText(msg) self.lb_new_ver_msg.setMinimumWidth(700) if self.form.rowCount() < 5: self.form.insertRow(1, self.lb_new_ver, self.lb_new_ver_msg) def initUI(self): self.setWindowTitle("关于 lanzou-gui") about = f'本项目使用PyQt5实现图形界面,可以完成蓝奏云的大部分功能<br/> \ 得益于 <a href="{self._api_url}">API</a> 的功能,可以间接突破单文件最大 100MB 的限制,同时增加了批量上传/下载的功能<br/> \ Python 依赖见<a href="{self._github }/blob/master/requirements.txt">requirements.txt</a>,\ <a href="{self._github}/releases">releases</a> 有打包好了的 Windows 可执行程序,但可能不是最新的' project_url = f'<a href="{self._home_page}">主页</a> | <a href="{self._github}">repo</a> | \ <a href="{self._gitee}">mirror repo</a>' self.logo = QLabel() # logo self.logo.setPixmap(QPixmap("./src/logo2.gif")) self.logo.setStyleSheet("background-color:rgb(255,255,255);") self.logo.setAlignment(Qt.AlignCenter) self.lb_name = QLabel("版本") # 版本 self.lb_name_text = QPushButton("") # 版本 self.lb_name_text.setToolTip("点击检查更新") ver_style = "QPushButton {border:none; background:transparent;font-weight:bold;color:blue;}" self.lb_name_text.setStyleSheet(ver_style) self.lb_name_text.clicked.connect( lambda: self.check_update.emit(self._ver, True)) self.lb_about = QLabel("关于") # about self.lb_about_text = QLabel() self.lb_about_text.setText(about) self.lb_about_text.setOpenExternalLinks(True) self.lb_author = QLabel("作者") # author self.lb_author_mail = QLabel( "<a href='mailto:[email protected]'>rachpt</a>") self.lb_author_mail.setOpenExternalLinks(True) self.lb_update = QLabel("项目") # 更新 self.lb_update_url = QLabel(project_url) self.lb_update_url.setOpenExternalLinks(True) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.buttonBox.button(QDialogButtonBox.Close).setText("关闭") self.buttonBox.rejected.connect(self.reject) self.buttonBox.setStyleSheet(btn_style) self.line = QLine(QPoint(), QPoint(550, 0)) self.lb_line = QLabel() self.lb_line.setText('<html><hr /></html>') vbox = QVBoxLayout() vbox.addWidget(self.logo) vbox.addStretch(1) self.form = QFormLayout() self.form.setLabelAlignment(Qt.AlignRight) self.form.setFormAlignment(Qt.AlignLeft) self.form.setHorizontalSpacing(40) self.form.setVerticalSpacing(15) self.form.addRow(self.lb_name, self.lb_name_text) self.form.addRow(self.lb_update, self.lb_update_url) self.form.addRow(self.lb_author, self.lb_author_mail) self.form.addRow(self.lb_about, self.lb_about_text) vbox.addLayout(self.form) vbox.addStretch(1) vbox.addWidget(self.lb_line) donate = QLabel() donate.setText("<b>捐助我</b> 如果你愿意") donate.setAlignment(Qt.AlignCenter) hbox = QHBoxLayout() hbox.addStretch(2) for it in ["wechat", "alipay", "qqpay"]: lb = QLabel() lb.setPixmap(QPixmap(f"./src/{it}.jpg")) hbox.addWidget(lb) hbox.addStretch(1) hbox.addWidget(self.buttonBox) vbox.addWidget(donate) vbox.addLayout(hbox) self.setLayout(vbox) self.setMinimumWidth(720) def paintEvent(self, event): QDialog.paintEvent(self, event) if not self.line.isNull(): painter = QPainter(self) pen = QPen(Qt.red, 3) painter.setPen(pen) painter.drawLine(self.line)
class TipInfoDialog(QDialog): def __init__(self, parent): super(TipInfoDialog, self).__init__(parent) self.parent = parent self.is_show = False self.point = QPoint() self.InitUserInterface() def __del__(self): pass def InitUserInterface(self): win_size_x = 395 win_size_y = 90 # 两行文字,110 三行文字 self.resize(win_size_x, win_size_y) self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) self.widget = QWidget() self.widget.setGeometry(QRect(0, 0, win_size_x, win_size_y)) self.text_edit = QTextEdit() self.text_edit.setFont(QFont("SimSun", 10)) self.text_edit.setReadOnly(True) self.text_edit.setLineWrapMode(QTextEdit.WidgetWidth) self.text_edit.document().setDefaultTextOption(QTextOption(Qt.AlignCenter)) self.button_box = QDialogButtonBox(self.widget) self.button_box.setStandardButtons(QDialogButtonBox.Ok) self.button_box.button(QDialogButtonBox.Ok).setText("已 阅") self.button_box.setCenterButtons(True) self.button_box.accepted.connect(self.OnButtonClose) self.v_box = QVBoxLayout() self.v_box.setContentsMargins(5, 5, 5, 5) self.spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.v_box.addWidget(self.text_edit) self.v_box.addItem(self.spacer) self.v_box.addWidget(self.button_box) self.setLayout(self.v_box) self.timer_show = QTimer() self.timer_stay = QTimer() self.timer_hide = QTimer() self.timer_show.timeout.connect(self.OnTimerShow) self.timer_stay.timeout.connect(self.OnTimerStay) self.timer_hide.timeout.connect(self.OnTimerHide) pub.subscribe(self.OnTipInfoMessage, "tip.info.message") def OnTipInfoMessage(self, msg): self.ShowMessage(msg) def ShowMessage(self, msg): if self.is_show == True: self.OnButtonClose() self.rect_desktop = QApplication.desktop().availableGeometry() self.desktop_height = self.rect_desktop.height() self.point.setX(self.rect_desktop.width() - self.width()) self.point.setY(self.rect_desktop.height() - self.height()) self.move(self.point.x(), self.desktop_height) self.text_edit.clear() self.text_edit.append(msg) self.transparent = 0.9 self.setWindowOpacity(self.transparent) self.show() self.is_show = True self.timer_show.start(10) def OnTimerShow(self): self.desktop_height -= 1 self.move(self.point.x(), self.desktop_height) if self.desktop_height <= self.point.y(): self.timer_show.stop() self.timer_stay.start(8000) def OnTimerStay(self): self.timer_stay.stop() self.timer_hide.start(100) def OnTimerHide(self): self.transparent -= 0.05 if self.transparent <= 0.0: self.timer_hide.stop() self.is_show = False self.close() else: self.setWindowOpacity(self.transparent) def OnButtonClose(self): self.timer_show.stop() self.timer_stay.stop() self.timer_hide.stop() self.is_show = False self.close()
def initUI(self): self.setWindowTitle("设置") logo = QLabel() # logo logo.setPixmap(QPixmap("./src/logo2.gif")) logo.setStyleSheet("background-color:rgb(255,255,255);") logo.setAlignment(Qt.AlignCenter) self.download_threads_lb = QLabel("同时下载文件数") # about self.download_threads_var = QLineEdit() self.download_threads_var.setPlaceholderText("范围:1-9") self.download_threads_var.setToolTip("范围:1-9") self.download_threads_var.setInputMask("D") self.max_size_lb = QLabel("分卷大小(MB)") self.max_size_var = QLineEdit() self.max_size_var.setPlaceholderText("普通用户最大100,vip用户根据具体情况设置") self.max_size_var.setToolTip("普通用户最大100,vip用户根据具体情况设置") self.max_size_var.setInputMask("D99") self.timeout_lb = QLabel("请求超时(秒)") self.timeout_var = QLineEdit() self.timeout_var.setPlaceholderText("范围:1-99") self.timeout_var.setToolTip("范围:1-99") self.timeout_var.setInputMask("D9") self.dl_path_lb = QLabel("下载保存路径") self.dl_path_var = MyLineEdit(self) self.dl_path_var.clicked.connect(self.set_download_path) self.time_fmt_box = QCheckBox("使用[年-月-日]时间格式") self.to_tray_box = QCheckBox("关闭到系统托盘") self.time_fmt_box.toggle() self.time_fmt_box.stateChanged.connect(self.change_time_fmt) self.to_tray_box.stateChanged.connect(self.change_to_tray) buttonBox = QDialogButtonBox() buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Reset | QDialogButtonBox.Save | QDialogButtonBox.Cancel) buttonBox.button(QDialogButtonBox.Reset).setText("重置") buttonBox.button(QDialogButtonBox.Save).setText("保存") buttonBox.button(QDialogButtonBox.Cancel).setText("取消") buttonBox.button(QDialogButtonBox.Reset).clicked.connect( lambda: self.set_values(reset=True)) buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.slot_save) buttonBox.rejected.connect(self.reject) form = QFormLayout() form.setLabelAlignment(Qt.AlignRight) form.setSpacing(10) form.addRow(self.download_threads_lb, self.download_threads_var) form.addRow(self.timeout_lb, self.timeout_var) form.addRow(self.max_size_lb, self.max_size_var) form.addRow(self.dl_path_lb, self.dl_path_var) vbox = QVBoxLayout() vbox.addWidget(logo) vbox.addStretch(1) vbox.addLayout(form) vbox.addStretch(1) hbox = QHBoxLayout() hbox.addWidget(self.time_fmt_box) hbox.addWidget(self.to_tray_box) vbox.addLayout(hbox) vbox.addStretch(1) vbox.addWidget(buttonBox) self.setLayout(vbox) self.setMinimumWidth(500)
class ModeShiftDialog(QDialog): def __init__(self, parent=None): super(ModeShiftDialog, self).__init__(parent) mainLayout = QGridLayout() self.setLayout(mainLayout) self.keyLabel = QLabel() self.keyInput = QLineEdit() self.modeCombo = QComboBox() self.modeLabel = QLabel() self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) userguide.addButton(self.buttons, "mode_shift") for m in sorted(modes.keys()): self.modeCombo.addItem(m) mainLayout.addWidget(self.keyLabel, 0, 0, 1, 1) mainLayout.addWidget(self.keyInput, 0, 1, 1, 1) mainLayout.addWidget(self.modeLabel, 1, 0, 1, 1) mainLayout.addWidget(self.modeCombo, 1, 1, 1, 1) mainLayout.addWidget(self.buttons, 9, 0, 2, 2) app.translateUI(self) qutil.saveDialogSize(self, "mode_shift/dialog/size", QSize(80, 60)) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) self.keyInput.textEdited.connect(self.readKeyInput) self.modeCombo.currentIndexChanged.connect(self.readSettings) self.loadSettings() def translateUI(self): self.setWindowTitle(app.caption(_("Mode Shift"))) self.keyLabel.setText(_("Key:")) self.modeLabel.setText(_("Mode:")) self.buttons.button(QDialogButtonBox.Ok).setText(_("shift pitches")) self.buttons.button(QDialogButtonBox.Ok).setEnabled(False) def setKeyValidator(self, validate): """Set function that validates the key input.""" keyValidator = KeyValidator() keyValidator.setValidateFunc(validate) self.keyInput.setValidator(keyValidator) def readSettings(self): """Reads the current settings.""" self._currentKey = self.keyInput.text() self._currentMode = self.modeCombo.currentText() def readKeyInput(self): """Read the key input and check if it's acceptable.""" if self.keyInput.hasAcceptableInput(): self.readSettings() self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) else: self.buttons.button(QDialogButtonBox.Ok).setEnabled(False) def getMode(self): """Returns the chosen mode.""" return self._currentKey, modes[self._currentMode] def loadSettings(self): """ get users previous settings """ s = QSettings() s.beginGroup('mode_shift') key = s.value('key', "", str) self.keyInput.setText(key) index = s.value('mode', 0, int) self.modeCombo.setCurrentIndex(index) self.readKeyInput() def saveSettings(self): """ save users last settings """ s = QSettings() s.beginGroup('mode_shift') s.setValue('key', self._currentKey) s.setValue('mode', self.modeCombo.currentIndex())
class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self._info = None self._text = '' self._convertedtext = '' self._encoding = None self.mainwindow = parent self.fromVersionLabel = QLabel() self.fromVersion = QLineEdit() self.reason = QLabel() self.toVersionLabel = QLabel() self.toVersion = QLineEdit() self.lilyChooser = lilychooser.LilyChooser() self.messages = QTextBrowser() self.diff = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap) self.uni_diff = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap) self.copyCheck = QCheckBox(checked= QSettings().value('convert_ly/copy_messages', True, bool)) self.tabw = QTabWidget() self.tabw.addTab(self.messages, '') self.tabw.addTab(self.diff, '') self.tabw.addTab(self.uni_diff, '') self.buttons = QDialogButtonBox( QDialogButtonBox.Reset | QDialogButtonBox.Save | QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).clicked .connect(self.accept) self.buttons.rejected.connect(self.reject) self.buttons.button(QDialogButtonBox.Reset).clicked.connect(self.run) self.buttons.button(QDialogButtonBox.Save).clicked.connect(self.saveFile) layout = QVBoxLayout() self.setLayout(layout) grid = QGridLayout() grid.addWidget(self.fromVersionLabel, 0, 0) grid.addWidget(self.fromVersion, 0, 1) grid.addWidget(self.reason, 0, 2, 1, 3) grid.addWidget(self.toVersionLabel, 1, 0) grid.addWidget(self.toVersion, 1, 1) grid.addWidget(self.lilyChooser, 1, 3, 1, 2) layout.addLayout(grid) layout.addWidget(self.tabw) layout.addWidget(self.copyCheck) layout.addWidget(widgets.Separator()) layout.addWidget(self.buttons) app.translateUI(self) qutil.saveDialogSize(self, 'convert_ly/dialog/size', QSize(600, 300)) app.settingsChanged.connect(self.readSettings) self.readSettings() self.finished.connect(self.saveCopyCheckSetting) self.lilyChooser.currentIndexChanged.connect(self.slotLilyPondVersionChanged) self.slotLilyPondVersionChanged() def translateUI(self): self.fromVersionLabel.setText(_("From version:")) self.toVersionLabel.setText(_("To version:")) self.copyCheck.setText(_("Save convert-ly messages in document")) self.copyCheck.setToolTip(_( "If checked, the messages of convert-ly are appended as a " "comment to the end of the document.")) self.tabw.setTabText(0, _("&Messages")) self.tabw.setTabText(1, _("&Changes")) self.tabw.setTabText(2, _("&Diff")) self.buttons.button(QDialogButtonBox.Reset).setText(_("Run Again")) self.buttons.button(QDialogButtonBox.Save).setText(_("Save as file")) self.setCaption() def saveCopyCheckSetting(self): QSettings().setValue('convert_ly/copy_messages', self.copyCheck.isChecked()) def readSettings(self): font = textformats.formatData('editor').font self.diff.setFont(font) diffFont = QFont("Monospace") diffFont.setStyleHint(QFont.TypeWriter) self.uni_diff.setFont(diffFont) def slotLilyPondVersionChanged(self): self.setLilyPondInfo(self.lilyChooser.lilyPondInfo()) def setCaption(self): version = self._info and self._info.versionString() or _("<unknown>") title = _("Convert-ly from LilyPond {version}").format(version=version) self.setWindowTitle(app.caption(title)) def setLilyPondInfo(self, info): self._info = info self.setCaption() self.toVersion.setText(info.versionString()) self.setConvertedText() self.setDiffText() self.messages.clear() def setConvertedText(self, text=''): self._convertedtext = text self.buttons.button(QDialogButtonBox.Ok).setEnabled(bool(text)) if text: self.diff.setHtml(htmldiff.htmldiff( self._text, text, _("Current Document"), _("Converted Document"), wrapcolumn=100)) else: self.diff.clear() def setDiffText(self, text=''): if text: from_filename = "current" # TODO: maybe use real filename here to_filename = "converted" # but difflib can choke on non-ascii characters, # see https://github.com/wbsoft/frescobaldi/issues/674 difflist = list(difflib.unified_diff( self._text.split('\n'), text.split('\n'), from_filename, to_filename)) diffHLstr = self.diffHighl(difflist) self.uni_diff.setHtml(diffHLstr) else: self.uni_diff.clear() def convertedText(self): return self._convertedtext or '' def setDocument(self, doc): v = documentinfo.docinfo(doc).version_string() if v: self.fromVersion.setText(v) self.reason.setText(_("(set in document)")) else: self.reason.clear() self._text = doc.toPlainText() self._encoding = doc.encoding() or 'UTF-8' self.setConvertedText() self.setDiffText() def run(self): """Runs convert-ly (again).""" fromVersion = self.fromVersion.text() toVersion = self.toVersion.text() if not fromVersion or not toVersion: self.messages.setPlainText(_( "Both 'from' and 'to' versions need to be set.")) return info = self._info command = info.toolcommand(info.ly_tool('convert-ly')) command += ['-f', fromVersion, '-t', toVersion, '-'] # if the user wants english messages, do it also here: LANGUAGE=C env = None if os.name == "nt": # Python 2.7 subprocess on Windows chokes on unicode in env env = util.bytes_environ() else: env = dict(os.environ) if sys.platform.startswith('darwin'): try: del env['PYTHONHOME'] except KeyError: pass try: del env['PYTHONPATH'] except KeyError: pass if QSettings().value("lilypond_settings/no_translation", False, bool): if os.name == "nt": # Python 2.7 subprocess on Windows chokes on unicode in env env[b'LANGUAGE'] = b'C' else: env['LANGUAGE'] = 'C' with qutil.busyCursor(): try: proc = subprocess.Popen(command, env = env, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE) out, err = proc.communicate(util.platform_newlines(self._text).encode(self._encoding)) except OSError as e: self.messages.setPlainText(_( "Could not start {convert_ly}:\n\n" "{message}\n").format(convert_ly = command[0], message = e)) return out = util.universal_newlines(out.decode('UTF-8')) err = util.universal_newlines(err.decode('UTF-8')) self.messages.setPlainText(err) self.setConvertedText(out) self.setDiffText(out) if not out or self._convertedtext == self._text: self.messages.append('\n' + _("The document has not been changed.")) def saveFile(self): """Save content in tab as file""" tabdata = self.getTabData(self.tabw.currentIndex()) doc = self.mainwindow.currentDocument() orgname = doc.url().toLocalFile() filename = os.path.splitext(orgname)[0] + '['+tabdata.filename+']'+'.'+tabdata.ext caption = app.caption(_("dialog title", "Save File")) filetypes = '{0} (*.txt);;{1} (*.htm);;{2} (*)'.format(_("Text Files"), _("HTML Files"), _("All Files")) filename = QFileDialog.getSaveFileName(self.mainwindow, caption, filename, filetypes)[0] if not filename: return False # cancelled with open(filename, 'wb') as f: f.write(tabdata.text.encode('utf-8')) def getTabData(self, index): """Get content of current tab from current index""" if index == 0: return FileInfo('message', 'txt', self.messages.toPlainText()) elif index == 1: return FileInfo('html-diff', 'html', self.diff.toHtml()) elif index == 2: return FileInfo('uni-diff', 'diff', self.uni_diff.toPlainText()) def diffHighl(self, difflist): """Return highlighted version of input.""" result = [] for l in difflist: if l.startswith('-'): s = '<span style="color: red; white-space: pre-wrap;">' elif l.startswith('+'): s = '<span style="color: green; white-space: pre-wrap;">' else: s = '<span style="white-space: pre-wrap;">' h = l.replace('&', '&').replace('<', '<').replace('>', '>') result.append(s + h + '</span>') return '<br>'.join(result)
class RenameDialog(QDialog): out = pyqtSignal(object) def __init__(self, parent=None): super(RenameDialog, self).__init__(parent) self.infos = None self.min_width = 400 self.initUI() self.update_text() self.setStyleSheet(dialog_qss_style) def set_values(self, infos): self.infos = infos self.update_text() # 更新界面 def initUI(self): self.setWindowIcon(QIcon("./src/desc.ico")) self.lb_name = QLabel() self.lb_name.setText("文件夹名:") self.lb_name.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.tx_name = QLineEdit() self.lb_desc = QLabel() self.tx_desc = QTextEdit() self.lb_desc.setText("描 述:") self.lb_desc.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setText("确定") self.buttonBox.button(QDialogButtonBox.Cancel).setText("取消") self.grid = QGridLayout() self.grid.setSpacing(10) self.grid.addWidget(self.lb_name, 1, 0) self.grid.addWidget(self.tx_name, 1, 1) self.grid.addWidget(self.lb_desc, 2, 0) self.grid.addWidget(self.tx_desc, 2, 1, 5, 1) self.grid.addWidget(self.buttonBox, 7, 1, 1, 1) self.setLayout(self.grid) self.buttonBox.accepted.connect(self.btn_ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def update_text(self): if self.infos: self.buttonBox.button(QDialogButtonBox.Ok).setToolTip( "") # 去除新建文件夹影响 self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( True) # 去除新建文件夹影响 self.setWindowTitle("修改文件夹名与描述") self.tx_name.setText(str(self.infos[1])) if self.infos[6]: self.tx_desc.setText(str(self.infos[6])) self.tx_desc.setToolTip('原描述:' + str(self.infos[6])) else: self.tx_desc.setText("无") self.tx_desc.setToolTip('') self.tx_desc.setPlaceholderText("无") self.min_width = len(str(self.infos[1])) * 8 if self.infos[2]: # 文件无法重命名,由 infos[2] size表示文件 self.setWindowTitle("修改文件描述") self.tx_name.setFocusPolicy(Qt.NoFocus) self.tx_name.setReadOnly(True) else: self.tx_name.setFocusPolicy(Qt.StrongFocus) self.tx_name.setReadOnly(False) else: self.setWindowTitle("新建文件夹") self.tx_name.setText("") self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Ok).setToolTip("请先输入文件名!") self.tx_name.textChanged.connect(self.slot_new_ok_btn) self.tx_name.setPlaceholderText("不支持空格,如有会被自动替换成 _") self.tx_name.setFocusPolicy(Qt.StrongFocus) self.tx_name.setReadOnly(False) self.tx_desc.setPlaceholderText("可选项,建议160字数以内。") if self.min_width < 400: self.min_width = 400 self.resize(self.min_width, 200) def slot_new_ok_btn(self): """新建文件夹槽函数""" self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Ok).setToolTip("") def btn_ok(self): new_name = self.tx_name.text() new_desc = self.tx_desc.toPlainText() if not self.infos: # 在 work_id 新建文件夹 if new_name: self.out.emit(("new", "", new_name, new_desc)) else: return elif new_name != self.infos[1] or new_desc != self.infos[6]: if self.infos[2]: # 文件 self.out.emit(("file", self.infos[0], new_name, new_desc)) else: self.out.emit(("folder", self.infos[0], new_name, new_desc))
class ConfigurationWidget(QWidget): """ Class implementing a dialog for the configuration of eric6. @signal preferencesChanged() emitted after settings have been changed @signal masterPasswordChanged(str, str) emitted after the master password has been changed with the old and the new password @signal accepted() emitted to indicate acceptance of the changes @signal rejected() emitted to indicate rejection of the changes """ preferencesChanged = pyqtSignal() masterPasswordChanged = pyqtSignal(str, str) accepted = pyqtSignal() rejected = pyqtSignal() DefaultMode = 0 HelpBrowserMode = 1 TrayStarterMode = 2 HexEditorMode = 3 def __init__(self, parent=None, fromEric=True, displayMode=DefaultMode, expandedEntries=[]): """ Constructor @param parent The parent widget of this dialog. (QWidget) @keyparam fromEric flag indicating a dialog generation from within the eric6 ide (boolean) @keyparam displayMode mode of the configuration dialog (DefaultMode, HelpBrowserMode, TrayStarterMode, HexEditorMode) @exception RuntimeError raised to indicate an invalid dialog mode @keyparam expandedEntries list of entries to be shown expanded (list of strings) """ assert displayMode in ( ConfigurationWidget.DefaultMode, ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode, ConfigurationWidget.HexEditorMode, ) super(ConfigurationWidget, self).__init__(parent) self.fromEric = fromEric self.displayMode = displayMode self.__setupUi() self.itmDict = {} if not fromEric: from PluginManager.PluginManager import PluginManager try: self.pluginManager = e5App().getObject("PluginManager") except KeyError: self.pluginManager = PluginManager(self) e5App().registerObject("PluginManager", self.pluginManager) if displayMode == ConfigurationWidget.DefaultMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "applicationPage": [self.tr("Application"), "preferences-application.png", "ApplicationPage", None, None], "cooperationPage": [self.tr("Cooperation"), "preferences-cooperation.png", "CooperationPage", None, None], "corbaPage": [self.tr("CORBA"), "preferences-orbit.png", "CorbaPage", None, None], "emailPage": [self.tr("Email"), "preferences-mail_generic.png", "EmailPage", None, None], "graphicsPage": [self.tr("Graphics"), "preferences-graphics.png", "GraphicsPage", None, None], "hexEditorPage": [self.tr("Hex Editor"), "hexEditor.png", "HexEditorPage", None, None], "iconsPage": [self.tr("Icons"), "preferences-icons.png", "IconsPage", None, None], "ircPage": [self.tr("IRC"), "irc.png", "IrcPage", None, None], "logViewerPage": [self.tr("Log-Viewer"), "preferences-logviewer.png", "LogViewerPage", None, None], "mimeTypesPage": [self.tr("Mimetypes"), "preferences-mimetypes.png", "MimeTypesPage", None, None], "networkPage": [self.tr("Network"), "preferences-network.png", "NetworkPage", None, None], "notificationsPage": [self.tr("Notifications"), "preferences-notifications.png", "NotificationsPage", None, None], "pluginManagerPage": [self.tr("Plugin Manager"), "preferences-pluginmanager.png", "PluginManagerPage", None, None], "printerPage": [self.tr("Printer"), "preferences-printer.png", "PrinterPage", None, None], "pythonPage": [self.tr("Python"), "preferences-python.png", "PythonPage", None, None], "qtPage": [self.tr("Qt"), "preferences-qtlogo.png", "QtPage", None, None], "securityPage": [self.tr("Security"), "preferences-security.png", "SecurityPage", None, None], "shellPage": [self.tr("Shell"), "preferences-shell.png", "ShellPage", None, None], "tasksPage": [self.tr("Tasks"), "task.png", "TasksPage", None, None], "templatesPage": [self.tr("Templates"), "preferences-template.png", "TemplatesPage", None, None], "trayStarterPage": [self.tr("Tray Starter"), "erict.png", "TrayStarterPage", None, None], "vcsPage": [self.tr("Version Control Systems"), "preferences-vcs.png", "VcsPage", None, None], "0debuggerPage": [self.tr("Debugger"), "preferences-debugger.png", None, None, None], "debuggerGeneralPage": [self.tr("General"), "preferences-debugger.png", "DebuggerGeneralPage", "0debuggerPage", None], "debuggerPythonPage": [self.tr("Python"), "preferences-pyDebugger.png", "DebuggerPythonPage", "0debuggerPage", None], "debuggerPython3Page": [self.tr("Python3"), "preferences-pyDebugger.png", "DebuggerPython3Page", "0debuggerPage", None], "0editorPage": [self.tr("Editor"), "preferences-editor.png", None, None, None], "editorAPIsPage": [self.tr("APIs"), "preferences-api.png", "EditorAPIsPage", "0editorPage", None], "editorAutocompletionPage": [self.tr("Autocompletion"), "preferences-autocompletion.png", "EditorAutocompletionPage", "0editorPage", None], "editorAutocompletionQScintillaPage": [self.tr("QScintilla"), "qscintilla.png", "EditorAutocompletionQScintillaPage", "editorAutocompletionPage", None], "editorCalltipsPage": [self.tr("Calltips"), "preferences-calltips.png", "EditorCalltipsPage", "0editorPage", None], "editorCalltipsQScintillaPage": [self.tr("QScintilla"), "qscintilla.png", "EditorCalltipsQScintillaPage", "editorCalltipsPage", None], "editorGeneralPage": [self.tr("General"), "preferences-general.png", "EditorGeneralPage", "0editorPage", None], "editorFilePage": [self.tr("Filehandling"), "preferences-filehandling.png", "EditorFilePage", "0editorPage", None], "editorSearchPage": [self.tr("Searching"), "preferences-search.png", "EditorSearchPage", "0editorPage", None], "editorSpellCheckingPage": [self.tr("Spell checking"), "preferences-spellchecking.png", "EditorSpellCheckingPage", "0editorPage", None], "editorStylesPage": [self.tr("Style"), "preferences-styles.png", "EditorStylesPage", "0editorPage", None], "editorSyntaxPage": [self.tr("Code Checkers"), "preferences-debugger.png", "EditorSyntaxPage", "0editorPage", None], "editorTypingPage": [self.tr("Typing"), "preferences-typing.png", "EditorTypingPage", "0editorPage", None], "editorExportersPage": [self.tr("Exporters"), "preferences-exporters.png", "EditorExportersPage", "0editorPage", None], "1editorLexerPage": [self.tr("Highlighters"), "preferences-highlighting-styles.png", None, "0editorPage", None], "editorHighlightersPage": [self.tr("Filetype Associations"), "preferences-highlighter-association.png", "EditorHighlightersPage", "1editorLexerPage", None], "editorHighlightingStylesPage": [self.tr("Styles"), "preferences-highlighting-styles.png", "EditorHighlightingStylesPage", "1editorLexerPage", None], "editorKeywordsPage": [self.tr("Keywords"), "preferences-keywords.png", "EditorKeywordsPage", "1editorLexerPage", None], "editorPropertiesPage": [self.tr("Properties"), "preferences-properties.png", "EditorPropertiesPage", "1editorLexerPage", None], "1editorMouseClickHandlers": [self.tr("Mouse Click Handlers"), "preferences-mouse-click-handler.png", "EditorMouseClickHandlerPage", "0editorPage", None], "0helpPage": [self.tr("Help"), "preferences-help.png", None, None, None], "helpDocumentationPage": [self.tr("Help Documentation"), "preferences-helpdocumentation.png", "HelpDocumentationPage", "0helpPage", None], "helpViewersPage": [self.tr("Help Viewers"), "preferences-helpviewers.png", "HelpViewersPage", "0helpPage", None], "0projectPage": [self.tr("Project"), "preferences-project.png", None, None, None], "projectBrowserPage": [self.tr("Project Viewer"), "preferences-project.png", "ProjectBrowserPage", "0projectPage", None], "projectPage": [self.tr("Project"), "preferences-project.png", "ProjectPage", "0projectPage", None], "multiProjectPage": [self.tr("Multiproject"), "preferences-multiproject.png", "MultiProjectPage", "0projectPage", None], "0interfacePage": [self.tr("Interface"), "preferences-interface.png", None, None, None], "interfacePage": [self.tr("Interface"), "preferences-interface.png", "InterfacePage", "0interfacePage", None], "viewmanagerPage": [self.tr("Viewmanager"), "preferences-viewmanager.png", "ViewmanagerPage", "0interfacePage", None], } try: from PyQt5 import QtWebKit # __IGNORE_WARNING__ self.configItems.update({ "helpAppearancePage": [self.tr("Appearance"), "preferences-styles.png", "HelpAppearancePage", "0helpPage", None], "helpFlashCookieManagerPage": [self.tr("Flash Cookie Manager"), "flashCookie16.png", "HelpFlashCookieManagerPage", "0helpPage", None], "helpVirusTotalPage": [self.tr("VirusTotal Interface"), "virustotal.png", "HelpVirusTotalPage", "0helpPage", None], "helpWebBrowserPage": [self.tr("eric6 Web Browser"), "ericWeb.png", "HelpWebBrowserPage", "0helpPage", None], }) except ImportError: pass self.configItems.update( e5App().getObject("PluginManager").getPluginConfigData()) elif displayMode == ConfigurationWidget.HelpBrowserMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "interfacePage": [self.tr("Interface"), "preferences-interface.png", "HelpInterfacePage", None, None], "networkPage": [self.tr("Network"), "preferences-network.png", "NetworkPage", None, None], "printerPage": [self.tr("Printer"), "preferences-printer.png", "PrinterPage", None, None], "securityPage": [self.tr("Security"), "preferences-security.png", "SecurityPage", None, None], "0helpPage": [self.tr("Help"), "preferences-help.png", None, None, None], "helpDocumentationPage": [self.tr("Help Documentation"), "preferences-helpdocumentation.png", "HelpDocumentationPage", "0helpPage", None], } try: from PyQt5 import QtWebKit # __IGNORE_WARNING__ self.configItems.update({ "helpAppearancePage": [self.tr("Appearance"), "preferences-styles.png", "HelpAppearancePage", "0helpPage", None], "helpFlashCookieManagerPage": [self.tr("Flash Cookie Manager"), "flashCookie16.png", "HelpFlashCookieManagerPage", "0helpPage", None], "helpVirusTotalPage": [self.tr("VirusTotal Interface"), "virustotal.png", "HelpVirusTotalPage", "0helpPage", None], "helpWebBrowserPage": [self.tr("eric6 Web Browser"), "ericWeb.png", "HelpWebBrowserPage", "0helpPage", None], }) except ImportError: pass elif displayMode == ConfigurationWidget.TrayStarterMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "trayStarterPage": [self.tr("Tray Starter"), "erict.png", "TrayStarterPage", None, None], } elif displayMode == ConfigurationWidget.HexEditorMode: self.configItems = { # key : [display string, pixmap name, dialog module name or # page creation function, parent key, # reference to configuration page (must always be last)] # The dialog module must have the module function 'create' to # create the configuration page. This must have the method # 'save' to save the settings. "hexEditorPage": [self.tr("Hex Editor"), "hexEditor.png", "HexEditorPage", None, None], } else: raise RuntimeError("Illegal mode value: {0}".format(displayMode)) # generate the list entries self.__expandedEntries = [] for key in sorted(self.configItems.keys()): pageData = self.configItems[key] if pageData[3]: if pageData[3] in self.itmDict: pitm = self.itmDict[pageData[3]] # get the parent item else: continue else: pitm = self.configList self.itmDict[key] = ConfigurationPageItem(pitm, pageData[0], key, pageData[1]) self.itmDict[key].setData(0, Qt.UserRole, key) if (not self.fromEric or displayMode != ConfigurationWidget.DefaultMode or key in expandedEntries): self.itmDict[key].setExpanded(True) self.configList.sortByColumn(0, Qt.AscendingOrder) # set the initial size of the splitter self.configSplitter.setSizes([200, 600]) self.configList.itemActivated.connect(self.__showConfigurationPage) self.configList.itemClicked.connect(self.__showConfigurationPage) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.rejected) if displayMode in [ConfigurationWidget.HelpBrowserMode, ConfigurationWidget.TrayStarterMode, ConfigurationWidget.HexEditorMode]: self.configListSearch.hide() if displayMode not in [ConfigurationWidget.TrayStarterMode, ConfigurationWidget.HexEditorMode]: self.__initLexers() def accept(self): """ Public slot to accept the buttonBox accept signal. """ if not isMacPlatform(): wdg = self.focusWidget() if wdg == self.configList: return self.accepted.emit() def __setupUi(self): """ Private method to perform the general setup of the configuration widget. """ self.setObjectName("ConfigurationDialog") self.resize(900, 650) self.verticalLayout_2 = QVBoxLayout(self) self.verticalLayout_2.setSpacing(6) self.verticalLayout_2.setContentsMargins(6, 6, 6, 6) self.verticalLayout_2.setObjectName("verticalLayout_2") self.configSplitter = QSplitter(self) self.configSplitter.setOrientation(Qt.Horizontal) self.configSplitter.setObjectName("configSplitter") self.configListWidget = QWidget(self.configSplitter) self.leftVBoxLayout = QVBoxLayout(self.configListWidget) self.leftVBoxLayout.setContentsMargins(0, 0, 0, 0) self.leftVBoxLayout.setSpacing(0) self.leftVBoxLayout.setObjectName("leftVBoxLayout") self.configListSearch = E5ClearableLineEdit( self, self.tr("Enter search text...")) self.configListSearch.setObjectName("configListSearch") self.leftVBoxLayout.addWidget(self.configListSearch) self.configList = QTreeWidget() self.configList.setObjectName("configList") self.leftVBoxLayout.addWidget(self.configList) self.configListSearch.textChanged.connect(self.__searchTextChanged) self.scrollArea = QScrollArea(self.configSplitter) self.scrollArea.setFrameShape(QFrame.NoFrame) self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scrollArea.setWidgetResizable(False) self.scrollArea.setObjectName("scrollArea") self.configStack = QStackedWidget() self.configStack.setFrameShape(QFrame.Box) self.configStack.setFrameShadow(QFrame.Sunken) self.configStack.setObjectName("configStack") self.scrollArea.setWidget(self.configStack) self.emptyPage = QWidget() self.emptyPage.setGeometry(QRect(0, 0, 372, 591)) self.emptyPage.setObjectName("emptyPage") self.vboxlayout = QVBoxLayout(self.emptyPage) self.vboxlayout.setSpacing(6) self.vboxlayout.setContentsMargins(6, 6, 6, 6) self.vboxlayout.setObjectName("vboxlayout") spacerItem = QSpacerItem( 20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem) self.emptyPagePixmap = QLabel(self.emptyPage) self.emptyPagePixmap.setAlignment(Qt.AlignCenter) self.emptyPagePixmap.setObjectName("emptyPagePixmap") self.emptyPagePixmap.setPixmap( QPixmap(os.path.join(getConfig('ericPixDir'), 'eric.png'))) self.vboxlayout.addWidget(self.emptyPagePixmap) self.textLabel1 = QLabel(self.emptyPage) self.textLabel1.setAlignment(Qt.AlignCenter) self.textLabel1.setObjectName("textLabel1") self.vboxlayout.addWidget(self.textLabel1) spacerItem1 = QSpacerItem( 20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem1) self.configStack.addWidget(self.emptyPage) self.verticalLayout_2.addWidget(self.configSplitter) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.Apply | QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Reset) self.buttonBox.setObjectName("buttonBox") if not self.fromEric and \ self.displayMode == ConfigurationWidget.DefaultMode: self.buttonBox.button(QDialogButtonBox.Apply).hide() self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False) self.verticalLayout_2.addWidget(self.buttonBox) self.setWindowTitle(self.tr("Preferences")) self.configList.header().hide() self.configList.header().setSortIndicator(0, Qt.AscendingOrder) self.configList.setSortingEnabled(True) self.textLabel1.setText( self.tr("Please select an entry of the list \n" "to display the configuration page.")) QMetaObject.connectSlotsByName(self) self.setTabOrder(self.configList, self.configStack) self.configStack.setCurrentWidget(self.emptyPage) self.configList.setFocus() def __searchTextChanged(self, text): """ Private slot to handle a change of the search text. @param text text to search for (string) """ self.__searchChildItems(self.configList.invisibleRootItem(), text) def __searchChildItems(self, parent, text): """ Private method to enable child items based on a search string. @param parent reference to the parent item (QTreeWidgetItem) @param text text to search for (string) @return flag indicating an enabled child item (boolean) """ childEnabled = False text = text.lower() for index in range(parent.childCount()): itm = parent.child(index) if itm.childCount() > 0: enable = self.__searchChildItems(itm, text) or \ text == "" or text in itm.text(0).lower() else: enable = text == "" or text in itm.text(0).lower() if enable: childEnabled = True itm.setDisabled(not enable) return childEnabled def __initLexers(self): """ Private method to initialize the dictionary of preferences lexers. """ import QScintilla.Lexers from .PreferencesLexer import PreferencesLexer, \ PreferencesLexerLanguageError self.lexers = {} for language in QScintilla.Lexers.getSupportedLanguages(): if language not in self.lexers: try: self.lexers[language] = PreferencesLexer(language, self) except PreferencesLexerLanguageError: pass def __importConfigurationPage(self, name): """ Private method to import a configuration page module. @param name name of the configuration page module (string) @return reference to the configuration page module """ modName = "Preferences.ConfigurationPages.{0}".format(name) try: mod = __import__(modName) components = modName.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod except ImportError: E5MessageBox.critical( self, self.tr("Configuration Page Error"), self.tr("""<p>The configuration page <b>{0}</b>""" """ could not be loaded.</p>""").format(name)) return None def __showConfigurationPage(self, itm, column): """ Private slot to show a selected configuration page. @param itm reference to the selected item (QTreeWidgetItem) @param column column that was selected (integer) (ignored) """ pageName = itm.getPageName() self.showConfigurationPageByName(pageName, setCurrent=False) def __initPage(self, pageData): """ Private method to initialize a configuration page. @param pageData data structure for the page to initialize @return reference to the initialized page """ page = None if isinstance(pageData[2], types.FunctionType): page = pageData[2](self) else: mod = self.__importConfigurationPage(pageData[2]) if mod: page = mod.create(self) if page is not None: self.configStack.addWidget(page) pageData[-1] = page try: page.setMode(self.displayMode) except AttributeError: pass return page def showConfigurationPageByName(self, pageName, setCurrent=True): """ Public slot to show a named configuration page. @param pageName name of the configuration page to show (string) @param setCurrent flag indicating to set the current item (boolean) """ if pageName == "empty" or pageName not in self.configItems: page = self.emptyPage else: pageData = self.configItems[pageName] if pageData[-1] is None and pageData[2] is not None: # the page was not loaded yet, create it page = self.__initPage(pageData) else: page = pageData[-1] if page is None: page = self.emptyPage elif setCurrent: items = self.configList.findItems( pageData[0], Qt.MatchFixedString | Qt.MatchRecursive) for item in items: if item.data(0, Qt.UserRole) == pageName: self.configList.setCurrentItem(item) self.configStack.setCurrentWidget(page) ssize = self.scrollArea.size() if self.scrollArea.horizontalScrollBar(): ssize.setHeight( ssize.height() - self.scrollArea.horizontalScrollBar().height() - 2) if self.scrollArea.verticalScrollBar(): ssize.setWidth( ssize.width() - self.scrollArea.verticalScrollBar().width() - 2) psize = page.minimumSizeHint() self.configStack.resize(max(ssize.width(), psize.width()), max(ssize.height(), psize.height())) if page != self.emptyPage: page.polishPage() self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(True) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(True) else: self.buttonBox.button(QDialogButtonBox.Apply).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Reset).setEnabled(False) # reset scrollbars for sb in [self.scrollArea.horizontalScrollBar(), self.scrollArea.verticalScrollBar()]: if sb: sb.setValue(0) self.__currentConfigurationPageName = pageName def getConfigurationPageName(self): """ Public method to get the page name of the current page. @return page name of the current page (string) """ return self.__currentConfigurationPageName def calledFromEric(self): """ Public method to check, if invoked from within eric. @return flag indicating invocation from within eric (boolean) """ return self.fromEric def getPage(self, pageName): """ Public method to get a reference to the named page. @param pageName name of the configuration page (string) @return reference to the page or None, indicating page was not loaded yet """ return self.configItems[pageName][-1] def getLexers(self): """ Public method to get a reference to the lexers dictionary. @return reference to the lexers dictionary """ return self.lexers def setPreferences(self): """ Public method called to store the selected values into the preferences storage. """ for key, pageData in list(self.configItems.items()): if pageData[-1]: pageData[-1].save() # page was loaded (and possibly modified) QApplication.processEvents() # ensure HMI is responsive def on_buttonBox_clicked(self, button): """ Private slot called by a button of the button box clicked. @param button button that was clicked (QAbstractButton) """ if button == self.buttonBox.button(QDialogButtonBox.Apply): self.on_applyButton_clicked() elif button == self.buttonBox.button(QDialogButtonBox.Reset): self.on_resetButton_clicked() @pyqtSlot() def on_applyButton_clicked(self): """ Private slot called to apply the settings of the current page. """ if self.configStack.currentWidget() != self.emptyPage: page = self.configStack.currentWidget() savedState = page.saveState() page.save() self.preferencesChanged.emit() if savedState is not None: page.setState(savedState) page.polishPage() @pyqtSlot() def on_resetButton_clicked(self): """ Private slot called to reset the settings of the current page. """ if self.configStack.currentWidget() != self.emptyPage: currentPage = self.configStack.currentWidget() savedState = currentPage.saveState() pageName = self.configList.currentItem().getPageName() self.configStack.removeWidget(currentPage) if pageName == "editorHighlightingStylesPage": self.__initLexers() self.configItems[pageName][-1] = None self.showConfigurationPageByName(pageName) if savedState is not None: self.configStack.currentWidget().setState(savedState) def getExpandedEntries(self): """ Public method to get a list of expanded entries. @return list of expanded entries (list of string) """ return self.__expandedEntries @pyqtSlot(QTreeWidgetItem) def on_configList_itemCollapsed(self, item): """ Private slot handling a list entry being collapsed. @param item reference to the collapsed item (QTreeWidgetItem) """ pageName = item.data(0, Qt.UserRole) if pageName in self.__expandedEntries: self.__expandedEntries.remove(pageName) @pyqtSlot(QTreeWidgetItem) def on_configList_itemExpanded(self, item): """ Private slot handling a list entry being expanded. @param item reference to the expanded item (QTreeWidgetItem) """ pageName = item.data(0, Qt.UserRole) if pageName not in self.__expandedEntries: self.__expandedEntries.append(pageName)