class PageProjectType(QWizardPage): def __init__(self, wizard): super(PageProjectType, self).__init__() self.setTitle(_translate("PageProjectType", "Project Type")) self.setSubTitle(_translate("PageProjectType", "Choose the Project Type")) self._wizard = wizard vbox = QVBoxLayout(self) self.listWidget = QListWidget() vbox.addWidget(self.listWidget) types = settings.get_all_project_types() types.sort() index = types.index('Python') types.insert(0, types.pop(index)) self.listWidget.addItems(types) self.listWidget.setCurrentRow(0) self.listWidget.itemClicked['QListWidgetItem*'].connect(self.load_pages) def validatePage(self): self._wizard.option = self.listWidget.currentItem().text() return True def load_pages(self): self.wizard().add_project_pages(self.listWidget.currentItem().text())
class NapalmInterfaces(QWidget): napalm_actions = ( 'Interfaces', 'Interface IP', 'Interfaces counters', ) @update_paths def __init__(self, node, controller): super().__init__() self.node = node action_label = QLabel('Action') object_label = QLabel('Object') self.object_list = QListWidget() self.object_list.setSortingEnabled(True) self.object_list.itemSelectionChanged.connect(self.text_update) self.action_list = QListWidget() self.action_list.setSortingEnabled(True) self.action_list.itemSelectionChanged.connect(self.text_update) self.action_list.addItems(self.napalm_actions) self.properties_edit = QConsoleEdit() self.properties_edit.setMinimumSize(300, 300) layout = QGridLayout() layout.addWidget(object_label, 0, 0) layout.addWidget(self.object_list, 1, 0) layout.addWidget(action_label, 0, 1) layout.addWidget(self.action_list, 1, 1) layout.addWidget(self.properties_edit, 2, 0, 1, 2) self.setLayout(layout) def update(self): self.object_list.clear() if 'Interfaces' in self.node.napalm_data: self.object_list.addItems(self.node.napalm_data['Interfaces']) def text_update(self): action = self.action_list.currentItem() object = self.object_list.currentItem() if action and object: self.properties_edit.clear() # we display a dictionnary with the following format: # property1: value1 # property2: value2 action, object = action.text(), object.text() value = str_dict(self.node.napalm_data[action][object]) self.properties_edit.insertPlainText(value)
class SessionManager(QMainWindow): def __init__(self, parent=None): QListWidget.__init__(self, parent) self.setWindowTitle(tr("Saved Sessions")) self.setWindowFlags(Qt.Dialog) hideAction = QAction(self) hideAction.setShortcuts(["Esc", "Ctrl+W"]) hideAction.triggered.connect(self.hide) self.addAction(hideAction) self.sessionList = QListWidget(self) self.sessionList.itemActivated.connect(self.loadSession) self.setCentralWidget(self.sessionList) self.toolBar = QToolBar(self) self.toolBar.setMovable(False) self.toolBar.setContextMenuPolicy(Qt.CustomContextMenu) self.addToolBar(Qt.BottomToolBarArea, self.toolBar) self.loadButton = QPushButton(tr("&Load"), self) self.loadButton.clicked.connect(lambda: self.loadSession(self.sessionList.currentItem())) self.toolBar.addWidget(self.loadButton) self.saveButton = QPushButton(tr("&Save"), self) self.saveButton.clicked.connect(saveSessionManually) self.saveButton.clicked.connect(self.refresh) self.toolBar.addWidget(self.saveButton) deleteAction = QAction(self) deleteAction.setShortcut("Del") deleteAction.triggered.connect(self.delete) self.addAction(deleteAction) def refresh(self): self.sessionList.clear() if os.path.exists(settings.session_folder): sessions = os.listdir(settings.session_folder) for session in sessions: self.sessionList.addItem(session) def delete(self): if self.sessionList.hasFocus(): try: os.remove(os.path.join(settings.session_folder, self.sessionList.currentItem().text())) except: pass self.refresh() def show(self): self.refresh() QMainWindow.show(self) def loadSession(self, item): if os.path.exists(settings.session_folder): loadSession(os.path.join(settings.session_folder, item.text())) self.hide()
class ModeSelector(QDialog): """ Defines a UI for selecting the mode for Mu. """ def __init__(self, parent=None): super().__init__(parent) def setup(self, modes, current_mode): self.setMinimumSize(600, 400) self.setWindowTitle(_('Select Mode')) widget_layout = QVBoxLayout() label = QLabel(_('Please select the desired mode then click "OK". ' 'Otherwise, click "Cancel".')) label.setWordWrap(True) widget_layout.addWidget(label) self.setLayout(widget_layout) self.mode_list = QListWidget() self.mode_list.itemDoubleClicked.connect(self.select_and_accept) widget_layout.addWidget(self.mode_list) self.mode_list.setIconSize(QSize(48, 48)) for name, item in modes.items(): if not item.is_debugger: litem = ModeItem(item.name, item.description, item.icon, self.mode_list) if item.icon == current_mode: self.mode_list.setCurrentItem(litem) self.mode_list.sortItems() instructions = QLabel(_('Change mode at any time by clicking ' 'the "Mode" button containing Mu\'s logo.')) instructions.setWordWrap(True) widget_layout.addWidget(instructions) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) widget_layout.addWidget(button_box) def select_and_accept(self): """ Handler for when an item is double-clicked. """ self.accept() def get_mode(self): """ Return details of the newly selected mode. """ if self.result() == QDialog.Accepted: return self.mode_list.currentItem().icon else: raise RuntimeError('Mode change cancelled.')
class ModeSelector(QDialog): """ Defines a UI for selecting the mode for Mu. """ def setup(self, modes, current_mode, theme): if theme == 'day': self.setStyleSheet(DAY_STYLE) elif theme == 'night': self.setStyleSheet(NIGHT_STYLE) else: self.setStyleSheet(CONTRAST_STYLE) self.setMinimumSize(600, 400) self.setWindowTitle(_('Select Mode')) widget_layout = QVBoxLayout() label = QLabel(_('Please select the desired mode then click "OK". ' 'Otherwise, click "Cancel".')) label.setWordWrap(True) widget_layout.addWidget(label) self.setLayout(widget_layout) self.mode_list = QListWidget() widget_layout.addWidget(self.mode_list) self.mode_list.setIconSize(QSize(48, 48)) for name, item in modes.items(): if not item.is_debugger: ModeItem(item.name, item.description, item.icon, self.mode_list) self.mode_list.sortItems() instructions = QLabel(_('You can change mode at any time by clicking ' 'the name of the current mode shown in the ' 'bottom right-hand corner of Mu.')) instructions.setWordWrap(True) widget_layout.addWidget(instructions) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) widget_layout.addWidget(button_box) def get_mode(self): """ Return details of the newly selected mode. """ if self.result() == QDialog.Accepted: return self.mode_list.currentItem().icon else: raise RuntimeError('Mode change cancelled.')
class JavaScriptExceptionsPanel(SettingsPanel): def __init__(self, parent=None): super(JavaScriptExceptionsPanel, self).__init__(parent) domainEntryRow = custom_widgets.LineEditRow(tr("Add domain:"), self) self.domainEntry = domainEntryRow.lineEdit self.domainEntry.returnPressed.connect(self.addDomain) self.layout().addWidget(domainEntryRow) self.addDomainButton = QPushButton(tr("Add")) self.addDomainButton.clicked.connect(self.addDomain) domainEntryRow.layout().addWidget(self.addDomainButton) self.domainList = QListWidget(self) self.layout().addWidget(self.domainList) self.removeDomainButton = QPushButton(tr("Remove")) self.removeDomainButton.clicked.connect(lambda: self.removeDomain(True)) self.layout().addWidget(self.removeDomainButton) self.removeAction = QAction(self) self.removeAction.setShortcut("Del") self.removeAction.triggered.connect(self.removeDomain) self.addAction(self.removeAction) def removeDomain(self, forceFocus=False): if self.domainList.hasFocus() or forceFocus: self.domainList.takeItem(self.domainList.row(self.domainList.currentItem())) def addDomain(self): self.domainList.addItem(self.domainEntry.text()) self.domainEntry.clear() def loadSettings(self): settings.js_exceptions = settings.setting_to_list("content/JavaScriptExceptions") self.domainList.clear() for f in settings.js_exceptions: self.domainList.addItem(f) def saveSettings(self): settings.js_exceptions = [self.domainList.item(f).text() for f in range(0, self.domainList.count())] settings.settings.setValue("content/JavaScriptExceptions", settings.js_exceptions) settings.settings.sync()
class AdremoverSettingsPanel(SettingsPanel): def __init__(self, parent=None): super(AdremoverSettingsPanel, self).__init__(parent) filterEntryRow = custom_widgets.LineEditRow(tr("Add filter:"), self) self.filterEntry = filterEntryRow.lineEdit self.filterEntry.returnPressed.connect(self.addFilter) self.layout().addWidget(filterEntryRow) self.addFilterButton = QPushButton(tr("Add")) self.addFilterButton.clicked.connect(self.addFilter) filterEntryRow.layout().addWidget(self.addFilterButton) # Ad Remover filter list. self.filterList = QListWidget(self) self.layout().addWidget(self.filterList) self.removeFilterButton = QPushButton(tr("Remove")) self.removeFilterButton.clicked.connect(lambda: self.removeFilter(True)) self.layout().addWidget(self.removeFilterButton) self.removeAction = QAction(self) self.removeAction.setShortcut("Del") self.removeAction.triggered.connect(self.removeFilter) self.addAction(self.removeAction) def removeFilter(self, forceFocus=False): if self.filterList.hasFocus() or forceFocus: self.filterList.takeItem(self.filterList.row(self.filterList.currentItem())) def addFilter(self): self.filterList.addItem(self.filterEntry.text()) self.filterEntry.clear() def loadSettings(self): settings.load_adremover_filters() self.filterList.clear() for f in settings.adremover_filters: self.filterList.addItem(f) def saveSettings(self): settings.adremover_filters = [self.filterList.item(f).text() for f in range(0, self.filterList.count())] settings.save_adremover_filters()
class PythonDetectDialog(QDialog): def __init__(self, suggested, parent=None): super(PythonDetectDialog, self).__init__(parent, Qt.Dialog) self.setMaximumSize(QSize(0, 0)) self.setWindowTitle("Configure Python Path") vbox = QVBoxLayout(self) msg_str = ("We have detected that you are using " "Windows,\nplease choose the proper " "Python application for you:") lblMessage = QLabel(self.tr(msg_str)) vbox.addWidget(lblMessage) self.listPaths = QListWidget() self.listPaths.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.listPaths) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btnCancel = QPushButton(self.tr("Cancel")) btnAccept = QPushButton(self.tr("Accept")) hbox.addWidget(btnCancel) hbox.addWidget(btnAccept) vbox.addLayout(hbox) btnAccept.clicked['bool'].connect(self._set_python_path) btnCancel.clicked['bool'].connect(self.close) for path in suggested: self.listPaths.addItem(path) self.listPaths.setCurrentRow(0) def _set_python_path(self): python_path = self.listPaths.currentItem().text() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) settings.PYTHON_PATH = python_path settings.PYTHON_EXEC = python_path settings.PYTHON_EXEC_CONFIGURED_BY_USER = True qsettings.setValue('preferences/execution/pythonExec', python_path) qsettings.setValue('preferences/execution/pythonExecConfigured', True) self.close()
class LanguageChooser(QDialog): newQM = QtCore.pyqtSignal(str) supportedLanguages = {'Español': 'es_ES', 'English': 'en_GB', 'Català': 'ca_ES'} def __init__(self, parent=None): super(LanguageChooser, self).__init__(parent) self.initUI() def initUI(self): self.setWindowTitle(i18n( "LanguageChooser", "Language")) self.widgetLayout = QVBoxLayout(self) self.infoLabel = QLabel(self) self.infoLabel.setText(i18n( "LanguageChooser", "Select the desired language:")) self.widgetLayout.addWidget(self.infoLabel) self.languageListWidget = QListWidget(self) self.widgetLayout.addWidget(self.languageListWidget) for language in self.supportedLanguages.keys(): self.languageListWidget.addItem(language) self.buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self) self.buttonBox.accepted.connect(self.changeLanguage) self.buttonBox.rejected.connect(self.close) self.widgetLayout.addWidget(self.buttonBox) def changeLanguage(self): ci = self.languageListWidget.currentItem() if ci: selected = ci.text() fname = self.supportedLanguages[selected] self.newQM.emit(fname) self.close()
class DataSettingsPanel(SettingsPanel): def __init__(self, parent=None): super(DataSettingsPanel, self).__init__(parent) # Clear history dialog. self.clearHistoryDialog = clear_history_dialog.ClearHistoryDialog(self) self.clearHistoryDialog.hide() self.showClearHistoryDialogButton = QPushButton(tr("Clear Data"), self) self.showClearHistoryDialogButton.clicked.connect(self.clearHistoryDialog.exec_) self.layout().addWidget(self.showClearHistoryDialogButton) # Remember history checkbox. self.rememberHistoryToggle = QCheckBox(tr("Remember &history"), self) self.layout().addWidget(self.rememberHistoryToggle) # Maximum URL length spinbox. self.maximumURLLengthRow = custom_widgets.SpinBoxRow(tr("Maximum URL length:"), self) self.maximumURLLengthRow.expander.setText(tr("characters")) self.maximumURLLength = self.maximumURLLengthRow.spinBox self.maximumURLLength.setMaximum(9999) self.layout().addWidget(self.maximumURLLengthRow) # Maximum cache size spinbox. # The cache is gone because it f***s Nimbus with a chainsaw. #self.maximumCacheSizeRow = custom_widgets.SpinBoxRow(tr("Maximum cache size:"), self) #self.maximumCacheSizeRow.expander.setText(tr("MB")) #self.maximumCacheSize = self.maximumCacheSizeRow.spinBox #self.maximumCacheSize.setMaximum(20000) #self.layout().addWidget(self.maximumCacheSizeRow) # Checkbox to toggle geolocation. self.geolocationToggle = QCheckBox(tr("Enable geo&location"), self) self.layout().addWidget(self.geolocationToggle) self.geolocationPermissionsRow = custom_widgets.Row(self) self.layout().addWidget(self.geolocationPermissionsRow) self.geolocationWhitelistColumn = custom_widgets.Column(self) self.geolocationPermissionsRow.addWidget(self.geolocationWhitelistColumn) self.geolocationWhitelistLabel = QLabel(tr("Allow these sites to track my location:"), self) self.geolocationWhitelistColumn.addWidget(self.geolocationWhitelistLabel) self.geolocationWhitelist = QListWidget(self) self.geolocationWhitelistColumn.addWidget(self.geolocationWhitelist) self.removeFromWhitelistButton = QPushButton(tr("Remove")) self.removeFromWhitelistButton.clicked.connect(lambda: self.geolocationWhitelist.takeItem(self.geolocationWhitelist.row(self.geolocationWhitelist.currentItem()))) self.geolocationWhitelistColumn.addWidget(self.removeFromWhitelistButton) self.geolocationBlacklistColumn = custom_widgets.Column(self) self.geolocationPermissionsRow.addWidget(self.geolocationBlacklistColumn) self.geolocationBlacklistLabel = QLabel(tr("Prevent these sites from tracking my location:"), self) self.geolocationBlacklistColumn.addWidget(self.geolocationBlacklistLabel) self.geolocationBlacklist = QListWidget(self) self.geolocationBlacklistColumn.addWidget(self.geolocationBlacklist) self.removeFromBlacklistButton = QPushButton(tr("Remove")) self.removeFromBlacklistButton.clicked.connect(lambda: self.geolocationBlacklist.takeItem(self.geolocationBlacklist.row(self.geolocationBlacklist.currentItem()))) self.geolocationBlacklistColumn.addWidget(self.removeFromBlacklistButton) self.removeAction = QAction(self) self.removeAction.setShortcut("Del") self.removeAction.triggered.connect(lambda: self.geolocationWhitelist.takeItem(self.geolocationWhitelist.row(self.geolocationWhitelist.currentItem())) if self.geolocationWhitelist.hasFocus() else self.geolocationBlacklist.takeItem(self.geolocationBlacklist.row(self.geolocationBlacklist.currentItem()))) self.addAction(self.removeAction) self.layout().addWidget(custom_widgets.Expander(self)) def loadSettings(self): self.maximumURLLength.setValue(settings.setting_to_int("data/MaximumURLLength")) #self.maximumCacheSize.setValue(settings.setting_to_int("data/MaximumCacheSize")) self.rememberHistoryToggle.setChecked(settings.setting_to_bool("data/RememberHistory")) self.geolocationToggle.setChecked(settings.setting_to_bool("network/GeolocationEnabled")) self.geolocationWhitelist.clear() for url in data.geolocation_whitelist: self.geolocationWhitelist.addItem(url) self.geolocationBlacklist.clear() for url in data.geolocation_blacklist: self.geolocationBlacklist.addItem(url) def saveSettings(self): settings.settings.setValue("data/MaximumURLLength", self.maximumURLLength.value()) #settings.settings.setValue("data/MaximumCacheSize", self.maximumCacheSize.value()) settings.settings.setValue("data/RememberHistory", self.rememberHistoryToggle.isChecked()) settings.settings.setValue("network/GeolocationEnabled", self.geolocationToggle.isChecked()) data.geolocation_whitelist = [self.geolocationWhitelist.item(authority).text() for authority in range(0, self.geolocationWhitelist.count())] data.geolocation_blacklist = [self.geolocationBlacklist.item(authority).text() for authority in range(0, self.geolocationBlacklist.count())] data.saveData()
class ConnectionSplash(QDialog): def __init__(self, parent): super().__init__(parent) self.setWindowTitle('New Connection') # Keep focus on window self.setModal(True) self.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.remove_item = QPushButton('Remove Item') main_layout = QHBoxLayout() # Saved IP's saved_box = QGroupBox('Saved') saved_layout = QVBoxLayout() saved_box.setLayout(saved_layout) self.save_list = QListWidget() self.save_list.addItem('New Connection...') self.save_list.setSelectionMode(QAbstractItemView.SingleSelection) self.loaded_connections = self.load_profiles() self.save_list.setCurrentRow(0) self.save_list.clicked.connect(self.update_list_functions) saved_layout.addWidget(self.save_list) self.remove_item.setEnabled(False) self.remove_item.clicked.connect(self.remove_selected_item) saved_layout.addWidget(self.remove_item) # Connection connect_box = QGroupBox('Connection Details') connect_layout = QVBoxLayout() connect_box.setLayout(connect_layout) connection_options = QHBoxLayout() # Connection details host_label = QLabel('Server IP:') connect_layout.addWidget(host_label) self.address = QLineEdit() self.address.textChanged.connect(self.check_arguments) connect_layout.addWidget(self.address) port_label = QLabel('Port:') connect_layout.addWidget(port_label) self.port = QSpinBox() self.port.setMinimum(0) self.port.setMaximum(65536) self.port.setValue(30000) connect_layout.addWidget(self.port) pass_label = QLabel('Password:'******'Connect') self.connect.clicked.connect(self.connect_to_target) self.connect.setEnabled(False) self.save = QPushButton('Save') self.save.clicked.connect(self.save_connection) self.save.setEnabled(False) connection_options.addWidget(self.save) connection_options.addStretch() connection_options.addWidget(self.connect) connect_layout.addStretch() connect_layout.addLayout(connection_options) main_layout.addWidget(saved_box) main_layout.addWidget(connect_box) self.setLayout(main_layout) self.exec_() def load_profiles(self): user_dir = appdirs.user_data_dir('PySmartSwitchClient', 'JackHogan') if not isdir(user_dir): makedirs(user_dir, exist_ok=True) if not isfile(join(user_dir, 'profiles.json')): with open(join(user_dir, 'profiles.json'), 'w') as f: f.write('{}') with open(join(user_dir, 'profiles.json'), 'r+') as json_file: profiles = json.load(json_file) self.remove_item.setEnabled(len(profiles) > 0) for profile in profiles: self.save_list.addItem(profile) return profiles def closeEvent(self, event: QCloseEvent): self.save_all_connections() sys.exit(0) def connect_to_target(self): self.save_all_connections() self.hide() # Checks to make sure that all parameters are filled before allowing save/connection def check_arguments(self): ok = len(self.address.text()) > 0 self.save.setEnabled(ok) self.connect.setEnabled(ok) def save_connection(self): title = QInputDialog.getText(self, 'Save Connection', 'Input Connection Name:', QLineEdit.Normal, '', Qt.WindowCloseButtonHint) if not title[1]: return name = title[0] if name in self.loaded_connections: append_digit = 1 while (name + ' (' + str(append_digit) + ')') in self.loaded_connections: append_digit += 1 self.loaded_connections[name + ' (' + str(append_digit) + ')'] = (self.address.text(), self.port.value()) self.save_list.addItem(name + ' (' + str(append_digit) + ')') else: self.loaded_connections[name] = (self.address.text(), self.port.value()) self.save_list.addItem(name) self.save_list.setCurrentRow(len(self.save_list) - 1) self.remove_item.setEnabled(True) def update_list_functions(self): self.remove_item.setEnabled( not self.save_list.currentItem().text() == 'New Connection...') if self.save_list.currentItem().text() == 'New Connection...': self.address.setText('') self.port.setValue(30000) else: self.address.setText(self.loaded_connections[ self.save_list.currentItem().text()][0]) self.port.setValue(self.loaded_connections[ self.save_list.currentItem().text()][1]) def remove_selected_item(self): self.loaded_connections.pop(self.save_list.currentItem().text()) self.save_list.takeItem( self.save_list.row(self.save_list.currentItem())) self.update_list_functions() def save_all_connections(self): user_dir = appdirs.user_data_dir('PySmartSwitchClient', 'JackHogan') if isfile(join(user_dir, 'profiles.json')): remove(join(user_dir, 'profiles.json')) with open(join(user_dir, 'profiles.json'), 'w') as f: json.dump(self.loaded_connections, f) def get_port(self): return self.port.value() def get_address(self): return self.address.text() def get_pass(self): return self.password.text()
class CodeCompletionWidget(QFrame): def __init__(self, editor): super(CodeCompletionWidget, self).__init__( None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self._revision = 0 self._block = 0 self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = {'a': resources.IMAGES['attribute'], 'f': resources.IMAGES['function'], 'c': resources.IMAGES['class'], 'm': resources.IMAGES['module']} self.cc = code_completion.CodeCompletion() self._completion_results = {} self._prefix = '' self.setVisible(False) self.source = '' self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } self.desktop = QApplication.instance().desktop() self.completion_list.itemClicked['QListWidgetItem*'].connect(self.pre_key_insert_completion) self._editor.document().cursorPositionChanged['const QTextCursor &'].connect(self.update_metadata) def _select_next_row(self, move=1): new_row = self.completion_list.currentRow() + move if new_row < self.completion_list.count(): self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(0) return True def _select_previous_row(self, move=1): new_row = self.completion_list.currentRow() - move if new_row >= 0: self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow( self.completion_list.count() - move) return True def update_metadata(self, cursor): if settings.CODE_COMPLETION: if self._editor.document().revision() != self._revision and \ cursor.block().blockNumber() != self._block: source = self._editor.get_text() source = source.encode(self._editor.encoding) self.cc.analyze_file(self._editor.ID, source, self._editor.indent, self._editor.useTabs) self._revision = self._editor.document().revision() self._block = cursor.block().blockNumber() def insert_completion(self, insert, type_=ord('a')): if insert != self._prefix: closing = '' if type_ in (ord('f'), ord('c')): closing = '()' extra = len(self._prefix) - len(insert) insertion = '%s%s' % (insert[extra:], closing) self._editor.textCursor().insertText(insertion) self.hide_completer() def _get_geometry(self): cr = self._editor.cursorRect() desktop_geometry = self.desktop.availableGeometry(self._editor) point = self._editor.mapToGlobal(cr.topLeft()) cr.moveTopLeft(point) #Check new position according desktop geometry width = (self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10) height = 200 orientation = (point.y() + height) < desktop_geometry.height() if orientation: cr.moveTop(cr.bottom()) cr.setWidth(width) cr.setHeight(height) if not orientation: cr.moveBottom(cr.top()) xpos = desktop_geometry.width() - (point.x() + width) if xpos < 0: cr.moveLeft(cr.left() + xpos) return cr def complete(self, results): self.add_list_items(results) self.completion_list.setCurrentRow(0) cr = self._get_geometry() self.setGeometry(cr) self.completion_list.updateGeometries() self.show() def add_list_items(self, proposals): self.completion_list.clear() for p in proposals: self.completion_list.addItem( QListWidgetItem( QIcon( self._icons.get(p[0], resources.IMAGES['attribute'])), p[1], type=ord(p[0]))) def set_completion_prefix(self, prefix, valid=True): self._prefix = prefix proposals = [] proposals += [('m', item) for item in self._completion_results.get('modules', []) if item.startswith(prefix)] proposals += [('c', item) for item in self._completion_results.get('classes', []) if item.startswith(prefix)] proposals += [('a', item) for item in self._completion_results.get( 'attributes', []) if item.startswith(prefix)] proposals += [('f', item) for item in self._completion_results.get('functions', []) if item.startswith(prefix)] if proposals and valid: self.complete(proposals) else: self.hide_completer() def _invalid_completion_position(self): result = False cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) selection = cursor.selectedText()[:-1].split(' ') if len(selection) == 0 or selection[-1] == '' or \ selection[-1].isdigit(): result = True return result def fill_completer(self, force_completion=False): if not force_completion and (self._editor.cursor_inside_string() or self._editor.cursor_inside_comment() or self._invalid_completion_position()): return source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() results = self.cc.get_completion(source, offset) self._completion_results = results if force_completion: cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.KeepAnchor) prefix = cursor.selectedText() else: prefix = self._editor._text_under_cursor() self.set_completion_prefix(prefix) def hide_completer(self): self._prefix = '' self.hide() def pre_key_insert_completion(self): type_ = ord('a') current = self.completion_list.currentItem() insert = current.text() if not insert.endswith(')'): type_ = current.type() self.insert_completion(insert, type_) self.hide_completer() return True def process_pre_key_event(self, event): if not self.isVisible() or self._editor.lang != "python": return False skip = self._key_operations.get(event.key(), lambda: False)() self._key_operations.get(event.modifiers(), lambda: False)() if skip is None: skip = False return skip def process_post_key_event(self, event): if not settings.CODE_COMPLETION or self._editor.lang != "python": return if self.isVisible(): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() prefix, valid = self.cc.get_prefix(source, offset) self.set_completion_prefix(prefix, valid) self.completion_list.setCurrentRow(0) force_completion = (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier) if event.key() == Qt.Key_Period or force_completion: self.fill_completer(force_completion)
class Scheduler: def showDialog(self, currentCard=None): if currentCard: self.did = currentCard.did elif mw._selectedDeck(): self.did = mw._selectedDeck()['id'] else: return if not self._getCardInfo(self.did): showInfo('Please select an Incremental Reading deck.') return dialog = QDialog(mw) layout = QVBoxLayout() self.cardListWidget = QListWidget() self.cardListWidget.setAlternatingRowColors(True) self.cardListWidget.setSelectionMode( QAbstractItemView.ExtendedSelection) self.cardListWidget.setWordWrap(True) self.cardListWidget.itemDoubleClicked.connect(lambda: self.showBrowser( self.cardListWidget.currentItem().data(Qt.UserRole)['nid'])) self._updateListItems() upButton = QPushButton('Up') upButton.clicked.connect(self._moveUp) downButton = QPushButton('Down') downButton.clicked.connect(self._moveDown) topButton = QPushButton('Top') topButton.clicked.connect(self._moveToTop) bottomButton = QPushButton('Bottom') bottomButton.clicked.connect(self._moveToBottom) randomizeButton = QPushButton('Randomize') randomizeButton.clicked.connect(self._randomize) controlsLayout = QHBoxLayout() controlsLayout.addWidget(topButton) controlsLayout.addWidget(upButton) controlsLayout.addWidget(downButton) controlsLayout.addWidget(bottomButton) controlsLayout.addStretch() controlsLayout.addWidget(randomizeButton) buttonBox = QDialogButtonBox(QDialogButtonBox.Close | QDialogButtonBox.Save) buttonBox.accepted.connect(dialog.accept) buttonBox.rejected.connect(dialog.reject) buttonBox.setOrientation(Qt.Horizontal) layout.addLayout(controlsLayout) layout.addWidget(self.cardListWidget) layout.addWidget(buttonBox) dialog.setLayout(layout) dialog.setWindowModality(Qt.WindowModal) dialog.resize(500, 500) choice = dialog.exec_() if choice == 1: cids = [] for i in range(self.cardListWidget.count()): card = self.cardListWidget.item(i).data(Qt.UserRole) cids.append(card['id']) self.reorder(cids) def _updateListItems(self): cardInfo = self._getCardInfo(self.did) self.cardListWidget.clear() posWidth = len(str(len(cardInfo) + 1)) for i, card in enumerate(cardInfo, start=1): if self.settings['prioEnabled']: info = card['priority'] else: info = str(i).zfill(posWidth) title = sub('\s+', ' ', stripHTML(card['title'])) text = self.settings['organizerFormat'].format(info=info, title=title) item = QListWidgetItem(text) item.setData(Qt.UserRole, card) self.cardListWidget.addItem(item) def _moveToTop(self): selected = self._getSelected() if not selected: showInfo('Please select one or several items.') return selected.reverse() for item in selected: self.cardListWidget.takeItem(self.cardListWidget.row(item)) self.cardListWidget.insertItem(0, item) item.setSelected(True) self.cardListWidget.scrollToTop() def _moveUp(self): selected = self._getSelected() if not selected: showInfo('Please select one or several items.') return if self.cardListWidget.row(selected[0]) == 0: return for item in selected: row = self.cardListWidget.row(item) self.cardListWidget.takeItem(row) self.cardListWidget.insertItem(row - 1, item) item.setSelected(True) self.cardListWidget.scrollToItem(item) def _moveDown(self): selected = self._getSelected() if not selected: showInfo('Please select one or several items.') return selected.reverse() if (self.cardListWidget.row( selected[0]) == self.cardListWidget.count() - 1): return for item in selected: row = self.cardListWidget.row(item) self.cardListWidget.takeItem(row) self.cardListWidget.insertItem(row + 1, item) item.setSelected(True) self.cardListWidget.scrollToItem(item) def _moveToBottom(self): selected = self._getSelected() if not selected: showInfo('Please select one or several items.') return for item in selected: self.cardListWidget.takeItem(self.cardListWidget.row(item)) self.cardListWidget.insertItem(self.cardListWidget.count(), item) item.setSelected(True) self.cardListWidget.scrollToBottom() def _getSelected(self): return [ self.cardListWidget.item(i) for i in range(self.cardListWidget.count()) if self.cardListWidget.item(i).isSelected() ] def _randomize(self): allItems = [ self.cardListWidget.takeItem(0) for _ in range(self.cardListWidget.count()) ] if self.settings['prioEnabled']: maxPrio = len(self.settings['priorities']) - 1 for item in allItems: priority = item.data(Qt.UserRole)['priority'] if priority != '': item.contNewPos = gauss(maxPrio - int(priority), maxPrio / 20) else: item.contNewPos = float('inf') allItems.sort(key=lambda item: item.contNewPos) else: shuffle(allItems) for item in allItems: self.cardListWidget.addItem(item) def answer(self, card, ease): if self.settings['prioEnabled']: # reposition the card at the end of the organizer cardCount = len(self._getCardInfo(card.did)) self.reposition(card, cardCount) return if ease == SCHEDULE_EXTRACT: value = self.settings['extractValue'] randomize = self.settings['extractRandom'] method = self.settings['extractMethod'] elif ease == SCHEDULE_SOON: value = self.settings['soonValue'] randomize = self.settings['soonRandom'] method = self.settings['soonMethod'] elif ease == SCHEDULE_LATER: value = self.settings['laterValue'] randomize = self.settings['laterRandom'] method = self.settings['laterMethod'] elif ease == SCHEDULE_CUSTOM: self.reposition(card, 1) self.showDialog(card) return if method == 'percent': totalCards = len([c['id'] for c in self._getCardInfo(card.did)]) newPos = totalCards * (value / 100) elif method == 'count': newPos = value if randomize: newPos = gauss(newPos, newPos / 10) newPos = max(1, round(newPos)) self.reposition(card, newPos) if ease != SCHEDULE_EXTRACT: tooltip('Card moved to position {}'.format(newPos)) def reposition(self, card, newPos): cids = [c['id'] for c in self._getCardInfo(card.did)] mw.col.sched.forgetCards(cids) cids.remove(card.id) newOrder = cids[:newPos - 1] + [card.id] + cids[newPos - 1:] mw.col.sched.sortCards(newOrder) def reorder(self, cids): mw.col.sched.forgetCards(cids) mw.col.sched.sortCards(cids) def _getCardInfo(self, did): cardInfo = [] for cid, nid in mw.col.db.execute( 'select id, nid from cards where did = ?', did): note = mw.col.getNote(nid) if note.model()['name'] == self.settings['modelName']: if self.settings['prioEnabled']: prio = note[self.settings['prioField']] else: prio = None cardInfo.append({ 'id': cid, 'nid': nid, 'title': note[self.settings['titleField']], 'priority': prio }) return cardInfo def showBrowser(self, nid): browser = dialogs.open('Browser', mw) browser.form.searchEdit.lineEdit().setText('nid:' + str(nid)) browser.onSearchActivated()
class SettingsDialog(QDialog): def __init__(self, parent=None): super(SettingsDialog, self).__init__(parent) self.currentDirectories = [] # self.addDirectories(directories) self.initButtons() self.initUi() self.restoreSettings() self.setLibraryDirectoriesWidget() def saveSettings(self): settings = QtCore.QSettings( QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, QtCore.QCoreApplication.organizationName(), QtCore.QCoreApplication.applicationName()) settings.beginGroup("preferences") settings.beginWriteArray('library_directories', len(self.currentDirectories)) for index, value in enumerate(self.currentDirectories): settings.setArrayIndex(index) settings.setValue("url", value) settings.endArray() settings.endGroup() def restoreSettings(self): settings = QtCore.QSettings( QtCore.QSettings.IniFormat, QtCore.QSettings.UserScope, QtCore.QCoreApplication.organizationName(), QtCore.QCoreApplication.applicationName()) # settings.setValue("preferences_window/position", self.pos()) settings.beginGroup("preferences") size = settings.beginReadArray('library_directories') if not size == 0: for i in range(0, size): settings.setArrayIndex(i) url = settings.value("url") self.currentDirectories.append(url) settings.endArray() settings.endGroup() def initButtons(self): self.libraryDirectories = QLabel() self.libraryDirectories.setText("Library Directories") self.libraryDirectories.setAlignment(QtCore.Qt.AlignLeft) self.addButton = QPushButton("Add Directory") self.addButton.clicked.connect(self._onAdd) self.removeButton = QPushButton("Remove Directory") self.removeButton.clicked.connect(self._onRemove) self.directoriesList = QListWidget(self) def addDirectories(self, directories): if not isinstance(directories, list): directories = [directories] for directory in directories: self.currentDirectories.append(directory) def setLibraryDirectoriesWidget(self): for directory in self.currentDirectories: newItem = QListWidgetItem(directory, self.directoriesList) def _onAdd(self): directories = self.choose_directory() if not directories: return None for directory in directories: if directory not in self.currentDirectories: self.currentDirectories.append(directory) newItem = QListWidgetItem(directory, self.directoriesList) def _onRemove(self): currentItem = self.directoriesList.currentItem() row = self.directoriesList.indexFromItem(currentItem).row() if currentItem: self.directoriesList.takeItem(row) self.currentDirectories.remove(currentItem.data( QtCore.Qt.DisplayRole)) def choose_directory(self): fileDialog = QFileDialog(self) fileDialog.setAcceptMode(QFileDialog.AcceptOpen) fileDialog.setFileMode(QFileDialog.Directory) fileDialog.setViewMode(QFileDialog.Detail) fileDialog.setWindowTitle("Choose Media Directory") try: fileDialog.setDirectory(QtCore.QStandardPaths.standardLocations( QtCore.QStandardPaths.MusicLocation)[0]) except IndexError: fileDialog.setDirectory(QtCore.QDir.homePath()) if fileDialog.exec_() == QDialog.Accepted: return fileDialog.selectedFiles() def initUi(self): self.directoriesButtonsLayout = QVBoxLayout() self.directoriesButtonsLayout.addWidget(self.addButton) self.directoriesButtonsLayout.addWidget(self.removeButton) self.directoriesButtonsLayout.addSpacing(10) self.directoriesLayout = QHBoxLayout() self.directoriesLayout.addWidget(self.directoriesList) self.directoriesLayout.addLayout(self.directoriesButtonsLayout) self.closeButton = QPushButton("Close") self.saveButton = QPushButton("Save") self.closeButton.clicked.connect(self.reject) self.saveButton.clicked.connect(self.accept) self.bottomButtonsLayout = QHBoxLayout() self.bottomButtonsLayout.addStretch(1) self.bottomButtonsLayout.addSpacing(12) self.bottomButtonsLayout.addWidget(self.saveButton) self.bottomButtonsLayout.addWidget(self.closeButton) mainLayout = QVBoxLayout() mainLayout.addWidget(self.libraryDirectories) mainLayout.addLayout(self.directoriesLayout) mainLayout.addLayout(self.bottomButtonsLayout) self.setLayout(mainLayout) self.setWindowTitle("Settings") self.setMinimumSize(450, 340) self.resize(680, 420)
class Theme(QWidget): """Theme widget class.""" def __init__(self, parent): super(Theme, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) vbox.addWidget(QLabel(self.tr("<b>Select Theme:</b>"))) self.list_skins = QListWidget() self.list_skins.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.list_skins) self.btn_delete = QPushButton(self.tr("Delete Theme")) self.btn_preview = QPushButton(self.tr("Preview Theme")) self.btn_create = QPushButton(self.tr("Create Theme")) hbox = QHBoxLayout() hbox.addWidget(self.btn_delete) hbox.addSpacerItem(QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox.addWidget(self.btn_preview) hbox.addWidget(self.btn_create) vbox.addLayout(hbox) self._refresh_list() self.btn_preview.clicked['bool'].connect(self.preview_theme) self.btn_delete.clicked['bool'].connect(self.delete_theme) self.btn_create.clicked['bool'].connect(self.create_theme) self._preferences.savePreferences.connect(self.save) def delete_theme(self): if self.list_skins.currentRow() != 0: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) file_manager.delete_file(qss_file) self._refresh_list() def create_theme(self): designer = preferences_theme_editor.ThemeEditor(self) designer.exec_() self._refresh_list() def showEvent(self, event): self._refresh_list() super(Theme, self).showEvent(event) def _refresh_list(self): self.list_skins.clear() self.list_skins.addItem("Default") files = [file_manager.get_file_name(filename) for filename in file_manager.get_files_from_folder( resources.NINJA_THEME_DOWNLOAD, "qss")] files.sort() self.list_skins.addItems(files) if settings.NINJA_SKIN in files: index = files.index(settings.NINJA_SKIN) self.list_skins.setCurrentRow(index + 1) else: self.list_skins.setCurrentRow(0) def save(self): qsettings = IDE.ninja_settings() settings.NINJA_SKIN = self.list_skins.currentItem().text() qsettings.setValue("preferences/theme/skin", settings.NINJA_SKIN) self.preview_theme() def preview_theme(self): if self.list_skins.currentRow() == 0: qss_file = resources.NINJA_THEME else: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) with open(qss_file) as f: qss = f.read() QApplication.instance().setStyleSheet(qss)
class UI(QWidget): def __init__(self): super().__init__() self.width: any = None self.height: any = None self.input_open_button: QPushButton = None self.input_clear_button: QPushButton = None self.input_list: QListWidget = None self.input_input_label: QLabel = None self.method_calculate_button: QPushButton = None self.method_reset_button: QPushButton = None self.method_combobox: QComboBox = None self.method_method_used_label: QLabel = None self.method_intial_interval_textbox: QPlainTextEdit = None self.output_save_button: QPushButton = None self.output_clear_button: QPushButton = None self.output_textbox: QPlainTextEdit = None self.output_output_label: QLabel = None # 3d self.figure1 = plt.figure() self.canvas1 = FigureCanvas(self.figure1) # 2d self.figure2 = plt.figure() self.canvas2 = FigureCanvas(self.figure2) # graph error message box self.graph_error_texbox: QPlainTextEdit = None self.grid_layout: QGridLayout = None self.hbox1: QHBoxLayout = None self.hbox2: QHBoxLayout = None self.hbox: QHBoxLayout = None self.vbox: QVBoxLayout = None self.open_file_location: str = os.path.dirname( os.path.abspath(__file__)) self.save_file_location: str = os.path.dirname( os.path.abspath(__file__)) self.methods = list(Methods.keys()) self.initUI() def initUI(self): self.grid_layout = QGridLayout() self.setLayout(self.grid_layout) self.grid_layout.setHorizontalSpacing(50) # create 5 blocks self.create_input_block() self.create_method_used_block() self.create_output_block() self.create_graph_block() self.setGeometry(170, 100, 1600, 75E0) #self.setMinimumSize(1600, 500) self.setWindowTitle('Project2-Optimization') self.width = self.frameGeometry().width() self.height = self.frameGeometry().height() self.show() def create_input_block(self): self.input_open_button = QPushButton("open") self.input_open_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.input_open_button.clicked.connect(self.open_file_dialog) self.input_clear_button = QPushButton("clear") self.input_clear_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.input_clear_button.clicked.connect(self.input_clear) self.input_input_label = QLabel('Input:') input_h_box = QHBoxLayout() input_h_box.addWidget(self.input_open_button) input_h_box.addSpacing(50) input_h_box.addWidget(self.input_clear_button) self.input_list = QListWidget() input_v_box = QVBoxLayout() input_v_box.addWidget(self.input_input_label) input_v_box.addWidget(self.input_list) input_v_box.addLayout(input_h_box) self.grid_layout.addLayout(input_v_box, 0, 0) def create_method_used_block(self): # Combo Box to be used self.method_combobox = QComboBox(self) self.method_combobox.addItems(self.methods) # Buttons to be used self.method_reset_button = QPushButton("reset") self.method_reset_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.method_reset_button.clicked.connect(self.method_reset) self.method_calculate_button = QPushButton("calculate") self.method_calculate_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.method_calculate_button.clicked.connect(self.method_calculate) # Qlabel to be used self.method_method_used_label = QLabel('Method Used:') self.method_intial_interval_textbox = QPlainTextEdit() method_h2_box = QHBoxLayout() method_h2_box.addWidget(self.method_reset_button) method_h2_box.addWidget(self.method_calculate_button) method_v_box = QVBoxLayout() method_v_box.addWidget(self.method_method_used_label) method_v_box.addWidget(self.method_combobox) method_v_box.addWidget(self.method_intial_interval_textbox) method_v_box.addLayout(method_h2_box) self.grid_layout.addLayout(method_v_box, 0, 1) def create_output_block(self): self.output_textbox = QPlainTextEdit(QWidget().resize(640, 480)) self.output_textbox.setReadOnly(True) self.output_save_button = QPushButton("save") self.output_save_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.output_save_button.clicked.connect(self.save_file_dialog) self.output_clear_button = QPushButton("clear") self.output_clear_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.output_clear_button.clicked.connect(self.output_clear) self.output_output_label = QLabel('Output:') output_h_box = QHBoxLayout() output_h_box.addWidget(self.output_save_button) output_h_box.addWidget(self.output_clear_button) output_v_box = QVBoxLayout() output_v_box.addWidget(self.output_output_label) output_v_box.addWidget(self.output_textbox) output_v_box.addLayout(output_h_box) self.grid_layout.addLayout(output_v_box, 1, 0, 1, 2) def create_graph_block(self): ''' plot some random stuff ''' self.figure1.suptitle('3d') self.figure2.suptitle('2d') self.canvas1.draw() self.canvas2.draw() # self.figure2.legend() self.graph_error_texbox = QPlainTextEdit('Default graph(NULL)') self.graph_error_texbox.setReadOnly(True) self.graph_error_texbox.setMinimumSize(640, 110) self.hbox1 = QHBoxLayout() self.hbox2 = QHBoxLayout() self.hbox = QHBoxLayout() self.vbox = QVBoxLayout() self.hbox1.addWidget(self.canvas1) self.hbox2.addWidget(self.canvas2) self.hbox.addLayout(self.hbox1) self.hbox.addLayout(self.hbox2) self.vbox.addLayout(self.hbox) self.vbox.addWidget(self.graph_error_texbox) self.grid_layout.addLayout(self.vbox, 0, 2, 2, 2) def open_file_dialog(self): filename, _ = QFileDialog.getOpenFileName(self, "Open file", self.open_file_location, "Text Files (*.txt)") temp_pos = filename.rfind('/') if temp_pos: self.open_file_location = filename[:temp_pos + 1] if filename: with open(filename, 'rb') as file: read_data = file.read() udatabtype = read_data.decode("utf-8") asciidatabtype = udatabtype.encode("ascii", "ignore") asciidata = asciidatabtype.decode("ascii") read_data_list = asciidata.splitlines() self.input_list.addItems(read_data_list) def save_file_dialog(self): filename, _ = QFileDialog.getSaveFileName(self, "Save File", self.save_file_location, "Text Files (*.txt)") temp_pos = filename.rfind('/') self.save_file_location = filename[:temp_pos + 1] if filename: with open(filename, 'w') as file: file.write(self.output_textbox.toPlainText()) self.output_clear() def input_clear(self): self.input_list.clear() def output_clear(self): # clear textbox self.output_textbox.clear() # clear graph ''' clear windows ''' plt.figure(1) plt.clf() plt.figure(2) plt.clf() plt.close('all') ''' plot some random stuff ''' self.figure1 = plt.figure() self.figure2 = plt.figure() self.canvas1 = FigureCanvas(self.figure1) self.canvas2 = FigureCanvas(self.figure2) self.figure1.suptitle('3d') self.figure2.suptitle('2d') self.canvas1.draw() self.canvas2.draw() self.grid_layout.removeItem(self.hbox1) self.grid_layout.removeItem(self.hbox2) self.grid_layout.removeItem(self.hbox) self.grid_layout.removeItem(self.vbox) self.graph_error_texbox.setPlainText('Default graph(NULL)') self.hbox1 = QHBoxLayout() self.hbox2 = QHBoxLayout() self.hbox = QHBoxLayout() self.vbox = QVBoxLayout() self.hbox1.addWidget(self.canvas1) self.hbox2.addWidget(self.canvas2) self.hbox.addLayout(self.hbox1) self.hbox.addLayout(self.hbox2) self.vbox.addLayout(self.hbox) self.vbox.addWidget(self.graph_error_texbox) self.grid_layout.addLayout(self.vbox, 0, 2, 2, 2) def method_reset(self): self.method_intial_interval_textbox.setPlainText('') self.method_combobox.setCurrentIndex(0) def method_calculate(self): initial_interval = self.method_intial_interval_textbox.toPlainText() method = self.method_combobox.currentText() equation_item = self.input_list.currentItem() if equation_item is None: self.output_textbox.setPlainText('No equation string detected!\n') return elif method == 'None----': self.output_textbox.setPlainText('Method couldnt be None\n') return elif initial_interval == '': self.output_textbox.setPlainText('No initial point\n') return # global variables equation_str: str = None initial_point: List[float] = None intervals: List[List[float]] = None answer: str = None Xs: List[Arrai] = None vars_form: List[str] = None # exception added try: equation_str = equation_item.text() # get initial point and intervals initial_point, vars_form, intervals = get_ip_intervals( initial_interval) # manager = Manager(equation_str, vars_form, method, initial_point, intervals) manager = Manager(equation_str=equation_str, vars_form=vars_form, method_name=method, initial_point=initial_point, intervals=intervals) answer, Xs = manager.run() # write answer to output self.output_textbox.setPlainText(answer) except Exception as explosion: answer = explosion.args[0] self.output_textbox.setPlainText(answer) try: # draw out graph draw_graph(self, equation_str, vars_form, Xs, intervals) # catch graph drawing exception except: self.graph_error_texbox.setPlainText( 'Error while building graph!\n Current Equation: %s' % equation_str) def resizeEvent(self, a0: QResizeEvent) -> None: HeightIncreasement = self.frameGeometry().height() - self.height temp_size = 30 if abs(HeightIncreasement) - temp_size >= 0: # no pointer could be used in python self.change_font(self.input_input_label, HeightIncreasement / temp_size) self.change_font(self.method_method_used_label, HeightIncreasement / temp_size) self.change_font(self.output_output_label, HeightIncreasement / temp_size) self.change_font(self.input_open_button, HeightIncreasement / temp_size) self.change_font(self.input_clear_button, HeightIncreasement / temp_size) self.change_font(self.method_calculate_button, HeightIncreasement / temp_size) self.change_font(self.method_reset_button, HeightIncreasement / temp_size) self.change_font(self.output_save_button, HeightIncreasement / temp_size) self.change_font(self.output_clear_button, HeightIncreasement / temp_size) self.change_font(self.method_combobox, HeightIncreasement / temp_size) self.width = self.frameGeometry().width() self.height = self.frameGeometry().height() @staticmethod def change_font(label: QLabel, increasement: int): font = label.font() font.setPointSize(font.pointSize() + increasement) if font.pointSize() > 8: label.setFont(font)
class Example(QWidget): def __init__(self, parent=None): super(Example, self).__init__(parent) QApplication.setStyle(QStyleFactory.create('Fusion')) # -------------- QCOMBOBOX ---------------------- cbx = QComboBox() # agregar lista de nombres de estilos disponibles cbx.addItems(QStyleFactory.keys()) # responder al evento cambio de texto cbx.currentTextChanged.connect(self.textChanged) # seleccionar el ultimo elemento cbx.setItemText(4, 'Fusion') # -------------- QLISTWIDGET --------------------- items = ['Ubuntu', 'Linux', 'Mac OS', 'Windows', 'Fedora', 'Chrome OS', 'Android', 'Windows Phone'] self.lv = QListWidget() self.lv.addItems(items) self.lv.itemSelectionChanged.connect(self.itemChanged) # -------------- QTABLEWIDGET -------------------- self.table = QTableWidget(10, 3) # establecer nombre de cabecera de las columnas self.table.setHorizontalHeaderLabels(['Nombre', 'Edad', 'Nacionalidad']) # evento producido cuando cambia el elemento seleccionado self.table.itemSelectionChanged.connect(self.tableItemChanged) # alternar color de fila self.table.setAlternatingRowColors(True) # seleccionar solo filas self.table.setSelectionBehavior(QTableWidget.SelectRows) # usar seleccion simple, una fila a la vez self.table.setSelectionMode(QTableWidget.SingleSelection) table_data = [ ("Alice", 15, "Panama"), ("Dana", 25, "Chile"), ("Fernada", 18, "Ecuador") ] # agregar cada uno de los elementos al QTableWidget for i, (name, age, city) in enumerate(table_data): self.table.setItem(i, 0, QTableWidgetItem(name)) self.table.setItem(i, 1, QTableWidgetItem(str(age))) self.table.setItem(i, 2, QTableWidgetItem(city)) vbx = QVBoxLayout() vbx.addWidget(QPushButton('Tutoriales PyQT-5')) vbx.setAlignment(Qt.AlignTop) vbx.addWidget(cbx) vbx.addWidget(self.lv) vbx.addWidget(self.table) self.setWindowTitle("Items View") self.resize(362, 320) self.setLayout(vbx) def textChanged(self, txt): QApplication.setStyle(QStyleFactory.create(txt)) def itemChanged(self): item = QListWidgetItem(self.lv.currentItem()) print("Sistema seleccionado: ", item.text()) def tableItemChanged(self): name, age, city = self.table.selectedItems() print("Data:", name.text(), age.text(), city.text())
class MainWindow(QMainWindow): htmlReady = pyqtSignal(str) def __init__(self, app): QMainWindow.__init__(self) self.install_directory = os.getcwd() self.app = app self.book = None self.last_book = "" self.filename = "" self._part_is_new = False self.tread_running = False self.initTheme() self.createUi() self.createMenus() self.createStatusBar() self.readSettings() self.text_edit.textChanged.connect(self.textChanged) def initTheme(self): settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName()) self.theme = settings.value("theme", "DarkFusion") hilite_color = settings.value("hiliteColor", self.palette().highlight().color().name()) self.changeStyle(self.theme, hilite_color) def showEvent(self, event): if self.last_book: self.loadBook(self.last_book) def changeStyle(self, theme, hilite_color): self.theme = theme if theme == "DarkFusion": QApplication.setStyle(DarkFusion(hilite_color)) else: QApplication.setStyle(QStyleFactory.create(theme)) pal = self.app.palette() pal.setColor(QPalette.Highlight, QColor(hilite_color)) self.app.setPalette(pal) def createUi(self): self.content = Expander("Content", ":/images/parts.svg") self.images = Expander("Images", ":/images/images.svg") self.settings = Expander("Settings", ":/images/settings.svg") self.setWindowTitle(QCoreApplication.applicationName() + " " + QCoreApplication.applicationVersion()) vbox = QVBoxLayout() vbox.addWidget(self.content) vbox.addWidget(self.images) vbox.addWidget(self.settings) vbox.addStretch() self.content_list = QListWidget() self.content_list.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) content_box = QVBoxLayout() content_box.addWidget(self.content_list) self.item_edit = QLineEdit() self.item_edit.setMaximumHeight(0) self.item_edit.editingFinished.connect(self.editItemFinished) self.item_anim = QPropertyAnimation(self.item_edit, "maximumHeight".encode("utf-8")) content_box.addWidget(self.item_edit) button_layout = QHBoxLayout() plus_button = FlatButton(":/images/plus.svg") self.edit_button = FlatButton(":/images/edit.svg") self.trash_button = FlatButton(":/images/trash.svg") self.up_button = FlatButton(":/images/up.svg") self.down_button = FlatButton(":/images/down.svg") self.trash_button.enabled = False self.up_button.enabled = False self.down_button.enabled = False button_layout.addWidget(plus_button) button_layout.addWidget(self.up_button) button_layout.addWidget(self.down_button) button_layout.addWidget(self.edit_button) button_layout.addWidget(self.trash_button) content_box.addLayout(button_layout) self.content.addLayout(content_box) plus_button.clicked.connect(self.addPart) self.trash_button.clicked.connect(self.dropPart) self.up_button.clicked.connect(self.partUp) self.down_button.clicked.connect(self.partDown) self.edit_button.clicked.connect(self.editPart) self.image_list = QListWidget() self.image_list.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) image_box = QVBoxLayout() image_box.addWidget(self.image_list) image_button_layout = QHBoxLayout() image_plus_button = FlatButton(":/images/plus.svg") self.image_trash_button = FlatButton(":/images/trash.svg") self.image_trash_button.enabled = False image_button_layout.addWidget(image_plus_button) image_button_layout.addWidget(self.image_trash_button) image_box.addLayout(image_button_layout) self.images.addLayout(image_box) image_plus_button.clicked.connect(self.addImage) self.image_trash_button.clicked.connect(self.dropImage) scroll_content = QWidget() scroll_content.setLayout(vbox) scroll = QScrollArea() scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) scroll.setWidget(scroll_content) scroll.setWidgetResizable(True) scroll.setMaximumWidth(200) scroll.setMinimumWidth(200) self.navigationdock = QDockWidget("Navigation", self) self.navigationdock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.navigationdock.setWidget(scroll) self.navigationdock.setObjectName("Navigation") self.addDockWidget(Qt.LeftDockWidgetArea, self.navigationdock) self.splitter = QSplitter() self.text_edit = MarkdownEdit() self.text_edit.setFont(QFont("Courier", 11)) self.preview = QWebEngineView() self.preview.setMinimumWidth(300) self.setWindowTitle(QCoreApplication.applicationName()) self.splitter.addWidget(self.text_edit) self.splitter.addWidget(self.preview) self.setCentralWidget(self.splitter) self.content.expanded.connect(self.contentExpanded) self.images.expanded.connect(self.imagesExpanded) self.settings.expanded.connect(self.settingsExpanded) self.settings.clicked.connect(self.openSettings) self.content_list.currentItemChanged.connect(self.partSelectionChanged) self.image_list.currentItemChanged.connect(self.imageSelectionChanged) self.image_list.itemDoubleClicked.connect(self.insertImage) self.text_edit.undoAvailable.connect(self.undoAvailable) self.text_edit.redoAvailable.connect(self.redoAvailable) self.text_edit.copyAvailable.connect(self.copyAvailable) QApplication.clipboard().dataChanged.connect(self.clipboardDataChanged) def undoAvailable(self, value): self.undo_act.setEnabled(value) def redoAvailable(self, value): self.redo_act.setEnabled(value) def copyAvailable(self, value): self.copy_act.setEnabled(value) self.cut_act.setEnabled(value) def clipboardDataChanged(self): md = QApplication.clipboard().mimeData() self.paste_act.setEnabled(md.hasText()) def openSettings(self): dlg = Settings(self.book, self.install_directory) dlg.exec() if dlg.saved: self.setWindowTitle(QCoreApplication.applicationName() + " - " + self.book.name) def addPart(self): self.item_edit.setText("") self.item_edit.setFocus() self.item_anim.setStartValue(0) self.item_anim.setEndValue(23) self.item_anim.start() self._part_is_new = True def addItem(self): text = self.item_edit.text() if text: if not self.book.getPart(text): self.book.addPart(text) self.loadBook(self.last_book) def updateItem(self): text = self.item_edit.text() if text: if not self.book.getPart(text): self.book.updatePart(self.content_list.currentItem().data(1).name, text) self.loadBook(self.last_book) def editItemFinished(self): if self._part_is_new: self.addItem() else: self.updateItem() self.item_anim.setStartValue(23) self.item_anim.setEndValue(0) self.item_anim.start() def editPart(self): item = self.content_list.currentItem().data(1).name self.item_edit.setText(item) self.item_edit.setFocus() self.item_anim.setStartValue(0) self.item_anim.setEndValue(23) self.item_anim.start() self._part_is_new = False def dropPart(self): item = self.content_list.currentItem().data(1).name msgBox = QMessageBox() msgBox.setText("You are about to delete the part <i>" + item + "</i>") msgBox.setInformativeText("Do you really want to delete the item?") msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.Cancel) msgBox.setDefaultButton(QMessageBox.Cancel) ret = msgBox.exec() if ret == QMessageBox.Yes: self.book.dropPart(item) self.loadBook(self.last_book) def addImage(self): fileName = "" dialog = QFileDialog() dialog.setFileMode(QFileDialog.AnyFile) dialog.setNameFilter("Image Files(*.png *.jpg *.bmp *.gif);;All (*)") dialog.setWindowTitle("Load Image") dialog.setOption(QFileDialog.DontUseNativeDialog, True) dialog.setAcceptMode(QFileDialog.AcceptOpen) if dialog.exec_(): fileName = dialog.selectedFiles()[0] del dialog if not fileName: return base = os.path.basename(fileName) if not os.path.exists(os.path.join(self.book.source_path, "images", base)): copy(fileName, os.path.join(self.book.source_path, "images")) item = QListWidgetItem() item.setText(Path(fileName).name) item.setData(1, os.path.join(self.book.source_path, "images", Path(fileName).name)) self.image_list.addItem(item) def dropImage(self): item = self.image_list.currentItem() image = item.data(1) filename = os.path.join(self.book.source_path, "parts", image) os.remove(filename) self.loadImages() def loadImages(self): self.image_list.clear() for root, dir, files in os.walk(os.path.join(self.book.source_path, "images")): for file in files: filename = os.path.join(self.book.source_path, "images", Path(file).name) item = QListWidgetItem() item.setToolTip("Doubleclick image to insert into text") item.setText(Path(file).name) item.setData(1, filename) self.image_list.addItem(item) def partUp(self): pos = self.content_list.currentRow() item = self.content_list.takeItem(pos) self.content_list.insertItem(pos - 1, item) self.content_list.setCurrentRow(pos - 1) self.book.partUp(item.data(1).name) def partDown(self): pos = self.content_list.currentRow() item = self.content_list.takeItem(pos) self.content_list.insertItem(pos + 1, item) self.content_list.setCurrentRow(pos + 1) self.book.partDown(item.data(1).name) def partSelectionChanged(self, item): if item: part = item.data(1) self.filename = os.path.join(self.book.source_path, "parts", part.src) with open(self.filename, "r") as f: self.text_edit.setText(f.read()) self.trash_button.enabled = True self.up_button.enabled = self.content_list.currentRow() > 0 self.down_button.enabled = self.content_list.currentRow() < self.content_list.count() - 1 self.edit_button.enabled = True else: self.text_edit.setText("") self.trash_button.enabled = False self.up_button.enabled = False self.down_button.enabled = False self.edit_button.enabled = False def imageSelectionChanged(self, item): if item: self.image_trash_button.enabled = True else: self.image_trash_button.enabled = False def contentExpanded(self, value): if value: self.images.setExpanded(False) self.settings.setExpanded(False) def imagesExpanded(self, value): if value: self.content.setExpanded(False) self.settings.setExpanded(False) def appearanceExpanded(self, value): if value: self.content.setExpanded(False) self.images.setExpanded(False) self.settings.setExpanded(False) def settingsExpanded(self, value): if value: self.content.setExpanded(False) self.images.setExpanded(False) def closeEvent(self, event): self.writeSettings() event.accept() def createMenus(self): new_icon = QIcon(QPixmap(":/images/new.svg")) open_icon = QIcon(QPixmap(":/images/open.svg")) book_icon = QIcon(QPixmap(":/images/book.svg")) bold_icon = QIcon(QPixmap(":/images/bold.svg")) italic_icon = QIcon(QPixmap(":/images/italic.svg")) image_icon = QIcon(QPixmap(":/images/image.svg")) table_icon = QIcon(QPixmap(":/images/table.svg")) á_icon = QIcon(QPixmap(":/images/á.svg")) ã_icon = QIcon(QPixmap(":/images/ã.svg")) é_icon = QIcon(QPixmap(":/images/é.svg")) ê_icon = QIcon(QPixmap(":/images/ê.svg")) ó_icon = QIcon(QPixmap(":/images/ó.svg")) new_act = QAction(new_icon, "&New", self) new_act.setShortcuts(QKeySequence.New) new_act.setStatusTip("Create a new ebook project") new_act.triggered.connect(self.newFile) new_act.setToolTip("Create new ebook project") open_act = QAction(open_icon, "&Open", self) open_act.setShortcuts(QKeySequence.Open) open_act.setStatusTip("Open an existing ebook project") open_act.triggered.connect(self.open) open_act.setToolTip("Open an existing ebook project") book_act = QAction(book_icon, "&Create Book", self) book_act.setShortcuts(QKeySequence.SaveAs) book_act.setStatusTip("Create an ebook") book_act.triggered.connect(self.create) book_act.setToolTip("Create an ebook") pdf_act = QAction("Create &PDF", self) pdf_act.setStatusTip("Create PDF") pdf_act.setToolTip("Create PDF") pdf_act.triggered.connect(self.pdfExport) settings_act = QAction("&Settings", self) settings_act.setStatusTip("Open settings dialog") settings_act.triggered.connect(self.settingsDialog) settings_act.setToolTip("Open settings dialog") exit_act = QAction("E&xit", self) exit_act.setShortcuts(QKeySequence.Quit) exit_act.setStatusTip("Exit the application") exit_act.triggered.connect(self.close) self.undo_act = QAction("Undo", self) self.undo_act.setShortcut(QKeySequence.Undo) self.undo_act.setEnabled(False) self.undo_act.triggered.connect(self.doUndo) self.redo_act = QAction("Redo", self) self.redo_act.setShortcut(QKeySequence.Redo) self.redo_act.setEnabled(False) self.undo_act.triggered.connect(self.doRedo) self.cut_act = QAction("Cu&t", self) self.cut_act.setShortcut(QKeySequence.Cut) self.cut_act.triggered.connect(self.doCut) self.cut_act.setEnabled(False) self.copy_act = QAction("&Copy", self) self.copy_act.setShortcut(QKeySequence.Copy) self.copy_act.triggered.connect(self.doCopy) self.copy_act.setEnabled(False) self.paste_act = QAction("&Paste", self) self.paste_act.setShortcut(QKeySequence.Paste) self.paste_act.triggered.connect(self.doPaste) self.paste_act.setEnabled(False) bold_act = QAction(bold_icon, "Bold", self) bold_act.setShortcut(Qt.CTRL + Qt.Key_B) bold_act.triggered.connect(self.bold) italic_act = QAction(italic_icon, "Italic", self) italic_act.setShortcut(Qt.CTRL + Qt.Key_I) italic_act.triggered.connect(self.italic) image_act = QAction(image_icon, "Image", self) image_act.setShortcut(Qt.CTRL + Qt.Key_G) image_act.triggered.connect(self.insertImage) image_act.setToolTip("Insert an image") table_act = QAction(table_icon, "Table", self) table_act.setShortcut(Qt.CTRL + Qt.Key_T) table_act.triggered.connect(self.insertTable) table_act.setToolTip("Insert a table") á_act = QAction(á_icon, "á", self) á_act.triggered.connect(self.insertLetterA1) á_act.setToolTip("Insert letter á") ã_act = QAction(ã_icon, "ã", self) ã_act.triggered.connect(self.insertLetterA2) ã_act.setToolTip("Insert letter ã") é_act = QAction(é_icon, "é", self) é_act.triggered.connect(self.insertLetterE1) é_act.setToolTip("Insert letter é") ê_act = QAction(ê_icon, "ê", self) ê_act.triggered.connect(self.insertLetterE2) ê_act.setToolTip("Insert letter ê") ó_act = QAction(ó_icon, "ó", self) ó_act.triggered.connect(self.insertLetterO1) ó_act.setToolTip("Insert letter ó") about_act = QAction("&About", self) about_act.triggered.connect(self.about) about_act.setStatusTip("Show the application's About box") spell_act = QAction("&Spellcheck", self) spell_act.setShortcut(Qt.CTRL + Qt.Key_P) spell_act.triggered.connect(self.spellCheck) spell_act.setStatusTip("Spellcheck") file_menu = self.menuBar().addMenu("&File") file_menu.addAction(new_act) file_menu.addAction(open_act) file_menu.addAction(book_act) file_menu.addAction(pdf_act) file_menu.addSeparator() file_menu.addAction(settings_act) file_menu.addSeparator() file_menu.addAction(exit_act) edit_menu = self.menuBar().addMenu("&Edit") edit_menu.addAction(self.undo_act) edit_menu.addAction(self.redo_act) edit_menu.addSeparator() edit_menu.addAction(self.cut_act) edit_menu.addAction(self.copy_act) edit_menu.addAction(self.paste_act) format_menu = self.menuBar().addMenu("&Format") format_menu.addAction(bold_act) format_menu.addAction(italic_act) insert_menu = self.menuBar().addMenu("&Insert") insert_menu.addAction(image_act) insert_menu.addAction(table_act) help_menu = self.menuBar().addMenu("&Help") help_menu.addAction(about_act) help_menu.addAction(spell_act) file_tool_bar = self.addToolBar("File") file_tool_bar.addAction(new_act) file_tool_bar.addAction(open_act) file_tool_bar.addAction(book_act) format_tool_bar = self.addToolBar("Format") format_tool_bar.addAction(bold_act) format_tool_bar.addAction(italic_act) insert_toolbar = self.addToolBar("Insert") insert_toolbar.addAction(image_act) insert_toolbar.addAction(table_act) insert_toolbar.addAction(á_act) insert_toolbar.addAction(ã_act) insert_toolbar.addAction(é_act) insert_toolbar.addAction(ê_act) insert_toolbar.addAction(ó_act) def doUndo(self): self.text_edit.undo() def doRedo(self): self.text_edit.redo() def doCut(self): self.text_edit.cut() def doCopy(self): self.text_edit.copy() def doPaste(self): self.text_edit.paste() def insertImage(self): if not self.book: QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to load or create a book first!") return if not self.filename: QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!") return if self.image_list.count() == 0: QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to add an image to the image list first!") return if not self.image_list.currentItem(): QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select an image from the image list first!") return item = self.image_list.currentItem() filename = item.text() cursor = self.text_edit.textCursor() pos = cursor.position() base = filename.split(".")[0].replace("_", "-") cursor.insertText("![" + base + "](../images/" + filename + " \"" + base + "\")") cursor.setPosition(pos) self.text_edit.setTextCursor(cursor) def insertTable(self): cursor = self.text_edit.textCursor() pos = cursor.position() cursor.insertText("| alignLeft | alignCenter | unAligned | alignRight |\n" "| :--- | :---: | --- | ---: |\n" "| cell a | cell b | cell c | cell d |\n" "| cell e | cell f | cell g | cell h |\n") cursor.setPosition(pos) self.text_edit.setTextCursor(cursor) def insertLetterA1(self): cursor = self.text_edit.textCursor() pos = cursor.position() cursor.insertText("á") cursor.setPosition(pos + 1) self.text_edit.setTextCursor(cursor) def insertLetterA2(self): cursor = self.text_edit.textCursor() pos = cursor.position() cursor.insertText("ã") cursor.setPosition(pos + 1) self.text_edit.setTextCursor(cursor) def insertLetterE1(self): cursor = self.text_edit.textCursor() pos = cursor.position() cursor.insertText("é") cursor.setPosition(pos + 1) self.text_edit.setTextCursor(cursor) def insertLetterE2(self): cursor = self.text_edit.textCursor() pos = cursor.position() cursor.insertText("ê") cursor.setPosition(pos + 1) self.text_edit.setTextCursor(cursor) def insertLetterO1(self): cursor = self.text_edit.textCursor() pos = cursor.position() cursor.insertText("ó") cursor.setPosition(pos + 1) self.text_edit.setTextCursor(cursor) def createStatusBar(self): self.statusBar().showMessage("Ready") def about(self): QMessageBox.about(self, "About " + QCoreApplication.applicationName(), "EbookCreator\nVersion: " + QCoreApplication.applicationVersion() + "\n(C) Copyright 2019 Olaf Japp. All rights reserved.\n\nThis program is provided AS IS with NO\nWARRANTY OF ANY KIND, INCLUDING THE\nWARRANTY OF DESIGN, MERCHANTABILITY AND\nFITNESS FOR A PATICULAR PURPOSE.") def newFile(self): dlg = ProjectWizard(self.install_directory, parent = self) dlg.loadBook.connect(self.loadBook) dlg.show() def open(self): fileName = "" dialog = QFileDialog() dialog.setFileMode(QFileDialog.AnyFile) dialog.setNameFilter("EbookCreator (book.qml);;All (*)") dialog.setWindowTitle("Load Ebook") dialog.setOption(QFileDialog.DontUseNativeDialog, True) dialog.setAcceptMode(QFileDialog.AcceptOpen) dialog.setDirectory(os.path.join(self.install_directory, "sources")) if dialog.exec_(): fileName = dialog.selectedFiles()[0] del dialog if not fileName: return self.loadBook(fileName) def writeSettings(self): settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName()) settings.setValue("geometry", self.saveGeometry()) settings.setValue("lastBook", self.last_book) def readSettings(self): settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName()) geometry = settings.value("geometry", QByteArray()) self.last_book = settings.value("lastBook") if not geometry: availableGeometry = QApplication.desktop().availableGeometry(self) self.resize(availableGeometry.width() / 3, availableGeometry.height() / 2) self.move((availableGeometry.width() - self.width()) / 2, (availableGeometry.height() - self.height()) / 2) else: self.restoreGeometry(geometry) def bold(self): if not self.filename: QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!") return cursor = self.text_edit.textCursor() pos = cursor.position() if not cursor.hasSelection(): cursor.select(QTextCursor.WordUnderCursor) cursor.insertText("**" + cursor.selectedText() + "**") cursor.setPosition(pos + 2) self.text_edit.setTextCursor(cursor) def italic(self): if not self.filename: QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!") return cursor = self.text_edit.textCursor() pos = cursor.position() if not cursor.hasSelection(): cursor.select(QTextCursor.WordUnderCursor) cursor.insertText("*" + cursor.selectedText() + "*") cursor.setPosition(pos + 1) self.text_edit.setTextCursor(cursor) def create(self): filename = "" dialog = QFileDialog() dialog.setFileMode(QFileDialog.AnyFile) dialog.setNameFilter("ePub3 (*.epub);;All (*)") dialog.setWindowTitle("Create Ebook") dialog.setOption(QFileDialog.DontUseNativeDialog, True) dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setDirectory(self.book.source_path) dialog.setDefaultSuffix("epub") if dialog.exec_(): filename = dialog.selectedFiles()[0] del dialog if not filename: return QApplication.setOverrideCursor(Qt.WaitCursor) createEpub(filename, self.book, self) QApplication.restoreOverrideCursor() def loadStatusChanged(self, status): if status == 1: self.book = self.component.create() if self.book is not None: self.book.setFilename(self.last_book) self.book.setWindow(self) else: for error in self.component.errors(): print(error.toString()) return self.content_list.clear() for part in self.book.parts: item = QListWidgetItem() item.setText(part.name) item.setData(1, part) self.content_list.addItem(item) self.loadImages() self.setWindowTitle(QCoreApplication.applicationName() + " - " + self.book.name) self.content.setExpanded(True) self.content_list.setCurrentRow(0) elif status == 3: for error in self.component.errors(): print(error.toString()) return def loadBook(self, filename): self.last_book = filename self.filename = "" engine = QQmlEngine() self.component = QQmlComponent(engine) self.component.statusChanged.connect(self.loadStatusChanged) self.component.loadUrl(QUrl.fromLocalFile(filename)) def settingsDialog(self): dlg = SettingsDialog(self.theme, self.palette().highlight().color().name(), parent=self) dlg.exec() if dlg.theme != self.theme or dlg.hilite_color != self.palette().highlight().color().name(): settings = QSettings(QSettings.IniFormat, QSettings.UserScope, QCoreApplication.organizationName(), QCoreApplication.applicationName()) settings.setValue("theme", dlg.theme) settings.setValue("hiliteColor", dlg.hilite_color) msgBox = QMessageBox() msgBox.setText("Please restart the app to change the theme!") msgBox.exec() def textChanged(self): text = self.text_edit.toPlainText() if self.filename: with open(self.filename, "w") as f: f.write(text) self.lock = Lock() with self.lock: if not self.tread_running: self.tread_running = True self.htmlReady.connect(self.previewReady) thread = Thread(target=self.createHtml, args=(text,)) thread.daemon = True thread.start() def previewReady(self, html): self.preview.setHtml(html, baseUrl=QUrl(Path(os.path.join(self.book.source_path, "parts", "index.html")).as_uri())) self.htmlReady.disconnect() with self.lock: self.tread_running = False def createHtml(self, text): html = "<html>\n<head>\n" html += "<link href=\"../css/pastie.css\" rel=\"stylesheet\" type=\"text/css\"/>\n" html += "<link href=\"../css/stylesheet.css\" rel=\"stylesheet\" type=\"text/css\"/>\n" html += "</head>\n<body>\n" html += markdown(text, html4tags=False, extras=["fenced-code-blocks", "wiki-tables", "tables", "header-ids"]) html += "\n</body>\n</html>" html = addLineNumbers(html) self.htmlReady.emit(html) def pdfExport(self): p = PdfExport(self.book, self.statusBar()) def spellCheck(self): if not self.filename: QMessageBox.warning(self, QCoreApplication.applicationName(), "You have to select part from the book content first!") return cursor = self.text_edit.textCursor() pos = cursor.position() if not cursor.hasSelection(): cursor.select(QTextCursor.WordUnderCursor) spell = Speller(lang='en') changed = spell(cursor.selectedText()) if changed != cursor.selectedText(): cursor.insertText(changed) self.text_edit.setTextCursor(cursor)
class AccountsView(QSplitter): computing_privkeys_signal = pyqtSignal() show_privkeys_signal = pyqtSignal() def __init__(self, main_window: ElectrumWindow, wallet: Wallet) -> None: super().__init__(main_window) self._main_window = main_window self._wallet = wallet self._main_window.account_created_signal.connect( self._on_account_created) self._selection_list = QListWidget() self._selection_list.setMinimumWidth(150) self._tab_widget = QTabWidget() self.addWidget(self._selection_list) self.addWidget(self._tab_widget) self.setStretchFactor(1, 2) self._selection_list.setIconSize(QSize(32, 32)) self._selection_list.setContextMenuPolicy(Qt.CustomContextMenu) self._selection_list.customContextMenuRequested.connect( self._create_account_menu) self._update_account_list() def _on_account_created(self, new_account_id: int) -> None: self._update_account_list() def get_tab_widget(self) -> QTabWidget: return self._tab_widget def _update_account_list(self) -> None: self._selection_list.clear() for account in self._wallet.get_accounts(): item = QListWidgetItem() keystore = account.get_keystore() derivation_type = keystore.derivation_type if keystore is not None \ else DerivationType.NONE is_watching_only = keystore.is_watching_only( ) if keystore is not None else True icon_state = "inactive" if is_watching_only else "active" if derivation_type == DerivationType.ELECTRUM_MULTISIG: tooltip_text = _("Multi-signature account") icon_filename = "icons8-group-task-80-blueui-{}.png" elif derivation_type == DerivationType.HARDWARE: tooltip_text = _("Hardware wallet account") icon_filename = "icons8-usb-2-80-blueui-{}.png" elif derivation_type == DerivationType.IMPORTED: # This should not be watch only as imported public keys have no keystore. tooltip_text = _("Imported private key account") icon_filename = "icons8-key-80-plus-blueui-{}.png" elif derivation_type == DerivationType.ELECTRUM_OLD: tooltip_text = _("Old-style Electrum account") icon_filename = "icons8-password-1-80-blueui-{}.png" elif derivation_type == DerivationType.BIP32: tooltip_text = _("BIP32 account") icon_filename = "icons8-grand-master-key-80-blueui-{}.png" else: # This should always be watch only as imported public keys have no keystore. tooltip_text = _("Imported public key account") icon_filename = "icons8-key-80-plus-blueui-{}.png" if is_watching_only: tooltip_text += f" ({_('watch only')})" item.setIcon(read_QIcon(icon_filename.format(icon_state))) item.setData(Qt.UserRole, account.get_id()) item.setText(account.display_name()) item.setToolTip(tooltip_text) self._selection_list.addItem(item) def _create_account_menu(self, position) -> None: item = self._selection_list.currentItem() if not item: return account_id = item.data(Qt.UserRole) account = self._wallet.get_account(account_id) menu = QMenu() menu.addAction(_("&Information"), partial(self._show_account_information, account_id)) seed_menu = menu.addAction( _("View &Secured Data"), partial(self._view_secured_data, main_window=self._main_window, account_id=account_id)) seed_menu.setEnabled( not account.is_watching_only() and not isinstance(account, MultisigAccount) \ and not account.is_hardware_wallet()) menu.addSeparator() private_keys_menu = menu.addMenu(_("&Private keys")) import_menu = private_keys_menu.addAction( _("&Import"), partial(self._import_privkey, main_window=self._main_window, account_id=account_id)) import_menu.setEnabled(account.can_import_privkey()) export_menu = private_keys_menu.addAction( _("&Export"), partial(self._export_privkeys, main_window=self._main_window, account_id=account_id)) export_menu.setEnabled(account.can_export()) if account.can_import_address(): menu.addAction(_("Import addresses"), partial(self._import_addresses, account_id)) menu.addSeparator() labels_menu = menu.addMenu(_("&Labels")) action = labels_menu.addAction( _("&Import"), partial(self._main_window.do_import_labels, account_id)) # TODO(rt12) BACKLOG The plan is to implement this in a way that lets the user specify # whether to skip importing entries that already have a label (skip / overwrite). action.setEnabled(False) labels_menu.addAction( _("&Export"), partial(self._main_window.do_export_labels, account_id)) menu.exec_(self._selection_list.viewport().mapToGlobal(position)) def _show_account_information(self, account_id: int) -> None: dialog = AccountInformationDialog(self._main_window, self._wallet, account_id, self) dialog.exec_() @protected def _view_secured_data(self, main_window: ElectrumWindow, account_id: int = -1, password: Optional[str] = None) -> None: # account_id is a keyword argument so that 'protected' can identity the correct wallet # window to do the password request in the context of. account = self._wallet.get_account(account_id) keystore = account.get_keystore() from .secured_data_dialog import SecuredDataDialog d = SecuredDataDialog(self._main_window, self, keystore, password) d.exec_() @protected def _import_privkey(self, main_window: ElectrumWindow, account_id: int = -1, password: Optional[str] = None) -> None: # account_id is a keyword argument so that 'protected' can identity the correct wallet # window to do the password request in the context of. account = self._wallet.get_account(account_id) title, msg = _('Import private keys'), _("Enter private keys") self._main_window._do_import( title, msg, lambda x: account.import_private_key(x, password)) def _import_addresses(self, account_id: int) -> None: account = self._wallet.get_account(account_id) title, msg = _('Import addresses'), _("Enter addresses") def import_addr(addr): address = address_from_string(addr) if account.import_address(address): return addr # Show duplicate addition same as good addition. return addr self._main_window._do_import(title, msg, import_addr) @protected def _export_privkeys(self, main_window: ElectrumWindow, account_id: int = -1, password: Optional[str] = None) -> None: account = self._wallet.get_account(account_id) if isinstance(self._wallet, MultisigAccount): self.show_message( _('WARNING: This is a multi-signature wallet.') + '\n' + _('It can not be "backed up" by simply exporting these private keys.' )) d = WindowModalDialog(self, _('Private keys')) d.setMinimumSize(850, 300) vbox = QVBoxLayout(d) msg = "\n".join([ _("WARNING: ALL your private keys are secret."), _("Exposing a single private key can compromise your entire wallet!" ), _("In particular, DO NOT use 'redeem private key' services proposed by third parties." ) ]) vbox.addWidget(QLabel(msg)) e = QTextEdit() e.setReadOnly(True) vbox.addWidget(e) defaultname = 'electrumsv-private-keys.csv' select_msg = _('Select file to export your private keys to') hbox, filename_e, csv_button = filename_field(self._main_window.config, defaultname, select_msg) vbox.addLayout(hbox) b = OkButton(d, _('Export')) b.setEnabled(False) vbox.addLayout(Buttons(CancelButton(d), b)) private_keys = {} keyinstance_ids = account.get_keyinstance_ids() done = False cancelled = False def privkeys_thread(): for keyinstance_id in keyinstance_ids: time.sleep(0.1) if done or cancelled: break privkey = account.export_private_key(keyinstance_id, password) script_template = account.get_script_template_for_id( keyinstance_id) script_text = script_template_to_string(script_template) private_keys[script_text] = privkey self.computing_privkeys_signal.emit() if not cancelled: self.computing_privkeys_signal.disconnect() self.show_privkeys_signal.emit() def show_privkeys(): s = "\n".join('{}\t{}'.format(script_text, privkey) for script_text, privkey in private_keys.items()) e.setText(s) b.setEnabled(True) self.show_privkeys_signal.disconnect() nonlocal done done = True def on_dialog_closed(*args): nonlocal done nonlocal cancelled if not done: cancelled = True self.computing_privkeys_signal.disconnect() self.show_privkeys_signal.disconnect() self.computing_privkeys_signal.connect( lambda: e.setText("Please wait... %d/%d" % (len(private_keys), len(keyinstance_ids)))) self.show_privkeys_signal.connect(show_privkeys) d.finished.connect(on_dialog_closed) threading.Thread(target=privkeys_thread).start() if not d.exec_(): done = True return filename = filename_e.text() if not filename: return try: self.do_export_privkeys(filename, private_keys, csv_button.isChecked()) except (IOError, os.error) as reason: txt = "\n".join([ _("ElectrumSV was unable to produce a private key-export."), str(reason) ]) MessageBox.show_error(txt, title=_("Unable to create csv")) except Exception as e: self.show_message(str(e)) return MessageBox.show_message(_('Private keys exported'), self._main_window) def do_export_privkeys(self, fileName: str, pklist, is_csv): with open(fileName, "w+") as f: if is_csv: transaction = csv.writer(f) transaction.writerow(["reference", "private_key"]) for key_text, pk in pklist.items(): transaction.writerow([key_text, pk]) else: f.write(json.dumps(pklist, indent=4))
class NewProjectManager(QDialog): 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) def accept(self): logger.debug("Accept...") self._start_wizard() super().accept() def _project_selected(self): self.list_templates.clear() item = self.list_projects.currentItem() category = item.text() for template in self.template_registry.list_templates_for_cateogory( category): item = QListWidgetItem(template.type_name) item.setData(Qt.UserRole, template) item = self.list_templates.addItem(item) self.list_templates.setCurrentRow(0) def _template_selected(self): item = self.list_templates.currentItem() ptype = item.data(Qt.UserRole) self.text_info.setText(ptype.description) def _start_wizard(self): item = self.list_templates.currentItem() if item is not None: project_type = item.data(Qt.UserRole) wizard = WizardProject(project_type, self) wizard.show()
class Thumbnail(DockWidget): item_double_clicked = pyqtSignal(int) current_index_changed = pyqtSignal(int) remove_project_signal = pyqtSignal(int) selected_project_changed = pyqtSignal(ProjectDocument) analysis_compare = pyqtSignal(int) synchronize_changed_signal = pyqtSignal(bool) def __init__(self, history_project_manager: HistoryProjectManager, origin_project, parent=None): DockWidget.__init__(self, widget_title="历史项目", parent=parent) self.content_widget = QWidget() self.setWidget(self.content_widget) # 初始化窗口内组件 self.tb = QToolBar(self) self.list_widget = QListWidget() self.layout = QVBoxLayout() self._origin_project = origin_project self._list_item_to_project = {} self._history_project_manger = history_project_manager self.__create_layout() self.__create_tool_bar(self.tb) self.__create_list_widget() projects = self._history_project_manger.get_projects_document() for project in projects: self.add_project(project) def __del__(self): del self.list_widget del self.tb del self._history_project_manger # 创建布局 def __create_layout(self): self.layout.addWidget(self.tb) self.layout.addWidget(self.list_widget) self.content_widget.setLayout(self.layout) def current_project(self) -> ProjectDocument: return self._list_item_to_project[self.list_widget.currentItem()] # 创建工具栏 def __create_tool_bar(self, toolbar): self.new_action = QAction(QIcon(":/add.png"), "添加", self) self.new_action.triggered.connect(self.open_new_project) toolbar.addAction(self.new_action) self.delete_action = QAction(QIcon(':/remove.png'), "关闭", self) self.delete_action.triggered.connect(self.remove_project) toolbar.addAction(self.delete_action) self.analysis = QAction(QIcon(":/fenxi.png"), "历史数据分析", parent=self) self.analysis.triggered.connect(self.analysis_all_project) toolbar.addAction(self.analysis) self.analysis_compare = QAction(QIcon("://duibifenxi.png"), "数据对比", parent=self) toolbar.addAction(self.analysis_compare) self.analysis_compare.triggered.connect(self.analysis_project_with) self._is_synchronize_checked = QCheckBox("同步", self) self._is_synchronize_checked.setChecked(True) self._is_synchronize_checked.toggled.connect( self.synchronize_changed_signal) toolbar.addSeparator() toolbar.addWidget(self._is_synchronize_checked) def analysis_all_project(self): projects = self._history_project_manger.get_projects() projects.insert(0, self._origin_project.project()) years = [] for year in range(len(projects)): years.append(2014 + year) data = get_projects_area_data(projects, years) if not data: return chart = PolygonalChart("历史数据对比", data, self) chart.show() def analysis_project_with(self): """""" def __create_list_widget(self): # 设置列表窗口 self.list_widget.setGeometry(QtCore.QRect(90, 330, 621, 171)) self.list_widget.setIconSize(QtCore.QSize(100, 100)) self.list_widget.setMovement(QtWidgets.QListView.Static) self.list_widget.setResizeMode(QtWidgets.QListView.Adjust) self.list_widget.setGridSize(QtCore.QSize(150, 150)) self.list_widget.setViewMode(QtWidgets.QListView.IconMode) self.list_widget.setObjectName("listWidget") # item样式设置 self.list_widget.setStyleSheet( "QListWidget::item{border:1px solid gray; color:black; margin-top:20px;}" ) # 列表窗口右键点击菜单 self.list_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.list_widget.customContextMenuRequested.connect( self.my_listwidget_context) # 关闭自动排序 self.list_widget.setSortingEnabled(False) # 去除垂直滚动条 self.list_widget.setWrapping(0) self.list_widget.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAsNeeded) # 设置双击缩略图的信号与槽连接 self.list_widget.itemClicked.connect(self.__item_clicked) self.list_widget.itemDoubleClicked.connect(self.__item_double_clicked) def add_project(self, project): fit_pixmap = project.get_pixmap() fit_pixmap = fit_pixmap.scaled(80, 80, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation) new_item = ListWidgetItem(QIcon(fit_pixmap), project.project_brief_info()) new_item.setToolTip(project.project_brief_info()) new_item.setSizeHint(QtCore.QSize(90, 130)) self.list_widget.addItem(new_item) self.list_widget.setCurrentItem(new_item) self._list_item_to_project[new_item] = project # 右键菜单 def my_listwidget_context(self, point): pop_menu = QtWidgets.QMenu() if self.list_widget.itemAt(point): pop_menu.addAction(self.new_action) pop_menu.addAction(self.delete_action) else: pop_menu.addAction(self.new_action) pop_menu.exec_(QtGui.QCursor.pos()) # 鼠标单击 def __item_clicked(self, clicked_item): """""" def __item_double_clicked(self, item): if item in self._list_item_to_project: self.selected_project_changed.emit( self._list_item_to_project[item]) def open_new_project(self): file_format = "Project files (*.mfb)" dir_ = "." file_names = QFileDialog.getOpenFileNames(self, "选择遥感图片", dir_, file_format)[0] if file_names: project_format = ProjectFormat() had_files = self._history_project_manger.get_all_files() for file in file_names: if file == self._origin_project.get_file_name( ) or file in had_files: continue project = ProjectDocument(project_format.read_project(file)) if not project: continue self._history_project_manger.add_history_project(project) self.add_project(project) else: return None # 工具栏删除 def remove_project(self): current_project_item = self.list_widget.currentItem() if current_project_item and current_project_item in self._list_item_to_project: project = self._list_item_to_project[current_project_item] self._history_project_manger.remove_history_project(project) self.list_widget.removeItemWidget(current_project_item) self.list_widget.takeItem( self.list_widget.row(current_project_item)) del self._list_item_to_project[current_project_item] del current_project_item self.list_widget.update()
class ChatSetter(QWidget): """...""" saved = pyqtSignal(str, bool, list) def __init__(self, name_): super(ChatSetter, self).__init__() self._name = name_ self._setup_ui() def enable(self, enable_): """...""" self._enable.setChecked(enable_) def display_filter(self, filter_list_): """...""" self._filter.clear() for _name in filter_list_: _item = QListWidgetItem(_name) _item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable) self._filter.addItem(_item) def _on_clicked(self, item_): self._filter.setCurrentItem(item_) for _index in range(self._filter.count()): self._filter.item(_index).setBackground(QColor('white')) self._filter.item(_index).setForeground(QColor('black')) item_.setBackground(QColor(0, 105, 217)) item_.setForeground(QColor('white')) def _setup_ui(self): _vbox = QVBoxLayout() self._enable = QCheckBox(self._name) self._filter = QListWidget() self._filter.itemClicked.connect(self._on_clicked) self._filter.itemChanged.connect(self._save_filter) self._filter.setSelectionMode(QAbstractItemView.SingleSelection) _vbox.addWidget(self._enable) _vbox.addWidget(self._filter) _vbox.addLayout(self._gen_filter_btn_group()) self.setLayout(_vbox) def _gen_filter_btn_group(self): _add = QPushButton('Add') _add.clicked.connect(self._add_filter) _delete = QPushButton('Delete') _delete.clicked.connect(self._delete_filter) _btn_group = QHBoxLayout() _btn_group.addWidget(_add) _btn_group.addWidget(_delete) _btn_group.setSpacing(0) return _btn_group def _add_filter(self): _name = GuiUtils.input_dialog(self, 'Filter', 'Add filter:') if _name: _item = QListWidgetItem(_name) _item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsEditable) self._filter.addItem(_item) self._save_filter() def _delete_filter(self): try: _item = self._filter.currentItem() if GuiUtils.question_dialog(self, 'Filter', 'Delete filter: ' + _item.text()): _item = self._filter.takeItem(self._filter.currentRow()) del _item self._save_filter() except Exception as e: _msg = 'Choose one item before deleting.' print(_msg) def _save_filter(self): self.saved.emit(self._name, self._enable.isChecked(), [ self._filter.item(_index).text() for _index in range(self._filter.count()) ])
class Ui_MainWindow(object): def __init__(self): self.player = main2.player() self.music_titles = [] self.music_href = [] self.index = "" self.music_player = M.QMediaPlayer() self.searched = "" def setupUi(self, MainWindow): os.environ['QT_MULTIMEDIA_PREFERRED_PLUGINS'] = 'windowsmediafoundation' MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # self.img = QtWidgets.QLabel(self.centralwidget) #self.img.setGeometry(QtCore.QRect(100, 90, 511, 251)) #self.img.setObjectName("img") self.currentTimeLabel = QtWidgets.QLabel(self.centralwidget) self.currentTimeLabel.setMinimumSize(QtCore.QSize(80, 0)) self.currentTimeLabel.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.currentTimeLabel.setObjectName("currentTimeLabel") self.currentTimeLabel.setGeometry(QtCore.QRect(70, 325, 61, 90)) self.volumeSlider = QtWidgets.QSlider(self.centralwidget) self.volumeSlider.setMaximum(100) self.volumeSlider.setProperty("value", 100) self.volumeSlider.setOrientation(QtCore.Qt.Horizontal) self.volumeSlider.setObjectName("volumeSlider") self.volumeSlider.setGeometry(QtCore.QRect(550, 440, 61, 22)) self.timeSlider = QtWidgets.QSlider(self.centralwidget) self.timeSlider.setOrientation(QtCore.Qt.Horizontal) self.timeSlider.setObjectName("timeSlider") self.timeSlider.setGeometry(QtCore.QRect(160, 360, 481, 22)) self.timeSlider.setOrientation(QtCore.Qt.Horizontal) self.totalTimeLabel = QtWidgets.QLabel(self.centralwidget) self.totalTimeLabel.setMinimumSize(QtCore.QSize(80, 0)) self.totalTimeLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) self.totalTimeLabel.setGeometry(QtCore.QRect(650,325,61,90)) self.timeSlider.setOrientation(QtCore.Qt.Horizontal) self.list=QListWidget(self.centralwidget) self.list.setGeometry(QtCore.QRect(100, 90, 511, 251)) self.Play = QtWidgets.QPushButton(self.centralwidget) self.Play.setGeometry(QtCore.QRect(350, 440, 61, 41)) self.Play.setObjectName("Play") self.Play.clicked.connect(self.Start) self.pause_bt = QtWidgets.QPushButton(self.centralwidget) self.pause_bt.setGeometry(QtCore.QRect(420,440,61,41)) self.pause_bt.setObjectName('Pause') self.pause_bt.clicked.connect(self.Pause) self.Next = QtWidgets.QPushButton(self.centralwidget) self.Next.setGeometry(QtCore.QRect(310, 450, 31, 31)) self.Next.setObjectName("Next") self.label_title = QtWidgets.QLabel(self.centralwidget) self.label_title.setGeometry(QtCore.QRect(156, 390, 421, 31)) self.label_title.setObjectName("label_title") self.Search = QtWidgets.QLineEdit(self.centralwidget) self.Search.setGeometry(QtCore.QRect(172, 20, 411, 20)) self.Search.setText("") self.Search.setObjectName("Search") self.Search_button = QtWidgets.QPushButton(self.centralwidget) self.Search_button.setGeometry(QtCore.QRect(630, 20, 75, 23)) self.Search_button.setObjectName("Search_button") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) #self.horizontalSlider = QtWidgets.QSlider(self.centralwidget) #self.horizontalSlider.setGeometry(QtCore.QRect(160, 360, 481, 22)) #self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal) #self.horizontalSlider.setObjectName("horizontalSlider") self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) self.Search_button.clicked.connect(self.search_clicked) self.list.clicked.connect(self.list_OnClicked) def retranslateUi(self, MainWindow): self._translate = QtCore.QCoreApplication.translate self.currentTimeLabel.setText(self._translate("MainWindow", "0:00")) MainWindow.setWindowTitle(self._translate("MainWindow", "Fake Spotify")) #self.img.setText(self._translate("MainWindow", "TextLabel")) self.Play.setText(self._translate("MainWindow", "Play")) self.Next.setText(self._translate("MainWindow", "Next")) self.pause_bt.setText(self._translate("MainWindow","Pause")) self.Search_button.setText(self._translate("MainWindow", "Search")) self.label_title.setText(self._translate("MainWindow", "Download complete")) self.music_player.durationChanged.connect(self.update_duration) self.music_player.positionChanged.connect(self.update_position) self.timeSlider.valueChanged.connect(self.music_player.setPosition) self.volumeSlider.valueChanged.connect(self.music_player.setVolume) def Start(self): self.music_player.play() def Pause(self): self.music_player.pause() #ilk bu çalışacak def search_clicked(self): self.searched = self.Search.text() self.thread =threading.Thread(target=self.player.search, args = (self.searched,)) self.thread.start() self.insert_list() #buna basıldığında şarkı açılması lazım def insert_list(self): self.list.clear() self.music_titles,self.music_href = self.player.chrome() cache = "" for title in self.music_titles: title = title.strip() if cache != title: self.list.addItem(title) cache = title #when user click the listwiew def list_OnClicked(self): self.thread = threading.Thread(target = self.play_music) self.thread.start() def set_label_title(self): self.label_title.setText(self._translate("MainWindow",self.music_titles[self.index])) #play music thread def play_music(self): self.index = self.list.row(self.list.currentItem()) print(self.music_href[self.index],"index",self.index) name = self.player.music_choose(self.music_href[self.index],self.music_titles[self.index].strip() + ".mp4") self.url = QtCore.QUrl.fromLocalFile(name) self.content = M.QMediaContent(self.url) self.music_player.setMedia(self.content) self.music_player.play() def update_duration(self,duration): print("!", duration) print("?", self.music_player.duration()) self.timeSlider.setMaximum(duration) if duration >= 0: self.totalTimeLabel.setText(self.hhmmss(duration)) def update_position(self, position): if position >= 0: self.currentTimeLabel.setText(self.hhmmss(position)) self.timeSlider.blockSignals(True) self.timeSlider.setValue(position) self.timeSlider.blockSignals(False) def hhmmss(self,ms): s = round(ms / 1000) m,s = divmod(s,60) h,m = divmod(m,60) return ("%d:%02d:%02d" % (h,m,s)) if h else ("%d:%02d" % (m,s))
class Advanced_event_filtering_dialog(QDialog): """ Dialog for visualizing advanced event filtering results """ summary_header = ["Observation id", "Number of occurences", "Total duration (s)", "Duration mean (s)", "Std Dev"] details_header = ["Observation id", "Comment", "Start time", "Stop time", "Duration (s)"] def __init__(self, events): super().__init__() self.events = events self.out = [] self.setWindowTitle("Advanced event filtering") vbox = QVBoxLayout() lb = QLabel("Filter") vbox.addWidget(lb) hbox = QHBoxLayout() self.logic = QLineEdit("") hbox.addWidget(self.logic) self.pb_filter = QPushButton("Filter events", clicked=self.filter) hbox.addWidget(self.pb_filter) self.pb_clear = QPushButton("Clear", clicked=self.logic.clear) self.pb_clear.setIcon(QIcon.fromTheme("edit-clear")) hbox.addWidget(self.pb_clear) vbox.addLayout(hbox) hbox = QHBoxLayout() self.rb_summary = QRadioButton("Summary", toggled=self.filter) self.rb_summary.setChecked(True) hbox.addWidget(self.rb_summary) self.rb_details = QRadioButton("Details", toggled=self.filter) hbox.addWidget(self.rb_details) vbox.addLayout(hbox) hbox = QHBoxLayout() vbox2 = QVBoxLayout() vbox2.addWidget(QLabel("Subjects")) self.lw1 = QListWidget() vbox2.addWidget(self.lw1) hbox.addLayout(vbox2) vbox2 = QVBoxLayout() vbox2.addWidget(QLabel("Behaviors")) self.lw2 = QListWidget() vbox2.addWidget(self.lw2) hbox.addLayout(vbox2) self.add_subj_behav_button = QPushButton("", clicked=self.add_subj_behav) self.add_subj_behav_button.setIcon(QIcon.fromTheme("go-up")) hbox.addWidget(self.add_subj_behav_button) vbox2 = QVBoxLayout() vbox2.addWidget(QLabel("Logical operators")) self.lw3 = QListWidget() self.lw3.addItems(["AND", "OR"]) vbox2.addWidget(self.lw3) hbox.addLayout(vbox2) self.add_logic_button = QPushButton("", clicked=self.add_logic) self.add_logic_button.setIcon(QIcon.fromTheme("go-up")) hbox.addWidget(self.add_logic_button) vbox.addLayout(hbox) self.lb_results = QLabel("Results") vbox.addWidget(self.lb_results) self.tw = QTableWidget(self) vbox.addWidget(self.tw) hbox = QHBoxLayout() hbox.addItem(QSpacerItem(241, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) self.pb_save = QPushButton("Save results", clicked=self.save_results) hbox.addWidget(self.pb_save) self.pb_close = QPushButton("Close", clicked=self.close) hbox.addWidget(self.pb_close) vbox.addLayout(hbox) self.setLayout(vbox) subjects_list, behaviors_list = [], [] for obs_id in events: for subj_behav in events[obs_id]: subj, behav = subj_behav.split("|") subjects_list.append(subj) behaviors_list.append(behav) subjects_set = sorted(set(subjects_list)) behaviors_set = sorted(set(behaviors_list)) self.lw1.addItems(subjects_set) self.lw2.addItems(behaviors_set) self.resize(640, 640) def add_subj_behav(self): """ add subject|behavior of selected listwidgets items in lineEdit """ if self.lw1.currentItem() and self.lw2.currentItem(): self.logic.insert(f'"{self.lw1.currentItem().text()}|{self.lw2.currentItem().text()}" ') else: QMessageBox.warning(self, programName, "Select a subject and a behavior") def add_logic(self): """ add selected logic operaton to lineedit """ if self.lw3.currentItem(): text = "" if self.lw3.currentItem().text() == "AND": text = " & " if self.lw3.currentItem().text() == "OR": text = " | " if text: self.logic.insert(text) else: QMessageBox.warning(self, programName, "Select a logical operator") def filter(self): """ filter events """ if not self.logic.text(): return if self.logic.text().count('"') % 2: QMessageBox.warning(self, programName, f'Wrong number of double quotes (")') return sb_list = re.findall('"([^"]*)"', self.logic.text()) self.out = [] flag_error = False for obs_id in self.events: logic = self.logic.text() for sb in set(sb_list): logic = logic.replace(f'"{sb}"', f'self.events[obs_id]["{sb}"]') if sb not in self.events[obs_id]: self.events[obs_id][sb] = io([0, 0]) try: eval_result = eval(logic) for i in eval_result: if not i.empty: self.out.append([obs_id, "", f"{i.lower}", f"{i.upper}", f"{i.upper - i.lower:.3f}"]) except KeyError: self.out.append([obs_id, "subject / behavior not found", "NA", "NA", "NA"]) except Exception: # out += f"Error in {self.logic.text()}" + "\n" error_type, error_file_name, error_lineno = utilities.error_info(sys.exc_info()) self.out.append([obs_id, f"Error in {self.logic.text()}: {error_type} ", "NA", "NA", "NA"]) flag_error = True self.tw.clear() if flag_error or self.rb_details.isChecked(): self.lb_results.setText(f"Results ({len(self.out)} event{'s'*(len(self.out) > 1)})") self.tw.setRowCount(len(self.out)) self.tw.setColumnCount(len(self.details_header)) # obs_id, comment, start, stop, duration self.tw.setHorizontalHeaderLabels(self.details_header) if not flag_error and self.rb_summary.isChecked(): summary = {} for row in self.out: obs_id, _, start, stop, duration = row if obs_id not in summary: summary[obs_id] = [] summary[obs_id].append(float(duration)) self.out = [] for obs_id in summary: self.out.append([ obs_id, str(len(summary[obs_id])), str(round(sum(summary[obs_id]), 3)), str(round(statistics.mean(summary[obs_id]), 3)), str(round(statistics.stdev(summary[obs_id]), 3)) if len(summary[obs_id]) > 1 else "NA" ]) self.lb_results.setText(f"Results ({len(summary)} observation{'s'*(len(summary) > 1)})") self.tw.setRowCount(len(summary)) self.tw.setColumnCount(len(self.summary_header)) # obs_id, mean, stdev self.tw.setHorizontalHeaderLabels(self.summary_header) for r in range(len(self.out)): for c in range(self.tw.columnCount()): item = QTableWidgetItem() item.setText(self.out[r][c]) item.setFlags(Qt.ItemIsEnabled) self.tw.setItem(r, c, item) def save_results(self): """ save results """ extended_file_formats = ["Tab Separated Values (*.tsv)", "Comma Separated Values (*.csv)", "Open Document Spreadsheet ODS (*.ods)", "Microsoft Excel Spreadsheet XLSX (*.xlsx)", "Legacy Microsoft Excel Spreadsheet XLS (*.xls)", "HTML (*.html)"] file_formats = ["tsv", "csv", "ods", "xlsx", "xls", "html"] file_name, filter_ = QFileDialog().getSaveFileName(None, "Save results", "", ";;".join(extended_file_formats)) if not file_name: return output_format = file_formats[extended_file_formats.index(filter_)] if pathlib.Path(file_name).suffix != "." + output_format: file_name = str(pathlib.Path(file_name)) + "." + output_format # check if file with new extension already exists if pathlib.Path(file_name).is_file(): if dialog.MessageDialog(programName, f"The file {file_name} already exists.", [CANCEL, OVERWRITE]) == CANCEL: return if self.rb_details.isChecked(): tablib_dataset = tablib.Dataset(headers=self.details_header) if self.rb_summary.isChecked(): tablib_dataset = tablib.Dataset(headers=self.summary_header) tablib_dataset.title = utilities.safe_xl_worksheet_title(self.logic.text(), output_format) [tablib_dataset.append(x) for x in self.out] try: if output_format in ["csv", "tsv", "html"]: with open(file_name, "wb") as f: f.write(str.encode(tablib_dataset.export(output_format))) if output_format in ["ods", "xlsx", "xls"]: with open(file_name, "wb") as f: f.write(tablib_dataset.export(output_format)) except Exception: QMessageBox.critical(self, programName, f"The file {file_name} can not be saved")
class ProfilesLoader(QDialog): def __init__(self, load_func, create_func, save_func, profiles, parent=None): super(ProfilesLoader, self).__init__(self, parent, Qt.Dialog) self.setWindowTitle(_translate("ProfilesLoader", "Profile Manager")) self.setMinimumWidth(400) self._profiles = profiles self.load_function = load_func self.create_function = create_func self.save_function = save_func self.ide = parent vbox = QVBoxLayout(self) vbox.addWidget(QLabel(_translate("ProfilesLoader", "Save your opened files and projects " "into a profile and change really" "quick between projects and" "files sessions.\n This allows you to " "save your working environment, " "keep working in another\n" "project and then go back " "exactly where you left."))) self.profileList = QListWidget() self.profileList.addItems([key for key in profiles]) self.profileList.setCurrentRow(0) self.contentList = QListWidget() self.btnDelete = QPushButton(_translate("ProfilesLoader", "Delete Profile")) self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnUpdate = QPushButton(_translate("ProfilesLoader", "Update Profile")) self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnCreate = QPushButton(_translate("ProfilesLoader", "Create New Profile")) self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen = QPushButton(_translate("ProfilesLoader", "Open Profile")) self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen.setDefault(True) hbox = QHBoxLayout() hbox.addWidget(self.btnDelete) hbox.addWidget(self.btnUpdate) hbox.addWidget(self.btnCreate) hbox.addWidget(self.btnOpen) vbox.addWidget(self.profileList) vbox.addWidget(self.contentList) vbox.addLayout(hbox) self.profileList.itemSelectionChanged.connect(self.load_profile_content) self.btnOpen.clicked['bool'].connect(self.open_profile) self.btnUpdate.clicked['bool'].connect(self.save_profile) self.btnCreate.clicked['bool'].connect(self.create_profile) self.btnDelete.clicked['bool'].connect(self.delete_profile) def load_profile_content(self): item = self.profileList.currentItem() self.contentList.clear() if item is not None: key = item.text() files = [_translate("ProfilesLoader", 'Files:')] + \ [file[0] for file in self._profiles[key][0]] projects = [_translate("ProfilesLoader", 'Projects:')] + self._profiles[key][1] content = files + projects self.contentList.addItems(content) def create_profile(self): profileName = self.create_function() self.ide.Profile = profileName self.close() def save_profile(self): if self.profileList.currentItem(): profileName = self.profileList.currentItem().text() self.save_function(profileName) self.ide.show_status_message(_translate("ProfilesLoader", "Profile %s Updated!") % profileName) self.load_profile_content() def open_profile(self): if self.profileList.currentItem(): key = self.profileList.currentItem().text() self.load_function(key) self.ide.Profile = key self.close() def delete_profile(self): if self.profileList.currentItem(): key = self.profileList.currentItem().text() self._profiles.pop(key) self.profileList.takeItem(self.profileList.currentRow()) self.contentList.clear()
class SubwindowMisc(QWidget): """Show subwindow with miscellaneous settings.""" def createWindow(self, mainWindow, tab=''): """Create subwindow with miscellaneous settings.""" try: parent = None super().__init__(parent) # self.setWindowFlags(Qt.WindowStaysOnTopHint) self.setWindowIcon( QIcon(scctool.settings.getResFile('settings.png'))) self.setWindowModality(Qt.ApplicationModal) self.mainWindow = mainWindow self.passEvent = False self.controller = mainWindow.controller self.__dataChanged = False self.createButtonGroup() self.createTabs(tab) mainLayout = QVBoxLayout() mainLayout.addWidget(self.tabs) mainLayout.addLayout(self.buttonGroup) self.setLayout(mainLayout) self.resize( QSize(mainWindow.size().width() * .80, self.sizeHint().height())) relativeChange = QPoint(mainWindow.size().width() / 2, mainWindow.size().height() / 3)\ - QPoint(self.size().width() / 2, self.size().height() / 3) self.move(mainWindow.pos() + relativeChange) self.setWindowTitle(_("Miscellaneous Settings")) except Exception as e: module_logger.exception("message") def createTabs(self, tab=''): """Create tabs.""" self.tabs = QTabWidget() self.createMapsBox() self.createFavBox() self.createAliasBox() self.createOcrBox() self.createAlphaBox() # Add tabs self.tabs.addTab(self.mapsBox, _("Map Manager")) self.tabs.addTab(self.favBox, _("Favorites")) self.tabs.addTab(self.aliasBox, _("Alias")) self.tabs.addTab(self.ocrBox, _("OCR")) self.tabs.addTab(self.alphaBox, _("AlphaTL && Ingame Score")) table = dict() table['mapmanager'] = 0 table['favorites'] = 1 table['alias'] = 2 table['ocr'] = 3 table['alphatl'] = 4 self.tabs.setCurrentIndex(table.get(tab, -1)) def changed(self): """Handle changes.""" self.__dataChanged = True def createAlphaBox(self): """Create Alpha QWidget.""" self.alphaBox = QWidget() mainLayout = QVBoxLayout() box = QGroupBox(_("AlphaTL")) layout = QHBoxLayout() self.cb_trans_banner = QCheckBox( " " + _("Download transparent Banner of the Match")) self.cb_trans_banner.setChecked( scctool.settings.config.parser.getboolean( "SCT", "transparent_match_banner")) self.cb_trans_banner.stateChanged.connect(self.changed) layout.addWidget(self.cb_trans_banner) box.setLayout(layout) mainLayout.addWidget(box) box = QGroupBox(_("Set Ingame Score Task")) layout = QVBoxLayout() self.cb_ctrlx = QCheckBox(" " + _('Automatically press Ctrl+X to apply the' ' correct player order ingame')) self.cb_ctrlx.setToolTip( _("This will ensure that the player of the first team is always" " on the left/top in the ingame Observer UI.")) self.cb_ctrlx.setChecked( scctool.settings.config.parser.getboolean("SCT", "CtrlX")) self.cb_ctrlx.stateChanged.connect(self.changed) layout.addWidget(self.cb_ctrlx) self.cb_ctrln = QCheckBox(" " + _('Automatically press Ctrl+N before' ' OCR to display player names')) self.cb_ctrln.setToolTip( _("This is recommended for Standard and Gawliq Observer UI.")) self.cb_ctrln.setChecked( scctool.settings.config.parser.getboolean("SCT", "CtrlN")) self.cb_ctrln.stateChanged.connect(self.changed) layout.addWidget(self.cb_ctrln) self.cb_ctrlshifts = QCheckBox( " " + _('Automatically press Ctrl+Shift+S to display' ' the ingame score')) self.cb_ctrlshifts.setToolTip( _("Ctrl+Shift+S is needed for the WCS-Gameheart Oberserver" " Overlay, but disables the sound for other overlays.")) self.cb_ctrlshifts.setChecked( scctool.settings.config.parser.getboolean("SCT", "CtrlShiftS")) self.cb_ctrlshifts.stateChanged.connect(self.changed) layout.addWidget(self.cb_ctrlshifts) self.cb_ctrlshiftc = QCheckBox( " " + _('Automatically press Ctrl+Shift+C to toogle the clan tag')) self.cb_ctrlshiftc.setChecked( scctool.settings.config.parser.getboolean("SCT", "CtrlShiftC")) self.cb_ctrlshiftc.stateChanged.connect(self.changed) layout.addWidget(self.cb_ctrlshiftc) container = QHBoxLayout() self.cb_ctrlshiftr = QComboBox() self.cb_ctrlshiftr.addItem("0") self.cb_ctrlshiftr.addItem("1") self.cb_ctrlshiftr.addItem("2") try: self.cb_ctrlshiftr.setCurrentIndex( scctool.settings.config.parser.getint("SCT", "CtrlShiftR")) except Exception: self.cb_ctrlshiftr.setCurrentIndex(0) self.cb_ctrlshiftr.setMaximumWidth(40) self.cb_ctrlshiftr.currentIndexChanged.connect(self.changed) container.addWidget( QLabel( _('Automatically press Ctrl+Shift+R to toogle the race icon ')) ) container.addWidget(self.cb_ctrlshiftr) container.addWidget(QLabel(_(' time(s)'))) layout.addLayout(container) self.cb_blacklist = QCheckBox(" " + _('Activate Blacklist for' ' Ingame Score')) self.cb_blacklist.setChecked( scctool.settings.config.parser.getboolean("SCT", "blacklist_on")) self.cb_blacklist.stateChanged.connect(self.changed) layout.addWidget(self.cb_blacklist) box.setLayout(layout) mainLayout.addWidget(box) box = QGroupBox(_("Blacklist for Ingame Score")) layout = QVBoxLayout() blacklistDesc = _("Enter your SC2 client usernames to deactivate" " automatically setting the ingame score and" " toogling the production tab when you are playing" " yourself. Replays are exempt.") label = QLabel(blacklistDesc) label.setAlignment(Qt.AlignJustify) label.setWordWrap(True) layout.addWidget(label) self.list_blacklist = ListTable(4, scctool.settings.config.getBlacklist()) self.list_blacklist.dataModified.connect(self.changed) self.list_blacklist.setFixedHeight(50) layout.addWidget(self.list_blacklist) box.setLayout(layout) mainLayout.addWidget(box) mainLayout.addItem( QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)) self.alphaBox.setLayout(mainLayout) def createFavBox(self): """Create favorites box.""" self.favBox = QWidget() mainLayout = QVBoxLayout() box = QGroupBox(_("Players")) layout = QHBoxLayout() self.list_favPlayers = ListTable( 4, scctool.settings.config.getMyPlayers()) self.list_favPlayers.dataModified.connect(self.changed) self.list_favPlayers.setFixedHeight(150) layout.addWidget(self.list_favPlayers) box.setLayout(layout) mainLayout.addWidget(box) box = QGroupBox(_("Teams")) layout = QVBoxLayout() self.list_favTeams = ListTable(3, scctool.settings.config.getMyTeams()) self.list_favTeams.dataModified.connect(self.changed) self.list_favTeams.setFixedHeight(100) layout.addWidget(self.list_favTeams) self.cb_swapTeams = QCheckBox( _('Swap my favorite team always to the left')) self.cb_swapTeams.setChecked( scctool.settings.config.parser.getboolean("SCT", "swap_myteam")) self.cb_swapTeams.stateChanged.connect(self.changed) layout.addWidget(self.cb_swapTeams) box.setLayout(layout) mainLayout.addWidget(box) mainLayout.addItem( QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)) self.favBox.setLayout(mainLayout) def createAliasBox(self): """Create favorites box.""" self.aliasBox = QWidget() mainLayout = QGridLayout() aliasDesc = _( 'Player and team aliases are replaced by the actual name when' + ' encountered by the match grabber. Additionally, SC2 player' + ' names listed as aliases are replaced in the intros' + ' and used to identify players by the automatic' + ' background tasks "Auto Score Update" and "Set Ingame Score".') label = QLabel(aliasDesc) label.setAlignment(Qt.AlignJustify) label.setWordWrap(True) mainLayout.addWidget(label, 1, 0, 1, 2) box = QGroupBox(_("Player Aliases")) layout = QVBoxLayout() self.list_aliasPlayers = AliasTreeView(self) self.list_aliasPlayers.aliasRemoved.connect( self.controller.aliasManager.removePlayerAlias) layout.addWidget(self.list_aliasPlayers) addButton = QPushButton(_("Add Alias")) addButton.clicked.connect( lambda: self.addAlias(self.list_aliasPlayers, _('Player Name'))) layout.addWidget(addButton) box.setLayout(layout) mainLayout.addWidget(box, 0, 0) box = QGroupBox(_("Team Aliases")) layout = QVBoxLayout() self.list_aliasTeams = AliasTreeView(self) self.list_aliasTeams.aliasRemoved.connect( self.controller.aliasManager.removeTeamAlias) layout.addWidget(self.list_aliasTeams) addButton = QPushButton(_("Add Alias")) addButton.clicked.connect( lambda: self.addAlias(self.list_aliasTeams, _('Team Name'))) layout.addWidget(addButton) box.setLayout(layout) mainLayout.addWidget(box, 0, 1) list = self.controller.aliasManager.playerAliasList() for player, aliases in list.items(): self.list_aliasPlayers.insertAliasList(player, aliases) list = self.controller.aliasManager.teamAliasList() for team, aliases in list.items(): self.list_aliasTeams.insertAliasList(team, aliases) self.aliasBox.setLayout(mainLayout) def addAlias(self, widget, scope, name=""): name, ok = QInputDialog.getText(self, scope, scope + ':', text=name) if not ok: return name = name.strip() alias, ok = QInputDialog.getText(self, _('Alias'), _('Alias of {}').format(name) + ':', text="") alias = alias.strip() if not ok: return try: if widget == self.list_aliasPlayers: self.controller.aliasManager.addPlayerAlias(name, alias) elif widget == self.list_aliasTeams: self.controller.aliasManager.addTeamAlias(name, alias) widget.insertAlias(name, alias, True) except Exception as e: module_logger.exception("message") QMessageBox.critical(self, _("Error"), str(e)) def createOcrBox(self): """Create forms for OCR.""" self.ocrBox = QWidget() mainLayout = QVBoxLayout() box = QGroupBox( _("Optical Character Recognition for" " Automatic Setting of Ingame Score")) layout = QGridLayout() self.cb_useocr = QCheckBox(" " + _("Activate Optical Character Recognition")) self.cb_useocr.setChecked( scctool.settings.config.parser.getboolean("SCT", "use_ocr")) self.cb_useocr.stateChanged.connect(self.changed) self.tesseract = MonitoredLineEdit() self.tesseract.setText( scctool.settings.config.parser.get("SCT", "tesseract")) self.tesseract.textModified.connect(self.changed) # self.tesseract.setAlignment(Qt.AlignCenter) self.tesseract.setPlaceholderText( "C:\\Program Files (x86)\\Tesseract-OCR\\tesseract") self.tesseract.setReadOnly(True) self.tesseract.setToolTip(_('Tesseract-OCR Executable')) self.browse = QPushButton(_("Browse...")) self.browse.clicked.connect(self.selectTesseract) text = _( "Sometimes the order of players given by the SC2-Client-API" " differs from the order in the Observer-UI resulting in a" " swapped match score. To correct this via Optical Character" " Recognition you have to download {} and install and select the" " exectuable below, if it is not detected automatically.") url = 'https://github.com/UB-Mannheim/tesseract' + \ '/wiki#tesseract-at-ub-mannheim' href = "<a href='{}'>" + "Tesseract-OCR" + "</a>" href = href.format(url) label = QLabel(text.format(href)) label.setAlignment(Qt.AlignJustify) label.setOpenExternalLinks(True) label.setWordWrap(True) label.setMargin(5) layout.addWidget(label, 1, 0, 1, 2) layout.addWidget(self.cb_useocr, 0, 0, 1, 2) layout.addWidget(QLabel(_("Tesseract-OCR Executable") + ":"), 2, 0) layout.addWidget(self.tesseract, 3, 0) layout.addWidget(self.browse, 3, 1) box.setLayout(layout) mainLayout.addWidget(box) mainLayout.addItem( QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding)) self.ocrBox.setLayout(mainLayout) if (not scctool.settings.windows): self.cb_useocr.setEnabled(False) self.cb_useocr.setAttribute(Qt.WA_AlwaysShowToolTips) self.cb_useocr.setToolTip( _("This feature is only available in Windows.")) self.tesseract.setEnabled(False) self.tesseract.setAttribute(Qt.WA_AlwaysShowToolTips) self.tesseract.setToolTip( _("This feature is only available in Windows.")) self.browse.setEnabled(False) self.browse.setAttribute(Qt.WA_AlwaysShowToolTips) self.browse.setToolTip( _("This feature is only available in Windows.")) def selectTesseract(self): """Create forms for tesseract.""" old_exe = self.tesseract.text() default = scctool.settings.config.findTesserAct(old_exe) exe, ok = QFileDialog.getOpenFileName( self, _("Select Tesseract-OCR Executable"), default, _("Tesseract-OCR Executable") + " (tesseract.exe);; " + _("Executable") + " (*.exe);; " + _("All files") + " (*)") if (ok and exe != old_exe): self.tesseract.setText(exe) self.changed() def createMapsBox(self): """Create box for map manager.""" self.mapsize = 300 self.mapsBox = QWidget() layout = QGridLayout() self.maplist = QListWidget() self.maplist.setSortingEnabled(True) for map in scctool.settings.maps: self.maplist.addItem(QListWidgetItem(map)) self.maplist.setCurrentItem(self.maplist.item(0)) self.maplist.currentItemChanged.connect(self.changePreview) # self.maplist.setFixedHeight(self.mapsize) self.maplist.setMinimumWidth(150) layout.addWidget(self.maplist, 0, 1, 2, 1) self.mapPreview = QLabel() self.mapPreview.setFixedWidth(self.mapsize) self.mapPreview.setFixedHeight(self.mapsize) self.mapPreview.setAlignment(Qt.AlignCenter) layout.addWidget(self.mapPreview, 0, 0) self.mapInfo = QLabel() self.mapInfo.setIndent(10) layout.addWidget(self.mapInfo, 1, 0) self.pb_addMapLiquipedia = QPushButton(_("Add from Liquipedia")) self.pb_addMapLiquipedia.clicked.connect(self.addFromLquipedia) self.pb_addMap = QPushButton(_("Add from File")) self.pb_addMap.clicked.connect(self.addMap) self.pb_renameMap = QPushButton(_("Rename")) self.pb_renameMap.clicked.connect(self.renameMap) self.pb_changeMap = QPushButton(_("Change Image")) self.pb_changeMap.clicked.connect(self.changeMap) self.pb_removeMap = QPushButton(_("Remove")) self.pb_removeMap.clicked.connect(self.deleteMap) self.sc_removeMap = QShortcut(QKeySequence("Del"), self) self.sc_removeMap.setAutoRepeat(False) self.sc_removeMap.activated.connect(self.deleteMap) box = QWidget() container = QHBoxLayout() container.addWidget(self.pb_addMapLiquipedia, 0) container.addWidget(self.pb_addMap, 0) container.addWidget(QLabel(), 4) container.addWidget(self.pb_renameMap, 0) container.addWidget(self.pb_changeMap, 0) container.addWidget(self.pb_removeMap, 0) box.setLayout(container) layout.addWidget(box, 2, 0, 1, 2) layout.addItem( QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding), 3, 0, 1, 2) self.changePreview() self.mapsBox.setLayout(layout) def renameMap(self): """Rename maps.""" item = self.maplist.currentItem() map = item.text() text, ok = QInputDialog.getText(self, _('Map Name'), _('Map Name') + ':', text=map) if not ok: return text = text.strip() if (text == map): return if text.lower() == 'tbd': QMessageBox.critical( self, _("Error"), _('"{}" is not a valid map name.').format(text)) return if (text in scctool.settings.maps): buttonReply = QMessageBox.warning( self, _("Duplicate Entry"), _("Map is already in list! Overwrite?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.No: return self.controller.addMap(self.controller.getMapImg(map, True), text) self.controller.deleteMap(map) item.setText(text) def changeMap(self): """Change a map.""" map = self.maplist.currentItem().text() fileName, ok = QFileDialog.getOpenFileName( self, _("Select Map Image (> 500x500px recommended)"), "", _("Supported Images") + " (*.png *.jpg)") if ok: base = os.path.basename(fileName) name, ext = os.path.splitext(base) name = name.replace("_", " ") self.controller.deleteMap(map) self.controller.addMap(fileName, map) self.changePreview() def addMap(self): """Add a map.""" fileName, ok = QFileDialog.getOpenFileName( self, _("Select Map Image (> 500x500px recommended)"), "", _("Supported Images") + " (*.png *.jpg)") if ok: base = os.path.basename(fileName) name, ext = os.path.splitext(base) name = name.replace("_", " ") map_name, ok = QInputDialog.getText(self, _('Map Name'), _('Map Name') + ':', text=name) map_name = map_name.strip() if ok: if map_name.lower() == 'tbd': QMessageBox.critical( self, _("Error"), _('"{}" is not a valid map name.').format(map_name)) return if (map_name in scctool.settings.maps): buttonReply = QMessageBox.warning( self, _("Duplicate Entry"), _("Map is already in list! Overwrite?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.No: return else: self.controller.deleteMap(map_name) self.controller.addMap(fileName, map_name) items = self.maplist.findItems(map_name, Qt.MatchExactly) if len(items) == 0: item = QListWidgetItem(map_name) self.maplist.addItem(item) self.maplist.setCurrentItem(item) else: self.maplist.setCurrentItem(items[0]) self.changePreview() def addFromLquipedia(self): grabber = LiquipediaGrabber() search_str = '' while True: search_str, ok = QInputDialog.getText(self, _('Map Name'), _('Map Name') + ':', text=search_str) search_str.strip() try: if ok and search_str: if search_str.lower() == 'tbd': QMessageBox.critical( self, _("Error"), _('"{}" is not a valid map name.').format( search_str)) continue try: map = grabber.get_map(search_str) except MapNotFound: QMessageBox.critical( self, _("Map not found"), _('"{}" was not found on Liquipedia.').format( search_str)) continue map_name = map.get_name() if (map_name in scctool.settings.maps): buttonReply = QMessageBox.warning( self, _("Duplicate Entry"), _("Map {} is already in list! Overwrite?".format( map_name)), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.No: break else: self.controller.deleteMap(map_name) images = grabber.get_images(map.get_map_images()) image = "" for size in sorted(images): if not image or size <= 2500 * 2500: image = images[size] url = grabber._base_url + image downloader = MapDownloader(self, map_name, url) downloader.download() if map_name not in scctool.settings.maps: scctool.settings.maps.append(map_name) items = self.maplist.findItems(map_name, Qt.MatchExactly) if len(items) == 0: item = QListWidgetItem(map_name) self.maplist.addItem(item) self.maplist.setCurrentItem(item) else: self.maplist.setCurrentItem(items[0]) self.changePreview() except Exception as e: module_logger.exception("message") QMessageBox.critical(self, _("Error"), str(e)) finally: break def deleteMap(self): """Delete a map.""" item = self.maplist.currentItem() map = item.text() buttonReply = QMessageBox.question( self, _('Delete map?'), _("Delete '{}' permanently?").format(map), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: self.controller.deleteMap(map) self.maplist.takeItem(self.maplist.currentRow()) def changePreview(self): """Change the map preview.""" if self.maplist.count() < 1: return map = self.maplist.currentItem().text() if (map == "TBD"): self.pb_renameMap.setEnabled(False) self.pb_removeMap.setEnabled(False) self.sc_removeMap.setEnabled(False) else: self.pb_removeMap.setEnabled(True) self.pb_renameMap.setEnabled(True) self.sc_removeMap.setEnabled(True) file = self.controller.getMapImg(map, True) map = QPixmap(file) width = map.height() height = map.width() ext = os.path.splitext(file)[1].replace(".", "").upper() size = humanize.naturalsize(os.path.getsize(file)) map = QPixmap(file).scaled(self.mapsize, self.mapsize, Qt.KeepAspectRatio) self.mapPreview.setPixmap(map) text = "{}x{}px, {}, {}".format(width, height, str(size), ext) self.mapInfo.setText(text) def createButtonGroup(self): """Create buttons.""" try: layout = QHBoxLayout() layout.addWidget(QLabel("")) buttonCancel = QPushButton(_('Cancel')) buttonCancel.clicked.connect(self.closeWindow) layout.addWidget(buttonCancel) buttonSave = QPushButton(_('&Save && Close')) buttonSave.setToolTip(_("Shortcut: {}").format("Ctrl+S")) self.shortcut = QShortcut(QKeySequence("Ctrl+S"), self) self.shortcut.setAutoRepeat(False) self.shortcut.activated.connect(self.saveCloseWindow) buttonSave.clicked.connect(self.saveCloseWindow) layout.addWidget(buttonSave) self.buttonGroup = layout except Exception as e: module_logger.exception("message") def saveData(self): """Save the data.""" if (self.__dataChanged): scctool.settings.config.parser.set( "SCT", "myteams", ", ".join(self.list_favTeams.getData())) scctool.settings.config.parser.set( "SCT", "commonplayers", ", ".join(self.list_favPlayers.getData())) scctool.settings.config.parser.set("SCT", "tesseract", self.tesseract.text().strip()) scctool.settings.config.parser.set("SCT", "use_ocr", str(self.cb_useocr.isChecked())) scctool.settings.config.parser.set( "SCT", "transparent_match_banner", str(self.cb_trans_banner.isChecked())) scctool.settings.config.parser.set( "SCT", "CtrlShiftS", str(self.cb_ctrlshifts.isChecked())) scctool.settings.config.parser.set( "SCT", "CtrlShiftC", str(self.cb_ctrlshiftc.isChecked())) scctool.settings.config.parser.set( "SCT", "swap_myteam", str(self.cb_swapTeams.isChecked())) scctool.settings.config.parser.set("SCT", "CtrlN", str(self.cb_ctrln.isChecked())) scctool.settings.config.parser.set("SCT", "CtrlX", str(self.cb_ctrlx.isChecked())) scctool.settings.config.parser.set( "SCT", "CtrlShiftR", str(self.cb_ctrlshiftr.currentText())) scctool.settings.config.parser.set( "SCT", "blacklist_on", str(self.cb_blacklist.isChecked())) scctool.settings.config.parser.set( "SCT", "blacklist", ", ".join(self.list_blacklist.getData())) self.__dataChanged = False def saveCloseWindow(self): """Save and close window.""" self.saveData() self.passEvent = True self.close() def closeWindow(self): """Close window.""" self.passEvent = True self.close() def closeEvent(self, event): """Handle close event.""" try: self.mainWindow.updateMapCompleters() if (not self.__dataChanged): event.accept() return if (not self.passEvent): if (self.isMinimized()): self.showNormal() buttonReply = QMessageBox.question( self, _('Save data?'), _("Save data?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: self.saveData() event.accept() except Exception as e: module_logger.exception("message")
class EditorGeneral(QWidget): """EditorGeneral widget class.""" def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme, self._modified_editors = 'default', [] self._font = settings.FONT groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) formMini.setContentsMargins(5, 15, 5, 5) self._checkShowMinimap = QCheckBox( translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP) self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setRange(0, 100) self._spinMaxOpacity.setSuffix("% Max.") self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setRange(0, 100) self._spinMinOpacity.setSuffix("% Min.") self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) self._spinSize.setSuffix( translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_SIZE_MINIMAP), 1, 0, Qt.AlignRight) formMini.addWidget(self._spinSize, 1, 1) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinMaxOpacity, 2, 2) #Typo gridTypo = QGridLayout(groupBoxTypo) gridTypo.setContentsMargins(5, 15, 5, 5) self._btnEditorFont = QPushButton('') gridTypo.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme vboxScheme = QVBoxLayout(groupBoxScheme) vboxScheme.setContentsMargins(5, 15, 5, 5) self._listScheme = QListWidget() vboxScheme.addWidget(self._listScheme) hbox = QHBoxLayout() btnDownload = QPushButton( translations.TR_PREFERENCES_EDITOR_DOWNLOAD_SCHEME) btnDownload.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnDownload.clicked['bool'].connect(self._open_schemes_manager) hbox.addWidget(btnDownload) btnAdd = QPushButton(QIcon(":img/add"), translations.TR_EDITOR_CREATE_SCHEME) btnAdd.setIconSize(QSize(16, 16)) btnAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnAdd.clicked['bool'].connect(self._open_schemes_designer) btnRemove = QPushButton(QIcon(":img/delete"), translations.TR_EDITOR_REMOVE_SCHEME) btnRemove.setIconSize(QSize(16, 16)) btnRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) btnRemove.clicked['bool'].connect(self._remove_scheme) hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(btnAdd) hbox.addWidget(btnRemove) vboxScheme.addLayout(hbox) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) if settings.IS_MAC_OS: self._spinMinOpacity.setValue(100) self._spinMaxOpacity.setValue(100) self._spinMinOpacity.setDisabled(True) self._spinMaxOpacity.setDisabled(True) else: self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) btnText = ', '.join(self._font.toString().split(',')[0:2]) self._btnEditorFont.setText(btnText) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self._btnEditorFont.clicked['bool'].connect(self._load_editor_font) self._listScheme.itemSelectionChanged.connect(self._preview_style) self._preferences.savePreferences.connect(self.save) def _open_schemes_manager(self): ninjaide = IDE.getInstance() ninjaide.show_schemes() # refresh schemes def _open_schemes_designer(self): name = self._listScheme.currentItem().text() scheme = self._schemes.get(name, resources.COLOR_SCHEME) designer = preferences_editor_scheme_designer.EditorSchemeDesigner( scheme, self) designer.exec_() if designer.saved: scheme_name = designer.line_name.text() scheme = designer.original_style self._schemes[scheme_name] = scheme result = self._listScheme.findItems(scheme_name, Qt.MatchExactly) if not result: self._listScheme.addItem(scheme_name) def _remove_scheme(self): name = self._listScheme.currentItem().text() fileName = ('{0}.color'.format( file_manager.create_path(resources.EDITOR_SKINS, name))) file_manager.delete_file(fileName) item = self._listScheme.takeItem(self._listScheme.currentRow()) del item def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style for editorWidget in self._modified_editors: try: editorWidget.restyle(editorWidget.lang) except RuntimeError: print('the editor has been removed') def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') if not main_container: return editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get( scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) self._modified_editors.append(editorWidget) self.current_scheme = scheme def _load_editor_font(self): try: font, ok = QFontDialog.getFont(self._font, self) if ok: self._font = font btnText = ', '.join(self._font.toString().split(',')[0:2]) self._btnEditorFont.setText(btnText) except: QMessageBox.warning( self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def save(self): qsettings = IDE.ninja_settings() settings.FONT = self._font qsettings.setValue('preferences/editor/font', settings.FONT) settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) scheme = self._listScheme.currentItem().text() resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME) qsettings.setValue('preferences/editor/scheme', scheme)
class GlyphSetTab(QWidget): def __init__(self, parent=None): super().__init__(parent) self.name = self.tr("Glyph sets") self.defaultGlyphSetBox = QCheckBox( self.tr("Default glyph set:"), self) self.defaultGlyphSetDrop = QComboBox(self) self.defaultGlyphSetBox.toggled.connect(self.toggleGlyphSetDrop) self.glyphSetList = QListWidget(self) self.glyphSetList.setSortingEnabled(True) self.glyphSetContents = QPlainTextEdit(self) self.glyphSetList.currentItemChanged.connect( self.updateGlyphSetContents) self.glyphSetList.itemChanged.connect(self.renameGlyphSet) self._cachedName = None splitter = QSplitter(self) splitter.addWidget(self.glyphSetList) splitter.addWidget(self.glyphSetContents) self.addGlyphSetButton = QPushButton(self) self.addGlyphSetButton.setIcon(icons.i_plus()) self.addGlyphSetButton.clicked.connect(lambda: self.addGlyphSet()) self.removeGlyphSetButton = QPushButton(self) self.removeGlyphSetButton.setIcon(icons.i_minus()) self.removeGlyphSetButton.clicked.connect(self.removeGlyphSet) self.importButton = QPushButton(self.tr("Import"), self) importMenu = QMenu(self) importMenu.addAction( self.tr("Import from Current Font"), self.importFromCurrentFont) self.importButton.setMenu(importMenu) self.glyphListBox = QCheckBox(self.tr("Glyph list path:"), self) self.glyphListEdit = QLineEdit(self) self.glyphListEdit.setReadOnly(True) self.glyphListButton = QPushButton(self.tr("Browse…"), self) self.glyphListButton.clicked.connect(self.getGlyphList) self.glyphListBox.toggled.connect(self.glyphListEdit.setEnabled) self.glyphListBox.toggled.connect(self.glyphListButton.setEnabled) buttonsLayout = QHBoxLayout() buttonsLayout.addWidget(self.addGlyphSetButton) buttonsLayout.addWidget(self.removeGlyphSetButton) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) buttonsLayout.addWidget(spacer) buttonsLayout.addWidget(self.importButton) firstLayout = QGridLayout() line = 0 firstLayout.addWidget(self.defaultGlyphSetBox, line, 0, 1, 2) firstLayout.addWidget(self.defaultGlyphSetDrop, line, 3, 1, 3) line += 1 firstLayout.addWidget(splitter, line, 0, 1, 6) line += 1 firstLayout.addLayout(buttonsLayout, line, 0, 1, 3) secondLayout = QHBoxLayout() secondLayout.addWidget(self.glyphListBox) secondLayout.addWidget(self.glyphListEdit) secondLayout.addWidget(self.glyphListButton) mainLayout = QVBoxLayout(self) mainLayout.addLayout(firstLayout) mainLayout.addLayout(secondLayout) self.setLayout(mainLayout) self.readSettings() def addGlyphSet(self, glyphNames=[], glyphSetName=None): if glyphSetName is None: glyphSetName = self.tr("New glyph set") if glyphSetName in self.glyphSets: index = 1 while "%s %d" % (glyphSetName, index) in self.glyphSets: index += 1 glyphSetName = "%s %d" % (glyphSetName, index) self.glyphSets[glyphSetName] = glyphNames item = QListWidgetItem(glyphSetName, self.glyphSetList) item.setFlags(item.flags() | Qt.ItemIsEditable) self.glyphSetList.setCurrentItem(item) self.glyphSetList.editItem(item) self.removeGlyphSetButton.setEnabled(True) def removeGlyphSet(self): i = self.glyphSetList.currentRow() text = self.glyphSetList.takeItem(i).text() del self.glyphSets[text] if self.glyphSetList.count() < 2: self.removeGlyphSetButton.setEnabled(False) def renameGlyphSet(self): newKey = self.glyphSetList.currentItem() if newKey is None: return newKey = newKey.text() self.glyphSets[newKey] = self.glyphSets[self._cachedName] del self.glyphSets[self._cachedName] def importFromCurrentFont(self): font = QApplication.instance().currentFont() name = "%s %s" % (font.info.familyName, font.info.styleName) self.addGlyphSet(font.glyphOrder, name) def toggleGlyphSetDrop(self): sender = self.sender() self.defaultGlyphSetDrop.setEnabled(sender.isChecked()) def updateGlyphSetContents(self, current, previous): # store content of the textEdit in the glyphSet dict if previous is not None: glyphNames = self.glyphSetContents.toPlainText().split() self.glyphSets[previous.text()] = glyphNames # now update the text edit to current glyphSet glyphSetName = current.text() text = " ".join(self.glyphSets[glyphSetName]) self.glyphSetContents.setPlainText(text) # cache current name for renames self._cachedName = glyphSetName def getGlyphList(self): fileFormats = ( self.tr("Text file {}").format("(*.txt)"), self.tr("All files {}").format("(*.*)"), ) path, _ = QFileDialog.getOpenFileName( self, self.tr("Open File"), '', ";;".join(fileFormats) ) if path: self.glyphListEdit.setText(path) def readSettings(self): defaultGlyphSet = settings.defaultGlyphSet() self.defaultGlyphSetBox.setChecked(len(defaultGlyphSet)) self.glyphSets = settings.readGlyphSets() self.defaultGlyphSetDrop.clear() self.defaultGlyphSetDrop.addItems(self.glyphSets.keys()) self.glyphSetList.clear() glyphSetNames = self.glyphSets.keys() # Normally we should be enforcing this rather decently in the interface # already if glyphSetNames: for glyphSetName in glyphSetNames: item = QListWidgetItem(glyphSetName, self.glyphSetList) item.setFlags(item.flags() | Qt.ItemIsEditable) self.glyphSetList.setCurrentRow(0) self.removeGlyphSetButton.setEnabled(len(self.glyphSets) > 1) glyphListPath = settings.glyphListPath() self.glyphListBox.setChecked(bool(glyphListPath)) self.glyphListEdit.setEnabled(bool(glyphListPath)) self.glyphListEdit.setText(glyphListPath) self.glyphListButton.setEnabled(bool(glyphListPath)) def writeSettings(self): # store content of the textEdit in the glyphSet dict glyphNames = self.glyphSetContents.toPlainText().split() currentGlyphSet = self.glyphSetList.currentItem().text() self.glyphSets[currentGlyphSet] = glyphNames settings.writeGlyphSets(self.glyphSets) if not self.defaultGlyphSetBox.isChecked(): settings.setDefaultGlyphSet(None) else: defaultGlyphSet = self.defaultGlyphSetDrop.currentText() settings.setDefaultGlyphSet(defaultGlyphSet) if not self.glyphListBox.isChecked(): settings.setGlyphListPath(None) else: glyphListPath = self.glyphListEdit.text() if glyphListPath: settings.setGlyphListPath(glyphListPath) QApplication.instance().loadGlyphList()
class NewProjectManager(QDialog): 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) 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(hbox2) self.template_registry = IDE.get_service("template_registry") categories = self.template_registry.list_project_categories() for category in categories: self.list_projects.addItem(category) cancel.clicked['bool'].connect(self.close) choose.clicked['bool'].connect(self._start_wizard) self.list_projects.itemSelectionChanged.connect(self._project_selected) self.list_templates.itemSelectionChanged.connect(self._template_selected) def _project_selected(self): self.list_templates.clear() item = self.list_projects.currentItem() category = item.text() for template in self.template_registry.list_templates_for_cateogory( category): item = QListWidgetItem(template.type_name) item.setData(Qt.UserRole, template) item = self.list_templates.addItem(item) def _template_selected(self): item = self.list_templates.currentItem() ptype = item.data(Qt.UserRole) self.text_info.setText(ptype.description) def _start_wizard(self): return QMessageBox.critical(self, "Beta Info", "Can not construct this segment!") item = self.list_templates.currentItem() if item is not None: ptype = item.data(Qt.UserRole)
class ListEdit(QWidget): """A widget to edit a list of items (e.g. a list of directories).""" # emitted when anything changed in the listbox. changed = pyqtSignal() def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) layout = QGridLayout(self) self.setLayout(layout) self.addButton = QPushButton(icons.get('list-add'), '') self.editButton = QPushButton(icons.get('document-edit'), '') self.removeButton = QPushButton(icons.get('list-remove'), '') self.listBox = QListWidget() layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(0) layout.addWidget(self.listBox, 0, 0, 8, 1) layout.addWidget(self.addButton, 0, 1) layout.addWidget(self.editButton, 1, 1) layout.addWidget(self.removeButton, 2, 1) self.changed.connect(self.updateSelection) self.listBox.itemSelectionChanged.connect(self.updateSelection) self.updateSelection() self.connectSlots() app.translateUI(self) def connectSlots(self): self.addButton.clicked.connect(self.addClicked) self.editButton.clicked.connect(self.editClicked) self.removeButton.clicked.connect(self.removeClicked) self.listBox.itemDoubleClicked.connect(self.itemDoubleClicked) self.listBox.model().layoutChanged.connect(self.changed) def translateUI(self): self.addButton.setText(_("&Add...")) self.editButton.setText(_("&Edit...")) self.removeButton.setText(_("&Remove")) def addClicked(self, button): item = self.createItem() if self.openEditor(item): self.addItem(item) def editClicked(self, button): item = self.listBox.currentItem() item and self.editItem(item) def removeClicked(self, button): item = self.listBox.currentItem() if item: self.removeItem(item) def updateSelection(self): selected = bool(self.listBox.currentItem()) self.editButton.setEnabled(selected) self.removeButton.setEnabled(selected) def itemDoubleClicked(self, item): item and self.editItem(item) def createItem(self): return QListWidgetItem() def addItem(self, item): self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def removeItem(self, item): self.listBox.takeItem(self.listBox.row(item)) self.changed.emit() def editItem(self, item): if self.openEditor(item): self.itemChanged(item) self.changed.emit() def setCurrentItem(self, item): self.listBox.setCurrentItem(item) def setCurrentRow(self, row): self.listBox.setCurrentRow(row) def openEditor(self, item): """Opens an editor (dialog) for the item. Returns True if the dialog was accepted and the item edited. Returns False if the dialog was cancelled (the item must be left unedited). """ pass def itemChanged(self, item): """Called after an item has been added or edited. Re-implement to do something at this moment if needed, e.g. alter the text or display of other items. """ pass def setValue(self, strings): """Sets the listbox to a list of strings.""" self.listBox.clear() self.listBox.addItems(strings) self.changed.emit() def value(self): """Returns the list of paths in the listbox.""" return [self.listBox.item(i).text() for i in range(self.listBox.count())] def setItems(self, items): """Sets the listbox to a list of items.""" self.listBox.clear() for item in items: self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def items(self): """Returns the list of items in the listbox.""" return [self.listBox.item(i) for i in range(self.listBox.count())] def clear(self): """Clears the listbox.""" self.listBox.clear() self.changed.emit()
class SessionsManager(QDialog): """Session Manager, to load different configurations of ninja.""" def __init__(self, parent=None): super(SessionsManager, self).__init__(parent, Qt.Dialog) self._ide = parent self.setWindowTitle(translations.TR_SESSIONS_TITLE) self.setMinimumWidth(400) vbox = QVBoxLayout(self) vbox.addWidget(QLabel(translations.TR_SESSIONS_DIALOG_BODY)) self.sessionList = QListWidget() self.sessionList.addItems([key for key in settings.SESSIONS]) self.sessionList.setCurrentRow(0) self.contentList = QListWidget() self.btnDelete = QPushButton(translations.TR_SESSIONS_BTN_DELETE) self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnUpdate = QPushButton(translations.TR_SESSIONS_BTN_UPDATE) self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnCreate = QPushButton(translations.TR_SESSIONS_BTN_CREATE) self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen = QPushButton(translations.TR_SESSIONS_BTN_ACTIVATE) self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen.setDefault(True) hbox = QHBoxLayout() hbox.addWidget(self.btnDelete) hbox.addWidget(self.btnUpdate) hbox.addWidget(self.btnCreate) hbox.addWidget(self.btnOpen) vbox.addWidget(self.sessionList) vbox.addWidget(self.contentList) vbox.addLayout(hbox) self.sessionList.itemSelectionChanged.connect(self.load_session_content) self.btnOpen.clicked['bool'].connect(self.open_session) self.btnUpdate.clicked['bool'].connect(self.save_session) self.btnCreate.clicked['bool'].connect(self.create_session) self.btnDelete.clicked['bool'].connect(self.delete_session) self.load_session_content() def load_session_content(self): """Load the selected session, replacing the current session.""" item = self.sessionList.currentItem() self.contentList.clear() if item is not None: key = item.text() files = [translations.TR_FILES] + \ [file[0] for file in settings.SESSIONS[key][0]] projects = [translations.TR_PROJECT] + settings.SESSIONS[key][1] content = files + projects self.contentList.addItems(content) def create_session(self): """Create a new Session.""" sessionInfo = QInputDialog.getText(None, translations.TR_SESSIONS_CREATE_TITLE, translations.TR_SESSIONS_CREATE_BODY) if sessionInfo[1]: sessionName = sessionInfo[0] if not sessionName or sessionName in settings.SESSIONS: QMessageBox.information(self, translations.TR_SESSIONS_MESSAGE_TITLE, translations.TR_SESSIONS_MESSAGE_BODY) return SessionsManager.save_session_data(sessionName, self._ide) self._ide.Session = sessionName self.close() @classmethod def save_session_data(cls, sessionName, ide): """Save the updates from a session.""" openedFiles = ide.filesystem.get_files() files_info = [] for path in openedFiles: editable = ide.get_or_create_editable(path) if editable.is_dirty: stat_value = 0 else: stat_value = os.stat(path).st_mtime files_info.append([path, editable.editor.getCursorPosition(), stat_value]) projects_obj = ide.filesystem.get_projects() projects = [projects_obj[proj].path for proj in projects_obj] settings.SESSIONS[sessionName] = [files_info, projects] qsettings = ide.data_settings() qsettings.setValue('ide/sessions', settings.SESSIONS) def save_session(self): """Save current session""" if self.sessionList.currentItem(): sessionName = self.sessionList.currentItem().text() SessionsManager.save_session_data(sessionName, self._ide) self._ide.show_message(translations.TR_SESSIONS_UPDATED_NOTIF % {'session': sessionName}, 2000) self.load_session_content() def open_session(self): """Open a saved session""" if self.sessionList.currentItem(): key = self.sessionList.currentItem().text() self._load_session_data(key) self._ide.Session = key self.close() def delete_session(self): """Delete a session""" if self.sessionList.currentItem(): key = self.sessionList.currentItem().text() settings.SESSIONS.pop(key) self.sessionList.takeItem(self.sessionList.currentRow()) self.contentList.clear() qsettings = self._ide.data_settings() qsettings.setValue('ide/sessions', settings.SESSIONS) def _load_session_data(self, key): """Activate the selected session, closing the current files/projects""" main_container = self._ide.get_service('main_container') projects_explorer = self._ide.get_service('projects_explorer') if projects_explorer and main_container: projects_explorer.close_opened_projects() for fileData in settings.SESSIONS[key][0]: path, line, stat_value = fileData if file_manager.file_exists(path): mtime = os.stat(path).st_mtime ignore_checkers = (mtime == stat_value) main_container.open_file(path, line, ignore_checkers=ignore_checkers) if projects_explorer: projects_explorer.load_session_projects( settings.SESSIONS[key][1])
class ListEntry(BaseParamWidget): def __init__(self, layout_dir: str, title: str, initial_value: List[List[str]], new_id_func: Callable): super().__init__(layout_dir) self.choices = [] self.text_list = [] lab_title = QLabel(text=title) layout = QHBoxLayout() self.central_layout.addWidget(lab_title) self.on_check_callback = None self.list_widget = QListWidget() self.set_value(initial_value) layout_tools = QVBoxLayout() self.button_add_item = QPushButton('+') self.button_delete_item = QPushButton('-') self.button_delete_item.clicked.connect(self.delete_row) self.button_add_item.clicked.connect(self.add_row) self.button_add_item.setMaximumWidth(20) self.button_delete_item.setMaximumWidth(20) layout_tools.addWidget(self.button_add_item) layout_tools.addWidget(self.button_delete_item) layout.addLayout(layout_tools) layout.addWidget(self.list_widget) self.central_layout.addLayout(layout) self.data = initial_value self.new_id_func = new_id_func def new_id(self): if callable(self.new_id_func): return self.new_id_func() else: return None def add_row(self): self.data[0].append(self.new_id()) self.data[1].append('Unnamed') self.set_value(self.data) def delete_row(self): # item = self.list_widget.currentItem() index = self.list_widget.currentIndex().row() self.data[0].pop(index) self.data[1].pop(index) self.set_value(self.data) def on_listwidget_double_cicked(self): print('edit') item = self.list_widget.currentItem() self.list_widget.editItem(item) def get_value(self): text = [] for i in range(self.list_widget.count()): text.append(self.list_widget.item(i).text()) self.data[1] = text return self.data def set_value(self, data: List[List[str]]): self.list_widget.clear() self.list_widget.addItems(data[1]) self.data = data for index in range(self.list_widget.count()): item = self.list_widget.item(index) item.setFlags(item.flags() | Qt.ItemIsEditable)
class MainWindow(QMainWindow): def __init__(self, *args): QMainWindow.__init__(self) self.current_image = None self.createComponents() self.loadFromBufferMemory() #print("Input file type", type(input_file)) self.createMenu() self.createLayout() self.createConnects() self.setWindowTitle('Micrograph Selection Tool') def createComponents(self): self.buttonLoad = QPushButton('Load') self.buttonSave = QPushButton('Save') self.buttonKeep = QPushButton('Keep (Right arrow key)') self.buttonKeep.setStyleSheet('QPushButton {color: green;}') self.buttonDiscard = QPushButton('Discard (Left arrow key)') self.buttonDiscard.setStyleSheet('QPushButton {color: red;}') self.fileList = QListWidget() self.micrograph = emimage2d.EMImage2DWidget(image=EMAN2.EMData( 700, 700), application=app, parent=self) self.powerSpectrum = emimage2d.EMImage2DWidget(image=EMAN2.EMData( 700, 700), application=app, parent=self) self.all_items = [] def loadFromBufferMemory(self): """loads the content from the buffer database""" image_list = [] buffer_lines = [] self.buffer_path = "/home/turi/Schreibtisch/buffermemory.txt" with open(self.buffer_path) as buffer: buffer = buffer.read() if len(buffer) > 0: buffer_lines = buffer.split(',') print("buffer", buffer_lines) else: print("Buffer is empty") for image_index in range(len(buffer_lines)): # cleans the image name and status to add them in the GUI image_path = str(buffer_lines[image_index].split(':')[0]) print("imagepath", image_path) image_status = str(buffer_lines[image_index].split(':')[1]) print("imagestatus", image_status) # remove symbols from the image_name string if "(u'" in image_path: image_path = image_path.replace("(u'", "") if "',)" in image_path: image_path = image_path.replace("',)", "") if "\n" in image_path: image_path = image_path.replace("\n", "") if "'" in image_path: image_path = image_path.replace("'", "") if "\"" in image_path: image_path = image_path.replace("\"", "") if "[" in image_path: image_path = image_path.replace("[", "") if "]" in image_path: image_path = image_path.replace("]", "") if "\\" in image_path: image_path = image_path.replace("\\", "") image_name = QFileInfo(image_path).fileName() image_list.append(image_path) # adds the name item = QListWidgetItem(image_name) # remove symbols from the status string if "(u'" in image_status: image_status = image_status.replace("(u'", "") if "',)" in image_status: image_status = image_status.replace("',)", "") if "\n" in image_status: image_status = image_status.replace("\n", "") if "'" in image_status: image_status = image_status.replace("'", "") if "[" in image_status: image_status = image_status.replace("[", "") if "]" in image_status: image_status = image_status.replace("]", "") if image_status == "checked": item.setCheckState(Qt.Checked) if image_status == "unchecked": item.setCheckState(Qt.Unchecked) self.fileList.addItem(item) if len(image_list) > 0: self.uploadMicrographs(image_list=image_list, upload_from_buffer=True) else: pass def createLayout(self): """layout: left, middle, right layouts, all three are vertically structured""" layoutMain = QHBoxLayout() layoutLeft = QVBoxLayout() layoutLeft.addWidget(self.buttonLoad) layoutLeft.addWidget(self.fileList) layoutLeft.addWidget(self.buttonSave) layoutMiddle = QVBoxLayout() layoutMiddle.addWidget(self.micrograph) layoutMiddle.addWidget(self.buttonKeep) layoutRight = QVBoxLayout() layoutRight.addWidget(self.powerSpectrum) layoutRight.addWidget(self.buttonDiscard) layoutMain.addLayout(layoutLeft, stretch=1) layoutMain.addLayout(layoutMiddle, stretch=2) layoutMain.addLayout(layoutRight, stretch=2) widgetMain = QWidget() widgetMain.setLayout(layoutMain) self.setCentralWidget(widgetMain) def createMenu(self): self.actionOpenData = QAction(("Open file.."), self) self.actionSaveData = QAction(("Save"), self) self.actionSelectAll = QAction(("Select all"), self) self.actionDeselectAll = QAction(("Deselect all"), self) self.actionSetCheck_fromKeepFile = QAction("Upload Keep/Discard Files", self) self.actionQuit = QAction(("Quit"), self) self.actionQuit.setMenuRole(QAction.QuitRole) menu_file = self.menuBar().addMenu("File") menu_file.addAction(self.actionOpenData) menu_file.addAction(self.actionSaveData) menu_file.addAction(self.actionSelectAll) menu_file.addAction(self.actionDeselectAll) menu_file.addAction(self.actionSetCheck_fromKeepFile) menu_file.addSeparator() menu_file.addAction(self.actionQuit) self.menuBar().addMenu("Help") def createConnects(self): self.buttonLoad.clicked.connect( self.buttonLoad_clicked) # function call without ()-sign self.buttonSave.clicked.connect(self.buttonSave_clicked) self.buttonKeep.clicked.connect(self.buttonKeep_clicked) self.buttonDiscard.clicked.connect(self.buttonDiscard_clicked) self.fileList.clicked.connect(self.changeImageByMouse) self.fileList.keyPressEvent = self.myKeyPressEvent self.micrograph.keyPressEvent = self.myKeyPressEvent self.powerSpectrum.keyPressEvent = self.myKeyPressEvent self.actionSelectAll.triggered.connect(self.selectAll) self.actionDeselectAll.triggered.connect(self.deselectAll) self.actionSetCheck_fromKeepFile.triggered.connect( self.setCheck_fromKeepFile) def myKeyPressEvent(self, buttonSignal): if self.fileList.count() > 0: if buttonSignal.key() == Qt.Key_Right: print "Right" self.arrowKeyRight_clicked() elif buttonSignal.key() == Qt.Key_Left: print "Left" self.arrowKeyLeft_clicked() elif buttonSignal.key() == Qt.Key_Up: print "Up" self.arrowKeyUp_clicked() elif buttonSignal.key() == Qt.Key_Down: print "Down!" self.arrowKeyDown_clicked() def loadMicrographsFromItemList(self, image_index): """creates an EMImage-Widget""" if self.current_image is None: image_path = self.all_items[image_index] # self.current_image = EMAN2.EMData(image_path) self.micrograph.set_data( self.current_image ) # in project description as 'aaa' instead of 'micrograph' def loadPowerSpectrumFromItemList(self, image_index): """creates power spectrum of a micrograph""" # Try to load image from buffer # If buffer is empty, wait the image appears while True: load_successfull = False try: preload_image_path, preload_image_index, img, fft_img = img_buffer.popleft( ) if preload_image_index == image_index: load_successfull = True except IndexError as e: print("Index error", e) time.sleep(1) if load_successfull: break self.current_image = img self.powerSpectrum.set_data(fft_img) def preload_images(self, micrograph_list, img_buffer): """ Preloads IMG_BUFFER_SIZE number of images into the memory. :param micrograph_list: list of all micrographs ######## mistake --> here it gets just a string not a list :param img_buffer: deque as buffer for images :return: None """ print("preload_images micrograph_list", micrograph_list) offset = 0 last_index = -1 while True: index = self.fileList.row(self.fileList.currentItem()) if last_index != -1: if index - last_index == 1: offset = offset - 1 elif index - last_index != 0: offset = 0 if len(img_buffer) < IMG_BUFFER_SIZE and ( index + offset) < len(micrograph_list): start = time.time() print("in", index + offset) print("micrograph_list", micrograph_list) filename = str(micrograph_list[index + offset]) print("filename", filename) image = EMAN2.EMData(filename) fft_img = image.do_fft() fft_img.set_value_at(0, 0, 0, 0) fft_img.set_value_at(1, 0, 0, 0) fft_img.process_inplace("xform.phaseorigin.tocorner") fft_img.process_inplace("xform.fourierorigin.tocenter") fft_img = fft_img.get_fft_amplitude() img_buffer.append((filename, index + offset, image, fft_img)) end = time.time() print("Put new image:", filename, "Current index", index, "Image+offset:", index + offset, "offset", offset, "time", end - start) offset = offset + 1 else: time.sleep(1) last_index = index def buttonLoad_clicked(self): """"opens dialog for folder selection, """ image_dir = QFileDialog.getExistingDirectory(parent=None, caption=u"Open directory") image_dir = str(image_dir) image_list = [] for root, dirs, files in os.walk(image_dir): for file in files: if (".mrc" or ".tiff" or ".tif" or ".hdf" or ".png") in file: image_list.append(image_dir + "/" + file) #if no micrograph loaded if len(image_list) == 0: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setInformativeText("No images in the selected folder") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() if len(image_list) > 0: self.uploadMicrographs(image_list=image_list, upload_from_buffer=False) else: pass def buttonSave_clicked(self): """the keep and discard image names are added to two independent text files one for keep one for discard""" save_dir = QFileDialog.getExistingDirectory( parent=None, caption="Directory of selected and discarded file with image names" ) path_selected = str(save_dir) + "/" + "selected_images.txt" path_discarded = str(save_dir) + "/" + "discarded_images.txt" try: file_selected = open(path_selected, "w+") file_discarded = open(path_discarded, "w+") except IOError: return number_of_items = self.fileList.count() for index in range(number_of_items): # as often as number of files if (self.fileList.item(index).checkState()) == Qt.Checked: file_selected.write( os.path.basename(self.all_items[index]) + "\n") else: file_discarded.write( os.path.basename(self.all_items[index]) + "\n") file_selected.close() file_discarded.close() def uploadMicrographs(self, image_list, upload_from_buffer): """loads the micrograph into the GUI and saves their path and status in buffer memory""" #global all_items # maybe problematic? #all_items = [] self.all_items = [] image_path_and_status = [] if upload_from_buffer == True: for image_path in image_list: # loads the micrograph names and status into the GUI self.all_items.append(image_path) if upload_from_buffer == False: self.fileList.clear() # add a try except tree for image_path in image_list: print "Path", image_path image_name = QFileInfo(image_path).fileName() item = QListWidgetItem(image_name) image_path = str( image_path) # contains the path and the name of the image self.all_items.append(image_path) image_path_and_status.append(image_path + ":" + "checked") item.setCheckState(Qt.Checked) self.fileList.addItem(item) # remove symbols from the list image_path_and_status = str(image_path_and_status) if "'" in image_path_and_status: image_path_and_status = image_path_and_status.replace("'", "") if "[" in image_path_and_status: image_path_and_status = image_path_and_status.replace("[", "") if "]" in image_path_and_status: image_path_and_status = image_path_and_status.replace("]", "") if " " in image_path_and_status: image_path_and_status = image_path_and_status.replace(" ", "") with open(self.buffer_path, "w") as buffer: buffer.write(image_path_and_status) if len(image_list) > 0: # loads the micrographs into the GUI self.fileList.setCurrentRow(0) thread.start_new_thread(self.preload_images, ( image_list, img_buffer, )) self.loadPowerSpectrumFromItemList(0) self.loadMicrographsFromItemList(0) last_loaded_image = 0 def writeToBuffer_check(self): """the status of the image is written to the buffer""" row_index = self.fileList.row(self.fileList.currentItem()) with open(self.buffer_path, "r") as buffer: buffer_lines = buffer.read().split(",") buffer_line = buffer_lines[row_index].split(":") print(buffer_line) image_path = buffer_line[0] image_status = buffer_line[1] # order of checking importance: checked is included in unchecked !!! if "unchecked" in image_status: image_status = image_status.replace("unchecked", "checked") elif "checked" in image_status: pass buffer_lines[row_index] = str(image_path + ":" + image_status) buffer_lines = str(buffer_lines) if "'" in buffer_lines: buffer_lines = buffer_lines.replace("'", "") if "\"" in buffer_lines: buffer_lines = buffer_lines.replace("\"", "") if "[" in buffer_lines: buffer_lines = buffer_lines.replace("[", "") if "]" in buffer_lines: buffer_lines = buffer_lines.replace("]", "") if " " in buffer_lines: buffer_lines = buffer_lines.replace(" ", "") if "\\" in buffer_lines: buffer_lines = buffer_lines.replace("\\", "") print("Bufferline", str(buffer_lines)) with open(self.buffer_path, "w") as buffer: buffer.write(str(buffer_lines)) def writeToBuffer_uncheck(self): """the status of the image is written to the buffer""" row_index = self.fileList.row(self.fileList.currentItem()) with open(self.buffer_path, "r") as buffer: buffer_lines = buffer.read().split(",") buffer_line = buffer_lines[row_index].split(":") image_path = buffer_line[0] image_status = buffer_line[1] # order of checking importance: checked is included in unchecked !!! if "unchecked" in image_status: pass elif "checked" in image_status: image_status = image_status.replace("checked", "unchecked") buffer_lines[row_index] = str(image_path + ":" + image_status) print("Puffer", buffer_lines) buffer_lines = str(buffer_lines) if "'" in buffer_lines: buffer_lines = buffer_lines.replace("'", "") if "\"" in buffer_lines: buffer_lines = buffer_lines.replace("\"", "") if "[" in buffer_lines: buffer_lines = buffer_lines.replace("[", "") if "]" in buffer_lines: buffer_lines = buffer_lines.replace("]", "") if " " in buffer_lines: buffer_lines = buffer_lines.replace(" ", "") if "\\" in buffer_lines: buffer_lines = buffer_lines.replace("\\", "") print("Bufferline", str(buffer_lines)) with open(self.buffer_path, "w") as buffer: buffer.write(str(buffer_lines)) def setCheck_fromKeepFile(self): """images are automatically selected or discarded according to saved keep files""" file_dirs = QFileDialog.getExistingDirectory(parent=None, caption=u"Open files") file_list = [] files_selected = [] for root, dirs, files in os.walk(file_dirs): for file in files: if ("selected_images.txt") in file: file_list.append(file_dirs + "/" + file) files_selected.append(file_dirs + "/" + file) if ("discarded_images.txt") in file: file_list.append(file_dirs + "/" + file) # if no micrograph loaded if len(file_list) == 0: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setInformativeText("No textfile in the selected folder") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() else: for index in range(len(files_selected)): with open(files_selected[index], "r") as file: selected_images = file.readlines() if len(selected_images) > 0: if self.fileList.currentItem() is not None: self.fileList.setCurrentRow(0) for uploaded_image in self.all_items: # image contains name and path # all_items has the same order like self.fileList uploaded_image = str(uploaded_image) uploaded_image = uploaded_image.split("/")[ -1] # removes the path, extracts the name for index in range(len(selected_images)): if "\n" in selected_images[index]: selected_images[index] = selected_images[ index].replace("\n", "") if uploaded_image in selected_images: self.setCheck() self.moveToNextItem() else: self.setUncheck() self.moveToNextItem() else: pass def buttonKeep_clicked(self): if self.fileList.currentItem() is not None: self.setCheck() self.moveToNextItem() self.showImageOfCurrentRow() def buttonDiscard_clicked(self): if self.fileList.currentItem() is not None: self.setUncheck() self.moveToNextItem() self.showImageOfCurrentRow() def arrowKeyRight_clicked(self): self.setCheck() self.moveToNextItem() self.showImageOfCurrentRow() def arrowKeyLeft_clicked(self): self.setUncheck() self.moveToNextItem() self.showImageOfCurrentRow() def arrowKeyUp_clicked(self): self.moveToPrevItem() self.showImageOfCurrentRow() def arrowKeyDown_clicked(self): self.moveToNextItem() self.showImageOfCurrentRow() def setCheck(self): self.fileList.currentItem().setCheckState(Qt.Checked) self.writeToBuffer_check() def setUncheck(self): self.fileList.currentItem().setCheckState(Qt.Unchecked) self.writeToBuffer_uncheck() def selectAll(self): """all images get the checked status""" print("bbb") self.fileList.setCurrentRow(0) self.loadPowerSpectrumFromItemList(0) self.loadMicrographsFromItemList(0) print(len(self.all_items)) for row_index in range(len(self.all_items)): print("bbbbb") self.setCheck() self.moveToNextItem() def deselectAll(self): """all images get the unchecked status""" print("ccc") self.fileList.setCurrentRow(0) self.loadPowerSpectrumFromItemList(0) self.loadMicrographsFromItemList(0) print(len(self.all_items)) for row_index in range(len(self.all_items)): print("ccccc") self.setUncheck() self.moveToNextItem() def moveToNextItem(self): row_index = self.fileList.row(self.fileList.currentItem()) self.fileList.setCurrentRow(row_index + 1) if row_index >= (self.fileList.count()) - 1: self.fileList.setCurrentRow(0) def moveToPrevItem(self): row_index = self.fileList.row(self.fileList.currentItem()) self.fileList.setCurrentRow(row_index - 1) if row_index >= (self.fileList.count()) - 1: self.fileList.setCurrentRow(0) def changeImageByMouse(self): self.showImageOfCurrentRow() def showImageOfCurrentRow(self): """the image of current row is shown""" global last_loaded_image # maybe problematic? row_index = self.fileList.row(self.fileList.currentItem()) if last_loaded_image - row_index != 0: self.loadPowerSpectrumFromItemList(row_index) self.loadMicrographsFromItemList(row_index) last_loaded_image = row_index
class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint) # self.setAttribute(Qt.WA_TranslucentBackground) self.resize(900, 700) self.__search_mode = {'fuzzy': 'fuzzy_search', 'precise': 'precise_search', 'reg': 'reg_search'} # self.__pbn_switch_view = None # 创建窗口部件 self.__widget_frame = QLabel() # window title self.__lab_title_fram = QLabel() self.__lab_title = QLabel('搜索辅助工具') self.__lab_title.setAlignment(Qt.AlignCenter) self.__lab_open_tool = QLabel('打开文件方式') self.__ln_open_tool = QLineEdit() self.__pbn_open_tool = QToolButton() self.__pbn_open_tool.setText('选择...') self.__ln_open_tool.setFixedHeight(20) self.__ln_open_tool.setFixedWidth(150) self.__pbn_open_tool.setFixedSize(48, 20) self.__lab_title_fram.setFixedHeight(50) # search mode self.__lab_mode_fram = QLabel() self.__rbn_fuzzy = QRadioButton('模糊搜索') self.__rbn_precise = QRadioButton('精确搜索') self.__rbn_reg = QRadioButton('正则表达式搜索') self.__rbn_fuzzy.setChecked(True) self.__lab_mode_fram.setFixedHeight(22) # search pattern self.__lab_pattern_fram = QLabel() self.__ln_file_name = QLineEdit() self.__ln_file_name.setPlaceholderText('请输入搜索条件或正则表达式......') self.__rbn_reg_Iyes = QRadioButton('区分大小写') self.__rbn_reg_Ino = QRadioButton('不区分大小写') self.__lab_pattern_fram.setFixedHeight(20) # search path self.__lab_path_fram = QLabel() self.__ln_file_path = QLineEdit() self.__ln_file_path.setPlaceholderText('请选择或输入路径......') self.__pbn_file_path = QToolButton() self.__pbn_file_path.setText('浏览...') self.__rbn_search_file = QRadioButton('检索文件名') self.__rbn_search_content = QRadioButton('检索文件内容') self.__pbn_file_path.setFixedSize(48, 20) self.__lab_path_fram.setFixedHeight(20) # search state self.__lab_state_fram = QLabel() self.__lab_state = QLabel('状态:暂无搜索结果!') self.__pbn_search = QPushButton('开始') self.__pbn_stop = QPushButton('停止') self.__pbn_search.setFixedWidth(89) self.__pbn_stop.setFixedWidth(89) self.__lab_state_fram.setFixedHeight(35) # search result self.__tabView = QTabWidget() self.__browser_result = QListWidget() self.__browser_error = QTextBrowser() self.__tabView.addTab(self.__browser_result, '匹配结果') self.__tabView.addTab(self.__browser_error, '错误结果') self.__btn_group_type = QButtonGroup() self.__btn_group_type.addButton(self.__rbn_search_file) self.__btn_group_type.addButton(self.__rbn_search_content) self.__rbn_search_file.setChecked(True) # radiobutton group self.__btn_group_re_I = QButtonGroup() self.__btn_group_re_I.addButton(self.__rbn_reg_Iyes) self.__btn_group_re_I.addButton(self.__rbn_reg_Ino) self.__rbn_reg_Iyes.setChecked(True) # lines ''' self.__line_1 = QFrame() self.__line_1.setFrameStyle(QFrame.HLine | QFrame.Sunken) ''' # 布局 # open tool self.__layout_tool_choose = QHBoxLayout() self.__layout_tool_choose.addWidget(self.__ln_open_tool) self.__layout_tool_choose.addWidget(self.__pbn_open_tool) self.__layout_tool_choose.setSpacing(0) self.__layout_tool_choose.setContentsMargins(0, 0, 0, 0) self.__layout_open_tool = QHBoxLayout() self.__layout_open_tool.addWidget(self.__lab_open_tool) self.__layout_open_tool.addLayout(self.__layout_tool_choose) self.__layout_open_tool.setSpacing(2) # window title self.__layout_title = QHBoxLayout() self.__layout_title.addStretch(5) self.__layout_title.addWidget(self.__lab_title) self.__layout_title.addStretch(1) self.__layout_title.addLayout(self.__layout_open_tool) self.__layout_title.setContentsMargins(0, 0, 0, 20) self.__lab_title_fram.setLayout(self.__layout_title) # search mode self.__layout_search_mode = QHBoxLayout() self.__layout_search_mode.addWidget(self.__rbn_fuzzy) self.__layout_search_mode.addStretch() self.__layout_search_mode.addWidget(self.__rbn_precise) self.__layout_search_mode.addStretch() self.__layout_search_mode.addWidget(self.__rbn_reg) self.__layout_search_mode.setContentsMargins(60, 0, 60, 0) self.__lab_mode_fram.setLayout(self.__layout_search_mode) # search pattern self.__layout_search_reg_I = QHBoxLayout() self.__layout_search_reg_I.addWidget(self.__rbn_reg_Iyes) self.__layout_search_reg_I.addWidget(self.__rbn_reg_Ino) self.__layout_pattern = QHBoxLayout() self.__layout_pattern.addWidget(self.__ln_file_name) self.__layout_pattern.addLayout(self.__layout_search_reg_I) self.__layout_pattern.setContentsMargins(0, 0, 0, 0) self.__lab_pattern_fram.setLayout(self.__layout_pattern) # search path self.__layout_choose_path = QHBoxLayout() self.__layout_choose_path.addWidget(self.__ln_file_path) self.__layout_choose_path.addWidget(self.__pbn_file_path) self.__layout_choose_path.setSpacing(0) self.__layout_path = QHBoxLayout() self.__layout_path.addLayout(self.__layout_choose_path) self.__layout_path.addWidget(self.__rbn_search_file) self.__layout_path.addWidget(self.__rbn_search_content) self.__layout_path.setContentsMargins(0, 0, 0, 0) self.__lab_path_fram.setLayout(self.__layout_path) # search state self.__layout_state = QHBoxLayout() self.__layout_state.addWidget(self.__lab_state) self.__layout_state.addWidget(self.__pbn_search) self.__layout_state.addWidget(self.__pbn_stop) self.__layout_state.setContentsMargins(0, 0, 0, 10) self.__lab_state_fram.setLayout(self.__layout_state) # top layout self.__layout_top = QVBoxLayout() self.__layout_top.addWidget(self.__lab_title_fram) self.__layout_top.addWidget(self.__lab_mode_fram) self.__layout_top.addWidget(self.__lab_pattern_fram) self.__layout_top.addWidget(self.__lab_path_fram) self.__layout_top.addWidget(self.__lab_state_fram) self.__layout_top.addWidget(self.__tabView) self.__layout_top.setSpacing(10) self.__widget_frame.setLayout(self.__layout_top) self.__layout_fram = QGridLayout() self.__layout_fram.addWidget(self.__widget_frame, 0, 0, 1, 1) self.__layout_fram.setContentsMargins(0, 0, 0, 0) self.setLayout(self.__layout_fram) # set object name self.__widget_frame.setObjectName('fram') self.__lab_title.setObjectName('lab_title') self.__ln_open_tool.setObjectName('ln_open_tool') self.__lab_mode_fram.setObjectName('mode_fram') self.__ln_file_name.setObjectName('ln_pattern') self.__ln_file_path.setObjectName('ln_path') self.__lab_state.setObjectName('state') self.__tabView.setObjectName('tabView') self.__browser_result.setObjectName('browser_result') self.__browser_error.setObjectName('browser_error') self.setStyleSheet( '#fram{' 'border-image: url(Images/bg);' '}' '#lab_title{' 'color: white;' 'font-size: 18pt;' '}' '#open_tool{' 'color: black;' '}' '#mode_fram{' # 'border-top: 1px solid rgba(20, 20, 20, 100);' # 'border-bottom: 1px solid rgba(20, 20, 20, 100);' 'background: rgba(0, 0, 0, 40);' '}' '#ln_open_tool, #ln_path{' 'border-top-left-radius: 2px;' 'border-bottom-left-radius: 2px;' '}' '#ln_pattern{' 'border-radius: 2px;' '}' '#state{' 'background: rgba(0, 0, 0, 40);' 'border-radius: 2px;' 'padding: 1px;' 'color: rgb(240, 240, 240);' '}' 'QTabBar::tab {' 'border: 0;' 'width: 90px;' 'height: 20px;' 'margin: 0 2px 0 0;' # top right bottom left # 'border-top-left-radius: 5px;' # 'border-top-right-radius: 5px;' 'color: rgb(200, 255, 255;);' '}' 'QTabBar::tab:selected{' 'background: rgba(25, 0, 0, 40);' 'border-left: 1px solid rgba(255, 255, 255, 200);' 'border-top: 1px solid rgba(255, 255, 255, 200);' 'border-right: 1px solid rgba(255, 255, 255, 200);' '}' 'QTabWidget:pane {' 'border: 1px solid rgba(255, 255, 255, 200);' 'background: rgba(0, 0, 0, 80);' '}' '#browser_result, #browser_error{' 'background: rgba(0, 0, 0, 0);' 'border: 0;' '}' 'QLineEdit{' 'background: rgba(0, 0, 0, 40);' 'border: 1px solid rgba(220, 220, 220, 200);' 'color: white;' 'height: 20px;' '}' 'QPushButton{' 'background: rgba(0, 0, 0, 100);' 'border-radius: 5px;' 'height: 20px;' 'color: white;' '}' 'QPushButton::hover{' 'background: rgba(0, 0, 0, 150);' '}' 'QToolButton{' 'background: rgba(0, 0, 0, 100);' 'color: white;' 'border-top-right-radius: 2px;' 'border-bottom-right-radius: 2px;' '}' 'QToolButton::hover{' 'background: rgba(0, 0, 0, 150);' '}' ) self.__ln_file_name.setFocus() self.__pbn_search.setShortcut(Qt.Key_Return) # 关联 信号/槽 self.__pbn_file_path.clicked.connect(self.choose_path) self.__pbn_search.clicked.connect(self.pbn_search_clicked) self.__pbn_stop.clicked.connect(self.pbn_stop) self.__pbn_open_tool.clicked.connect(self.choose_open_tool) self.__browser_result.doubleClicked.connect(self.listitem_clicked) # 线程间共享数据队列 queue_size = 10000 self.__queue_result = Queue(queue_size) self.__queue_error = Queue(queue_size) # 标记搜索状态 self.__searching = False # 强制结束子线程 self.__thread_killer = False # 重写鼠标按下事件 def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.offset = event.globalPos() - self.pos() # 重写鼠标移动事件 def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() - self.offset) # 检测记事本程序 def set_open_tool(self): if platform.architecture() == ('32bit', 'WindowsPE'): possible_dir = ['C:\\Program Files\\Sublime Text 2', 'C:\\Sublime Text 2', 'D:\\Program Files\\Sublime Text 2', 'D:\\Sublime Text 2', 'E:\\Program Files\\Sublime Text 2', 'E:\\Sublime Text 2', 'F:\\Program Files\\Sublime Text 2', 'F:\\Sublime Text 2', 'C:\\Program Files\\Notepad++', 'C:\\notepad++', 'D:\\Program Files\\Notepad++', 'D:\\notepad++', 'E:\\Program Files\\Notepad++', 'E:\\notepad++', 'F:\\Program Files\\Notepad++', 'F:\\notepad++', 'C:\\Windows\\System32'] elif platform.architecture() == ('32bit', 'ELF'): possible_dir = ['/usr/bin'] for rootdir in possible_dir: for root, dirs, files in walk(rootdir): for file in files: if file == 'sublime_text.exe' or file == 'notepad++.exe' or file == 'notepad.exe': self.__ln_open_tool.setText(join(root, file)) return # 搜索文件名 def search_from_filename(self, filepath, filename, mode='fuzzy_search', I=True): # check arguments of searching if filepath == '' or not exists(filepath): return False if mode not in self.__search_mode.values(): return False if filename == '': return False # count count = 0 # fuzzy mode if mode == self.__search_mode['fuzzy']: for root, dirs, files in walk(filepath): for each_file in files: # kill subThread if self.__thread_killer == True: return if filename in each_file: count += 1 self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count) self.__queue_result.put(join(root, each_file)) self.__tabView.setTabText(0, '匹配结果(%d)' % count) # precise mode elif mode == self.__search_mode['precise']: for root, dirs, files in walk(filepath): for each_file in files: # kill subThread if self.__thread_killer == True: return if filename == splitext(each_file)[0] or filename == each_file: count += 1 self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count) self.__queue_result.put(join(root, each_file)) self.__tabView.setTabText(0, '匹配结果(%d)' % count) # regular expression mode elif mode == self.__search_mode['reg']: if I: pattern = re.compile(r'%s' % filename) else: pattern = re.compile(r'%s' % filename, re.I) for root, dirs, files in walk(filepath): for each_file in files: # kill subThread if self.__thread_killer == True: return if re.search(pattern, each_file): count += 1 self.__lab_state.setText('正在搜索......已搜到 %d 个文件' % count) self.__queue_result.put(join(root, each_file)) self.__tabView.setTabText(0, '匹配结果(%d)' % count) self.__lab_state.setText('搜索完毕! 共搜到 %d 个文件' % count) # finished self.__searching = False # set serching flag # 搜索文件内容 def search_from_content(self, path, content, mode='fuzzy_search', I=True): if path == '' or not exists(path): return False if mode not in self.__search_mode.values(): return False if content == '': return False pass_file_count = 0 error_number = 0 current_file = '' processing_file = '' match_files_count = 0 if mode == self.__search_mode['reg']: if I: pattern = re.compile(r'%s' % content) else: pattern = re.compile(r'%s' % content, re.I) for root, dirs, files in walk(path): for each_file in [file for file in files if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.cs')]: current_file = join(root, each_file) pass_file_count += 1 self.__lab_state.setText('正在搜索......%s' % current_file) try: for line_number, line in enumerate(open(current_file)): # kill subThread if self.__thread_killer == True: return if re.search(pattern, line): if processing_file != current_file: self.__queue_result.put('\n%s' % current_file) processing_file = current_file match_files_count += 1 self.__queue_result.put('line %s: %s' % (line_number, line.strip())) except Exception as error: self.__queue_error.put("%s\n(%s)\n" % (error, current_file)) pass_file_count -= 1 error_number += 1 continue self.__tabView.setTabText(0, '匹配结果(%d)' % match_files_count) else: for root, dirs, files in walk(path): for each_file in [file for file in files if file.endswith('.h') or file.endswith('.cpp') or file.endswith('.cs') or file.endswith('.txt') or file.endswith('.py')]: current_file = join(root, each_file) pass_file_count += 1 self.__lab_state.setText('正在搜索......%s' % current_file) try: for line_number, line in enumerate(open(current_file)): # kill subThread if self.__thread_killer == True: return if content in line: # 匹配成功 if processing_file != current_file: # 如果是新文件 self.__queue_result.put('\n%s' % current_file) # 文件名入队 processing_file = current_file # 更新文件标记 match_files_count += 1 self.__queue_result.put('line %s: %s' % (line_number, line.strip())) # 匹配行入队 except Exception as error: self.__queue_error.put("%s\n(%s)\n" % (error, current_file)) pass_file_count -= 1 error_number += 1 continue self.__tabView.setTabText(0, '匹配结果(%d)' % match_files_count) # self.__queue_result.put() self.__lab_state.setText('搜索完毕!成功匹配 %d 个文件,处理 %s 个文件,失败 %s 文件。' % (match_files_count, pass_file_count, error_number)) self.__searching = False # 单击选择路径按钮 def choose_path(self): path = QFileDialog.getExistingDirectory() if path != '': path = sep.join(path.split('/')) self.__ln_file_path.setText(path) # 选择打开文件工具 def choose_open_tool(self): path = QFileDialog.getOpenFileName() if path[0] != '': self.__ln_open_tool.setText(path[0]) # 显示搜索结果 def show_search_result(self): """将搜索结果加载到界面,供用户查看和操作""" line_block = [] # 定义临时列表,成批加载,避免刷新频率过高造成界面闪烁 block_size = 10 # 一次性加载的个数 while self.__searching or self.__queue_result.qsize(): # kill subThread if self.__thread_killer == True: return # if self.__searching or self.__queue_result.qsize() >= block_size: // 永远记住这个 bug (生产者-消费者 问题) if self.__queue_result.qsize() >= block_size: # 如果队列中不小于 block_size 个项 for i in range(block_size): # 取出 block_size 个项 line_block.append(self.__queue_result.get()) # 出队操作 self.__browser_result.addItems(line_block) # 一次性添加 block_size 个条目 line_block.clear() # 清空临时列表 elif self.__queue_result.qsize() >= 0: # 如果队列中小于 block_size 各项 item = self.__queue_result.get() # 出队一项 self.__browser_result.addItem(QListWidgetItem(item)) # 加载到界面 #self.__browser.setCurrentRow(self.__browser.count()-1) # 设置列表中最后一项为当前项,使列表不停滚动 sleep(0.05) # 给界面事件循环腾出时间,避免界面冻结 #self.__pbn_search.setEnabled(True) # 显示出错结果 def show_error_result(self): """打印略过的文件和出错原因,多为 I/O Error""" count = 0 while self.__queue_error.qsize() or self.__searching: # kill subThread if self.__thread_killer == True: return if self.__queue_error.qsize() <= 0: continue self.__browser_error.append(self.__queue_error.get()) count += 1 self.__tabView.setTabText(1, '错误结果(%d)' % count) # 单击检索按钮 def pbn_search_clicked(self): """To search allow the arguments from UI""" # 获取 UI 数据 file_path = self.__ln_file_path.text() file_name = self.__ln_file_name.text() # 检查参数 if file_path == '': QMessageBox(QMessageBox.Warning, '缺少参数!', '请输入搜索路径!', QMessageBox.Ok, self).exec_() return if file_name == '': QMessageBox(QMessageBox.Warning, '缺少参数!', '请输入匹配条件!', QMessageBox.Ok, self).exec_() return # 判断搜索模式 mode = self.__search_mode['fuzzy'] if self.__rbn_reg.isChecked(): mode = self.__search_mode['reg'] elif self.__rbn_fuzzy.isChecked(): mode = self.__search_mode['fuzzy'] elif self.__rbn_precise.isChecked(): mode = self.__search_mode['precise'] # 大小写敏感标记 I = True if self.__rbn_reg_Ino.isChecked(): I = False self.__browser_result.clear() self.__browser_error.clear() self.__tabView.setTabText(0, '匹配结果(0)') self.__tabView.setTabText(1, '错误结果(0)') self.__searching = True # 开启子线程,后台深度遍历 self.__thread_killer = False if self.__rbn_search_file.isChecked(): self.__lab_state.setText('正在搜索......已搜索到 0 个文件') self.__sub_thread_search = Thread(target=self.search_from_filename, args=(file_path, file_name, mode, I)) self.__sub_thread_search.start() else: self.__lab_state.setText('正在搜索......') self.__sub_thread_search = Thread(target=self.search_from_content, args=(file_path, file_name, mode, I)) self.__sub_thread_search.start() # 开启子线程,显示搜索结果 self.__sub_thread_show_result = Thread(target=self.show_search_result) self.__sub_thread_show_result.start() # 开启子线程,显示错误结果 self.__sub_thread_show_error = Thread(target=self.show_error_result) self.__sub_thread_show_error.start() # self.__pbn_search_file.setEnable(False) # self.__pbn_search_content.setEnable(False) # 单击停止按钮 def pbn_stop(self): if not self.__searching: return self.__thread_killer = True while self.__queue_result.qsize(): self.__queue_result.get() while self.__queue_error.qsize(): self.__queue_error.get() self.__lab_state.setText('搜索已停止!') self.__searching = False # 双击搜索结果 def listitem_clicked(self): """Double click to open the file from search result""" file_path = self.__browser_result.currentItem().text().strip() read_tool = self.__ln_open_tool.text() if not exists(file_path): QMessageBox.warning(self, '错误!', '请双击文件名\n%s 不是文件或打不开!' % file_path, QMessageBox.Ok) return if splitext(file_path)[1] in ['.jpg', '.png', '.jpeg', '.gif']: file_path = r'%s'.replace(' ', r'\ ') % file_path system('%s' % file_path) else: system('"%s" %s' % (read_tool, file_path))
class CityListDlg(QDialog): citieslist_signal = pyqtSignal([list]) citiesdict_signal = pyqtSignal([dict]) def __init__(self, citylist, accurate_url, appid, trans_cities_dict, parent=None): super(CityListDlg, self).__init__(parent) self.settings = QSettings() self.citylist = citylist self.trans_cities_dict = trans_cities_dict self.accurate_url = accurate_url self.appid = appid self.listWidget = QListWidget() self.listWidget.itemDoubleClicked.connect(self.translate) cities_list = [] for i in self.citylist: cities_list.append(self.trans_cities_dict.get(i, i)) self.listWidget.addItems(cities_list) buttonLayout = QVBoxLayout() self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.rejected.connect(self.reject) self.buttonBox.accepted.connect(self.accept) layoutT = QVBoxLayout() layout = QHBoxLayout() layout.addWidget(self.listWidget) layout.addLayout(buttonLayout) for text, slot in ((self.tr("&Add..."), self.add), (self.tr("&Remove..."), self.remove), (self.tr("&Up"), self.up), (self.tr("&Down"), self.down), (self.tr("De&fault"), self.default), (self.tr("&Sort"), self.listWidget.sortItems)): button = QPushButton(text) buttonLayout.addWidget(button) button.clicked.connect(slot) self.translate_button = QPushButton( QCoreApplication.translate('Button', '&Translate', 'Edit cities name')) buttonLayout.addWidget(self.translate_button) self.translate_button.clicked.connect(self.translate) buttonLayout.addWidget(self.buttonBox) self.status = QLabel() layoutT.addLayout(layout) layoutT.addWidget(self.status) self.setLayout(layoutT) self.setWindowTitle( QCoreApplication.translate('Window title', 'Cities', 'Cities list dialogue')) self.checklength() def add(self): self.status.setText('') lista = [] newitem = '' self.citytoadd = '' self.countrytoadd = '' self._idtoadd = '' dialog = searchcity.SearchCity(self.accurate_url, self.appid, self) dialog.id_signal.connect(self.addcity) dialog.city_signal.connect(self.addcity) dialog.country_signal.connect(self.addcity) if dialog.exec_() == 1: newitem = (self.citytoadd + '_' + self.countrytoadd + '_' + self._idtoadd) for row in range(self.listWidget.count()): lista.append(self.listWidget.item(row).text()) if newitem in lista: self.status.setText( QCoreApplication.translate( 'Status bar message', 'The city already exists in the list', 'Cities list dialogue')) return else: self.listWidget.addItem(newitem) self.checklength() self.status.setText('ℹ ' + QCoreApplication.translate( 'Status bar message', 'Toggle cities with mouse scroll on the weather window', 'Cities list dialogue')) def addcity(self, what): self.status.setText('') if what[0] == 'ID': self._idtoadd = what[1] elif what[0] == 'City': self.citytoadd = what[1] elif what[0] == 'Country': self.countrytoadd = what[1] def remove(self): self.status.setText('') if self.listWidget.count() == 1: self.status.setText( QCoreApplication.translate( 'Message when trying to remove the' 'last and unique city in the list', 'This is the default city!', 'Cities list dialogue')) return row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is None: return message = self.tr('The city "{0}" has been removed').format( self.listWidget.item(row).text()) item = self.listWidget.takeItem(row) del item self.status.setText(message) def up(self): self.status.setText('') row = self.listWidget.currentRow() if row >= 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row - 1, item) self.listWidget.setCurrentItem(item) def down(self): self.status.setText('') row = self.listWidget.currentRow() if row < self.listWidget.count() - 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row + 1, item) self.listWidget.setCurrentItem(item) def default(self): self.status.setText('') row = self.listWidget.currentRow() if row >= 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(0, item) self.listWidget.setCurrentItem(item) def checklength(self): if self.listWidget.count() == 1: # After adding the first city the entry is not activated self.listWidget.setCurrentRow(0) if self.listWidget.count() > 0: self.translate_button.setEnabled(True) self.listWidget.setMinimumWidth( self.listWidget.sizeHintForColumn(0)) else: self.translate_button.setEnabled(False) def translate(self): city = self.listWidget.currentItem().text() dialog = citytranslate.CityTranslate(city, self.trans_cities_dict, self) dialog.city_signal.connect(self.current_translation) if dialog.exec_() == 1: row = self.listWidget.currentRow() item = self.listWidget.takeItem(row) del item self.listWidget.insertItem(row, self.current_translated_city) self.listWidget.setCurrentRow(row) def current_translation(self, translated_city): for city, translated in translated_city.items(): if translated == '': translated = city self.trans_cities_dict[city] = translated self.current_translated_city = translated def accept(self): listtosend = [] for row in range(self.listWidget.count()): city = self.find_city_key(self.listWidget.item(row).text()) listtosend.append(city) if self.listWidget.count() == 0: return self.citieslist_signal[list].emit(listtosend) self.citiesdict_signal[dict].emit(self.trans_cities_dict) QDialog.accept(self) def find_city_key(self, city): for key, value in self.trans_cities_dict.items(): if value == city: return key return city
class MigrationWidget(QDialog): """2to3 Migration Assistance Widget Class""" dockedWidget = pyqtSignal("QObject*") undockedWidget = pyqtSignal() changeTitle = pyqtSignal(str) def __init__(self, parent=None): super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint) self._migration, vbox, hbox = {}, QVBoxLayout(self), QHBoxLayout() lbl_title = QLabel(translations.TR_CURRENT_CODE) lbl_suggestion = QLabel(translations.TR_SUGGESTED_CHANGES) self.current_list, self.suggestion = QListWidget(), QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(translations.TR_APPLY_CHANGES + " !") self.suggestion.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !") self.btn_apply.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !") # pack up all widgets hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) # connections self.current_list.itemClicked['QListWidgetItem*'].connect(self.load_suggestion) self.btn_apply.clicked['bool'].connect(self.apply_changes) # registers IDE.register_service('tab_migration', self) ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self) def install_tab(self): """Install the Tab on the IDE.""" ide = IDE.getInstance() ide.goingDown.connect(self.close) def apply_changes(self): """Apply the suggested changes on the Python code.""" lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration[lineno][0].split('\n') remove, code = -1, "" for line in lines: if line.startswith('-'): remove += 1 # line to remove elif line.startswith('+'): code += '{line_to_add}\n'.format(line_to_add=line[1:]) # get and apply changes on editor main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() block_start = editorWidget.document().findBlockByLineNumber(lineno) block_end = editorWidget.document().findBlockByLineNumber(lineno + remove) cursor = editorWidget.textCursor() cursor.setPosition(block_start.position()) cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) cursor.insertText(code[:-1]) def load_suggestion(self, item): """Take an argument item and load the suggestion.""" lineno, code = int(item.data(Qt.UserRole)), "" lines = self._migration[lineno][0].split('\n') for line in lines: if line.startswith('+'): code += '{line_to_add}\n'.format(line_to_add=line[1:]) self.suggestion.setPlainText(code) main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): """Refresh the list of code suggestions.""" self._migration, base_lineno = migration, -1 self.current_list.clear() for lineno in sorted(migration.keys()): linenostr = 'L{line_number}\n'.format(line_number=str(lineno + 1)) data = migration[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '{line_to_load}\n'.format(line_to_load=line) item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """Clear the widget.""" self.current_list.clear() self.suggestion.clear() def reject(self): """Reject""" if self.parent() is None: self.dockedWidget.emit(self) def closeEvent(self, event): """Close""" self.dockedWidget.emit(self) event.ignore()
class ClippingsPanel(SettingsPanel): def __init__(self, parent=None): super(ClippingsPanel, self).__init__(parent) self.setWindowTitle(tr("Clippings Manager")) coreColumn = custom_widgets.Column(self) self.layout().addWidget(coreColumn) # Title self.title = QLabel(tr("<b>Clippings</b>"), self) coreColumn.addWidget(self.title) howToUse = QLabel(tr("To use Clippings, Shift+right click a textbox on the page."), self) coreColumn.addWidget(howToUse) row1 = custom_widgets.Row(self) coreColumn.addWidget(row1) column1 = custom_widgets.Column(self) column2 = custom_widgets.Column(self) row1.addWidget(column1) row1.addWidget(column2) # Clipping list. self.clippingList = QListWidget(self) self.clippingList.currentTextChanged.connect(self.loadClipping) column1.addWidget(self.clippingList) self.removeClippingButton = QPushButton(tr("Remove")) self.removeClippingButton.clicked.connect(lambda: self.removeClipping(True)) column1.addWidget(self.removeClippingButton) self.removeAction = QAction(self) self.removeAction.setShortcut("Del") self.removeAction.triggered.connect(self.removeClipping) self.addAction(self.removeAction) clippingNameRow = custom_widgets.LineEditRow(tr("Name:"), self) self.nameEntry = clippingNameRow.lineEdit self.nameEntry.returnPressed.connect(self.addClipping) column2.addWidget(clippingNameRow) self.addClippingButton = QPushButton(tr("Add")) self.addClippingButton.clicked.connect(self.addClipping) clippingNameRow.layout().addWidget(self.addClippingButton) self.clippingEntry = QTextEdit(self) column2.addWidget(self.clippingEntry) def show(self): self.setVisible(True) self.loadSettings() def loadSettings(self): data.load_clippings() self.clippingList.clear() for item in sorted(list(data.clippings.keys())): self.clippingList.addItem(item) def saveSettings(self): data.save_clippings() def removeClipping(self, forceFocus=False): if self.clippingList.hasFocus() or forceFocus: name = self.clippingList.currentItem().text() del data.clippings[name] self.clippingList.takeItem(self.clippingList.row(self.clippingList.currentItem())) self.saveSettings() def loadClipping(self, text): try: self.nameEntry.setText(text) self.clippingEntry.setPlainText(data.clippings[text]) except: pass def addClipping(self): data.clippings[self.nameEntry.text()] = self.clippingEntry.toPlainText() self.saveSettings() self.loadSettings()
class App(QMainWindow): @pyqtSlot() def __init__(self): super().__init__() self.title = 'Google Drive Connection' self.left = 1000 self.top = 1000 self.width = 1000 self.height = 5000 self.initUI() @pyqtSlot() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) #self.setStyleSheet("""QMainWindow{ background: yellow; }""") # Create textbox self.textbox = QLineEdit(self) self.textbox.move(20, 20) self.textbox.resize(280, 40) # Create a button in the window self.button = QPushButton('Add URL', self) self.button.move(20, 80) self.listwidget = QListWidget(self) self.listwidget.move(200, 200) self.listwidget.resize(1000, 1000) self.setStyleSheet("""QListWidget{ background: green; }""") #goolle coneect self.btn = QPushButton('Connect To Google Drive', self) self.btn.resize(289, 49) self.btn.move(1000, 50) self.button3 = QPushButton('Download', self) self.button3.resize(289, 49) self.button3.move(1500, 50) self.button4 = QPushButton('Upload', self) self.button4.resize(289, 49) self.button4.move(2000, 50) # connect button to function on_click self.button.clicked.connect(self.addUrl) self.listwidget.clicked.connect(self.removeURL) self.btn.clicked.connect(self.auth) # self.button3.clicked.connect(self.downloadFile) # self.button4.clicked.connect(self.uploadFile) def addUrl(self): textboxValue = self.textbox.text() subString = textboxValue[0:23] print(subString) if subString == "https://www.youtube.com": self.listwidget.addItem(textboxValue) else: QMessageBox.question(self, 'Error', "The Url you entered is not a valid ", QMessageBox.Ok, QMessageBox.Ok) def removeURL(self): index = self.listwidget.row(self.listwidget.currentItem()) self.listwidget.takeItem(index) # @pyqtSlot() # def downloadFile(self): # # # Call the Drive v3 API # creds = None # if os.path.exists('token.pickle'): # with open('token.pickle', 'rb') as token: # creds = pickle.load(token) # else: # QMessageBox.question(self, 'Error', "Connect to google drive first ", QMessageBox.Ok, # QMessageBox.Ok) # return # # service = build('drive', 'v3', credentials=creds) # results = service.files().list( # pageSize=10, fields="nextPageToken, files(id, name)").execute() # items = results.get('files', []) # # if not items: # print('No files found.') # else: # print('Files:') # for item in items: # print(u'{0} ({1})'.format(item['name'], item['id'])) # @pyqtSlot() # def uploadFile(self): # creds = None # if os.path.exists('token.pickle'): # with open('token.pickle', 'rb') as token: # creds = pickle.load(token) # else: # QMessageBox.question(self, 'Error', "Connect to google drive first ", QMessageBox.Ok, # QMessageBox.Ok) # return # # service = build('drive', 'v3', credentials=creds) # # file_metadata = {'name': 'google.jpg'} # media = service('google.jpg', # mimetype='image/jpeg') # file = service.files().create(body=file_metadata, # media_body=media, # fields='id').execute() # print('File ID: %s' % file.get('id')) @pyqtSlot() def auth(self): """Shows basic usage of the Drive v3 API. Prints the names and ids of the first 10 files the user has access to. """ if os.path.exists('token.pickle'): self.on_click() else: creds = None # The file token.pickle stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) # service = build('drive', 'v3', credentials=creds) self.AuthMessage() @pyqtSlot() def on_click(self): QMessageBox.question(self, 'Message', "You are already connected", QMessageBox.Ok, QMessageBox.Ok) @pyqtSlot() def AuthMessage(self): QMessageBox.question(self, 'Message', "The connection was successfully done", QMessageBox.Ok, QMessageBox.Ok) @pyqtSlot() def of_click(self): QMessageBox.question(self, 'Message - pythonspot.com', "You typed: " + textboxValue, QMessageBox.Ok, QMessageBox.Ok) self.textbox.setText("")
class MigrationWidget(QDialog): """2to3 Migration Assistance Widget Class""" dockWidget = pyqtSignal("QObject*") undockWidget = pyqtSignal() changeTitle = pyqtSignal(str) def __init__(self, parent=None): super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint) self._migration, vbox, hbox = {}, QVBoxLayout(self), QHBoxLayout() lbl_title = QLabel(translations.TR_CURRENT_CODE) lbl_suggestion = QLabel(translations.TR_SUGGESTED_CHANGES) self.current_list, self.suggestion = QListWidget(), QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(translations.TR_APPLY_CHANGES + " !") self.suggestion.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !") self.btn_apply.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !") # pack up all widgets hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) # connections self.current_list.itemClicked['QListWidgetItem*'].connect(self.load_suggestion) self.btn_apply.clicked['bool'].connect(self.apply_changes) # registers IDE.register_service('tab_migration', self) ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self) def install_tab(self): """Install the Tab on the IDE.""" ide = IDE.getInstance() ide.goingDown.connect(self.close) def apply_changes(self): """Apply the suggested changes on the Python code.""" lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration[lineno][0].split('\n') remove, code = -1, "" for line in lines: if line.startswith('-'): remove += 1 # line to remove elif line.startswith('+'): code += '{line_to_add}\n'.format(line_to_add=line[1:]) # get and apply changes on editor main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() block_start = editorWidget.document().findBlockByLineNumber(lineno) block_end = editorWidget.document().findBlockByLineNumber(lineno + remove) cursor = editorWidget.textCursor() cursor.setPosition(block_start.position()) cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) cursor.insertText(code[:-1]) def load_suggestion(self, item): """Take an argument item and load the suggestion.""" lineno, code = int(item.data(Qt.UserRole)), "" lines = self._migration[lineno][0].split('\n') for line in lines: if line.startswith('+'): code += '{line_to_add}\n'.format(line_to_add=line[1:]) self.suggestion.setPlainText(code) main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): """Refresh the list of code suggestions.""" self._migration, base_lineno = migration, -1 self.current_list.clear() for lineno in sorted(migration.keys()): linenostr = 'L{line_number}\n'.format(line_number=str(lineno + 1)) data = migration[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '{line_to_load}\n'.format(line_to_load=line) item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """Clear the widget.""" self.current_list.clear() self.suggestion.clear() def reject(self): """Reject""" if self.parent() is None: self.dockWidget.emit(self) def closeEvent(self, event): """Close""" self.dockWidget.emit(self) event.ignore()
class CustomTextEditor(QWidget): def __init__(self, parent=None, txtInput=None): super(CustomTextEditor, self).__init__(parent) # met en place la coloration syntaxique if txtInput is None: self.txtInput = QTextEdit() else: self.txtInput = txtInput self.txtOutput = QTextEdit() # Search/Replace buttons : self.btnSearch = QPushButton('Search') self.btnReplaceAll = QPushButton('Replace all') self.btnQuickSearchImages = QPushButton('I') self.btnQuickSearchLinks = QPushButton('L') # self.btnClear = QPushButton('Clear') self.chkCaseSensitivity = QCheckBox('Case sensitive') # Line edit to search and replace : self.formSearch = QLineEdit() self.formReplace = QLineEdit() # Labels : self.labelCount = QLabel() self.labNotif = QLabel('') # List widget : self.listFound = QListWidget() # -------------------------------------- self.mainLayout = QGridLayout() self.splitVLayout = QSplitter(QtCore.Qt.Vertical) self.layoutCommand = QGridLayout() # Syntax highlighting : self.colorSyntaxHtml = ColorSyntaxHTML(self.txtInput.document()) self.hotkey = {} self.bind_key( 'actionSearch', 'Ctrl+F', lambda: self.on_ctrl_f_pushed(self.formSearch, self.txtInput)) self.bind_key('actionSearchOnReturnPress', 'Return', lambda: self.search_and_replace(), widget=self.formSearch) self.bind_key('actionSearchOnEnterPress', 'Enter', lambda: self.search_and_replace(), widget=self.formSearch) self.config() def set_size_policy(self, widget, hpolicy=QSizePolicy.Expanding, vpolicy=QSizePolicy.Expanding): policy = QSizePolicy(hpolicy, vpolicy) policy.setHorizontalStretch(0) policy.setVerticalStretch(0) widget.setSizePolicy(policy) def config(self): # ---------- SET STYLES ---------------------------------------- self.setAutoFillBackground(True) pal = self.palette() pal.setColor(self.backgroundRole(), QColor('#7FD1B9')) self.setPalette(pal) self.setStyleSheet('''QTextEdit { margin-right: 5px; background: #ffffff; color: black; border-radius: 4px; border: 0px solid #CBC9D2; selection-background-color: #ffa500; } QTextEdit:hover { background: #ffffff; } QListWidget { background: #ffffff; color: black; } QCheckBox, QLabel { color: #000000; font-size: 14px; } QPushButton { background: #333333; color: #ffffff; border-width: 2px; border-radius: 4px; width: 100px; padding: 4px; font-size: 13px; } QSplitter { background: transparent; } QPushButton:hover { border: 2px solid #FFFFFF; } ''') style_btn_mini = ''' width: 20px; height: 20px; border-radius: 8px; background-color: {bgcolor}; color: {color}; ''' self.btnQuickSearchImages.setStyleSheet( style_btn_mini.format(bgcolor='#1e90ff', color='#ffffff')) self.btnQuickSearchLinks.setStyleSheet( style_btn_mini.format(bgcolor='#ff4500', color='#ffffff')) # ---------------------------------------------------------------- self.setLayout(self.mainLayout) self.layoutCommand.addWidget(self.btnSearch, 0, 0) self.layoutCommand.addWidget(self.btnQuickSearchImages, 0, 1) self.layoutCommand.addWidget(self.btnReplaceAll, 1, 0) self.layoutCommand.addWidget(self.btnQuickSearchLinks, 1, 1) self.layoutCommand.addWidget(self.formSearch, 0, 2) self.layoutCommand.addWidget(self.formReplace, 1, 2) # self.layoutCommand.addWidget(self.btnClear, 0, 2) self.layoutCommand.addWidget(self.labelCount, 0, 3) self.layoutCommand.addWidget(self.labNotif, 1, 4) self.layoutCommand.addWidget(self.chkCaseSensitivity, 1, 3) self.mainLayout.addLayout(self.layoutCommand, 0, 0) self.splitVLayout.addWidget(self.txtInput) self.splitVLayout.addWidget(self.listFound) self.mainLayout.addWidget(self.splitVLayout, 2, 0, 1, 3) self.splitVLayout.setHandleWidth(6) self.splitVLayout.setSizes([200, 40]) # TEXT WIDGET CONFIG : # Set fonts : font = QFont() font.setFamily("DejaVu Sans Mono") font.setStyleHint(QFont.Courier) font.setPointSize(10) self.txtInput.setFont(font) self.txtInput.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor) # ---------- SIGNAL CONNECTION ---------------------------------------- self.btnSearch.clicked.connect(lambda: self.search_and_replace()) # self.btnClear.clicked.connect(lambda: self.wash(self.txtInput)) self.btnReplaceAll.clicked.connect( lambda: self.search_and_replace(replace=True)) self.listFound.itemDoubleClicked.connect( lambda: self.find_on_text(self.listFound.currentItem().text())) self.btnQuickSearchImages.clicked.connect( lambda: self.search_and_replace(pattern='src')) self.btnQuickSearchLinks.clicked.connect( lambda: self.search_and_replace(pattern='href')) # ---------- SET POLICY ---------------------------------------- self.set_size_policy(self.formSearch, QSizePolicy.Expanding, QSizePolicy.Maximum) self.set_size_policy(self.formReplace, QSizePolicy.Expanding, QSizePolicy.Maximum) self.set_size_policy(self.btnSearch, QSizePolicy.Maximum, QSizePolicy.Maximum) self.set_size_policy(self.btnReplaceAll, QSizePolicy.Maximum, QSizePolicy.Maximum) self.set_size_policy(self.btnQuickSearchImages, QSizePolicy.Maximum, QSizePolicy.Maximum) self.set_size_policy(self.btnQuickSearchLinks, QSizePolicy.Maximum, QSizePolicy.Maximum) self.set_size_policy(self.txtInput, QSizePolicy.Expanding, QSizePolicy.Expanding) # Set listWidget cursor shape : self.listFound.setCursor(QtCore.Qt.IBeamCursor) def wash(self, text_edit): text_edit.clear() self.labelCount.setText('') self.listFound.clear() def on_ctrl_f_pushed(self, source_form, text_edit): text = self.current_selection(text_edit) source_form.clear() source_form.setText(text) def current_selection(self, text_edit): cursor = text_edit.textCursor() return cursor.selectedText() def bind_key(self, key_name, key_combo, func, widget=None): if not widget: widget = self self.hotkey[key_name] = QtWidgets.QShortcut(QKeySequence(key_combo), widget) self.hotkey[key_name].activated.connect(func) def search_and_replace(self, replace=False, pattern=None): print('Search and replace function activated') to_search = self.formSearch.text() if pattern: to_search = pattern replace_with = self.formReplace.text() text = self.txtInput.toPlainText() pattern = re.escape(to_search) if to_search == '': return # REPLACE BLOCK ---------------------------------------------------------- if replace: print('Replace now :') self.txtInput.clear() if self.chkCaseSensitivity.isChecked(): text = re.sub(pattern, replace_with, text) else: text = re.sub(pattern, replace_with, text, flags=re.IGNORECASE) self.txtInput.insertPlainText(text) print('Updating label value') self.update_label(self.labNotif, '') # SEARCH ONLY ------------------------------------------------------------ else: print('Search only :') if self.chkCaseSensitivity.isChecked( ): # Check if case sensitive checkbox is checked matches = re.findall(pattern + r'.*', text) else: matches = re.findall(pattern + r'.*', text, re.IGNORECASE) if matches: # If there is any item matches : self.listFound.clear() # Clear the found listWidget [self.listFound.addItem(match) for match in matches] self.labelCount.setText( '<span style="color: #64ca77;">%s items found</span>' % len(matches)) print('Updating label value') self.update_label(self.labNotif, '') else: # If no matches : self.labelCount.setText( '<span style="color: red;">No item found</span>') self.listFound.clear() self.listFound.addItem('No item found...') return None def detect_bads(self): fr = re.findall(r'\.fr', self.txtInput.toPlainText()) com = re.findall(r'\.com', self.txtInput.toPlainText()) pixel = re.findall(r'<img.*?width="1".*?>{1}|<img.*?height="1".*?>{1}', self.txtInput.toPlainText()) bads = [x for x in (fr + com + pixel) if x is not None] print('Bads :', bads) def find_on_text(self, pattern): print('Find on text') # self.txtInput.moveCursor(QTextCursor.Start) found = self.txtInput.find(pattern) if not found: found = self.txtInput.find(self.listFound.currentItem().text(), QTextDocument.FindBackward) # self.txtInput.moveCursor(QTextCursor.Start) def update_label(self, label, text=''): if isinstance(label, QLabel): old_color = label.palette().color(QPalette.Background).name() print(old_color) pick = '#%s' % ''.join( [random.choice(hexdigits) for i in range(6)]) while pick.lower() == old_color.lower(): pick = '#%s' % ''.join( [random.choice(hexdigits) for i in range(6)]) label.clear() label.setText(text) label.setFixedWidth(15) label.setFixedHeight(15) label.setStyleSheet('background: %s' % pick)
class ProjectManagerPane(QWidget): """UI to select a project to start. Users are presented a list of existing projects or the available templates to start a new project. """ def __init__(self, main_window, projlist, parent=None): super().__init__(parent) self.layout = QHBoxLayout() self.setLayout(self.layout) self.tabs = QTabWidget() self.tabs.setObjectName('projectchoosertabs') self.layout.addWidget(self.tabs) self.projects = QListWidget() self.projects.currentItemChanged.connect(self.selected_project) self.templates = QListWidget() self.templates.currentItemChanged.connect(self.selected_template) if any(projlist): self.tabs.addTab(self.projects, "Existing Project") self.tabs.addTab(self.templates, "New Project") self.tabs.currentChanged.connect(self.tab_changed) self.detailspane = QVBoxLayout() self.layout.addLayout(self.detailspane) self.details = QLabel(DEFAULT_DETAILS) self.go = QPushButton("Go") self.go.setDisabled(True) self.go.clicked.connect(self.perform_action) self.detailspane.addWidget(self.details) self.detailspane.addWidget(self.go) self.action = None self.main_window = main_window self.projlist = projlist self.update_choices() def update_choices(self): for p in PROJECTS: self.templates.addItem(p.NAME) for name in self.projlist: self.projects.addItem(name) def tab_changed(self, index): """Called when the active tab is changed.""" if self.tabs.tabText(index) == "New Project": self.selected_template() else: self.selected_project() def deselected(self): self.details.setText(DEFAULT_DETAILS) self.go.setDisabled(True) self.action = None def selected_project(self, *args): current = self.projects.currentItem() if not current: return key = current.text() project = self.projlist[key] tmpl = env.get_template('project_details.html') self.details.setText(tmpl.render(project=project)) self.go.setDisabled(False) self.action = partial(self.open_project, project) def selected_template(self, *args): current = self.templates.currentItem() if not current: return key = current.text() tmpl = env.get_template('template_details.html') project = next(p for p in PROJECTS if p.NAME == key) self.details.setText(tmpl.render(project=project)) self.go.setDisabled(False) self.action = partial(self.new_project, project) def perform_action(self): if not self.action: pass self.action() def new_project(self, project): dlg = QInputDialog() dlg.setLabelText("Please enter a name for your new %s project" % project.NAME) dlg.setOkButtonText("Create project") res = dlg.exec() if not res: return name = dlg.textValue() proj = self.projlist.init_project(name, project) self.main_window.add_project(proj) def open_project(self, proj): self.main_window.add_project(proj)
class SubwindowLiquipediaSearch(QWidget): """Show readme sub window.""" nams = dict() results = dict() data = dict() def createWindow(self, mainWindow, placeholder, team): """Create readme sub window.""" super().__init__(None) self.mainWindow = mainWindow self.controller = mainWindow.controller self.team = team self.liquipediaGrabber = LiquipediaGrabber() self.setWindowIcon(QIcon( scctool.settings.getResFile("liquipedia.png"))) self.setWindowModality(Qt.ApplicationModal) mainLayout = QGridLayout() self.qle_search = QLineEdit(placeholder) self.qle_search.setAlignment(Qt.AlignCenter) self.qle_search.returnPressed.connect(self.search) completer = QCompleter( scctool.settings.config.getMyTeams() + self.controller.historyManager.getTeamList(), self.qle_search) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) completer.setWrapAround(True) self.qle_search.setCompleter(completer) mainLayout.addWidget(self.qle_search, 0, 0, 1, 2) searchButton = QPushButton(_("Search")) searchButton.clicked.connect(self.search) mainLayout.addWidget(searchButton, 0, 2) self.box = QGroupBox(_("Results")) layout = QHBoxLayout() self.result_list = QListWidget() self.result_list.setViewMode(QListWidget.IconMode) self.result_list.itemDoubleClicked.connect(self.doubleClicked) self.result_list.setContextMenuPolicy(Qt.CustomContextMenu) self.result_list.customContextMenuRequested.connect( self.listItemRightClicked) self.result_list.setIconSize(QSize(75, 75)) # list.setWrapping(False) # list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.result_list.setAcceptDrops(False) self.result_list.setDragEnabled(False) layout.addWidget(self.result_list) self.box.setLayout(layout) mainLayout.addWidget(self.box, 1, 0, 1, 3) selectButton = QPushButton(" " + _("Use Selected Logo") + " ") selectButton.clicked.connect(self.applyLogo) closeButton = QPushButton(_("Cancel")) closeButton.clicked.connect(self.close) mainLayout.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum), 2, 0) mainLayout.addWidget(closeButton, 2, 1) mainLayout.addWidget(selectButton, 2, 2) self.setLayout(mainLayout) self.setWindowTitle(_("Liqupedia Image Search")) self.resize( QSize(mainWindow.size().width() * 0.9, self.sizeHint().height())) relativeChange = QPoint(mainWindow.size().width() / 2, mainWindow.size().height() / 3)\ - QPoint(self.size().width() / 2, self.size().height() / 3) self.move(mainWindow.pos() + relativeChange) def clean(self): self.nams.clear() self.results.clear() self.data.clear() def search(self): QApplication.setOverrideCursor(Qt.WaitCursor) self.clean() loading_map = QPixmap(scctool.settings.getResFile("loading.png")) try: self.result_list.clear() idx = 0 search_str = self.qle_search.text() for name, thumb in self.liquipediaGrabber.image_search(search_str): self.data[idx] = name name = name.replace('/commons/File:', '') self.results[idx] = QListWidgetItem(QIcon(loading_map), name) self.results[idx].setSizeHint(QSize(80, 90)) url = base_url + thumb self.nams[idx] = QNetworkAccessManager() self.nams[idx].finished.connect( lambda reply, i=idx: self.finishRequest(reply, i)) self.nams[idx].get(QNetworkRequest(QUrl(url))) self.result_list.addItem(self.results[idx]) if idx == 0: self.result_list.setCurrentItem(self.results[idx]) idx += 1 self.box.setTitle( _("Results for '{}': {}").format(search_str, idx)) except Exception as e: module_logger.exception("message") finally: QApplication.restoreOverrideCursor() def finishRequest(self, reply, idx): img = QImage() img.loadFromData(reply.readAll()) map = QPixmap(img).scaled(75, 75, Qt.KeepAspectRatio) self.results[idx].setIcon(QIcon(map)) def applyLogo(self, skip=False): item = self.result_list.currentItem() if item is not None and (skip or item.isSelected()): for idx, iteritem in self.results.items(): if item is iteritem: images = self.liquipediaGrabber.get_images(self.data[idx]) image = "" for size in sorted(images): if not image or size <= 600 * 600: image = images[size] self.downloadLogo(base_url + image) break self.close() def doubleClicked(self, item): for idx, iteritem in self.results.items(): if item is iteritem: images = self.liquipediaGrabber.get_images(self.data[idx]) image = "" for size in sorted(images): if not image or size <= 600 * 600: image = images[size] self.downloadLogo(base_url + image) break self.close() def listItemRightClicked(self, QPos): self.listMenu = QMenu() menu_item = self.listMenu.addAction(_("Open on Liquipedia")) menu_item.triggered.connect(self.openLiquipedia) menu_item = self.listMenu.addAction(_("Use as Team Logo")) menu_item.triggered.connect(lambda: self.applyLogo(True)) parentPosition = self.result_list.mapToGlobal(QPoint(0, 0)) self.listMenu.move(parentPosition + QPos) self.listMenu.show() def openLiquipedia(self): item = self.result_list.currentItem() for idx, iteritem in self.results.items(): if item is iteritem: url = base_url + self.data[idx] self.controller.openURL(url) break def downloadLogo(self, url): logo = LogoDownloader(self.controller, self, url).download() logo.refreshData() map = logo.provideQPixmap() if self.team == 1: self.controller.logoManager.setTeam1Logo(logo) self.mainWindow.team1_icon.setPixmap(map) self.mainWindow.refreshLastUsed() elif self.team == 2: self.controller.logoManager.setTeam2Logo(logo) self.mainWindow.team2_icon.setPixmap(map) self.mainWindow.refreshLastUsed() def closeEvent(self, event): """Handle close event.""" try: self.clean() event.accept() except Exception as e: module_logger.exception("message")
class ScientificBasisDialog(QDialog): """Creates a simple about dialog. The about dialog contains general information about the application and shows the copyright notice. That's why the class has no attributes or return values. """ def __init__(self): """The constructor initializes the class AboutDialog.""" super().__init__() self.setAttribute(Qt.WA_DeleteOnClose) # initialize class constants self._BUTTON_MIN_WIDTH = 110 self._OXYGEN_PATH_48 = os.path.join("resources", "icons", "oxygen", "48") # fonts and margins settings hlFont = QFont() hlFont.setBold(True) hlFont.setPointSize(14) # scientific logo logo = QLabel(pixmap=QPixmap(os.path.join(self._OXYGEN_PATH_48, "applications-science.png"))) logoLayout = QVBoxLayout() logoLayout.addWidget(logo) logoLayout.addStretch() # begin the content # headline and description text self.headline = QLabel() self.headline.setFont(hlFont) self.description = QLabel(wordWrap=True) # the list with the open button self.listWidget = QListWidget() self.listWidget.setMinimumWidth(420) self.createArticles() self.openButton = QPushButton() self.openButton.clicked.connect(self.openAction) listLayout = QHBoxLayout() listLayout.addWidget(self.listWidget) listLayout.addWidget(self.openButton, alignment=Qt.AlignTop) # create a close button line = QFrame(frameShadow=QFrame.Sunken, frameShape=QFrame.HLine) self.closeButton = QPushButton() self.closeButton.setFixedWidth(self._BUTTON_MIN_WIDTH) self.closeButton.clicked.connect(self.close) # content layout contentLayout = QVBoxLayout() contentLayout.addWidget(self.headline) contentLayout.addWidget(self.description) contentLayout.addLayout(listLayout) contentLayout.addWidget(line) contentLayout.addWidget(self.closeButton, alignment=Qt.AlignRight) # main layout layout = QHBoxLayout(self) layout.addLayout(logoLayout) layout.addLayout(contentLayout) # translate the graphical user interface self.retranslateUi() def createArticles(self): # load articles from library # and add them to the list for article in library.SCIENTIFIC_ARTICLES: # list widget item with it's data item = QListWidgetItem() item.setText(article[0].strip()) item.setData(Qt.UserRole, article[1].strip()) # add the item to the list widget self.listWidget.addItem(item) def openAction(self): # get the current item from list item = self.listWidget.currentItem() # create the documentation path with # the current locale settings articleFile = os.path.join("articles", item.data(Qt.UserRole)) # on every platfrom a different # start operation is needed if sys.platform == "win32": os.startfile(articleFile) elif sys.platform == "darwin": subprocess.call(("open", articleFile)) elif sys.platform.startswith("linux"): subprocess.call(("xdg-open", articleFile)) def retranslateUi(self): # dialog titel self.setWindowTitle(QApplication.translate("ScientificBasisDialog", "Specialist articles")) # Wissenschaftliche Grundlage # headline and description self.headline.setText(QApplication.translate("ScientificBasisDialog", "Specialist articles")) # Wissenschaftliche Beiträge self.description.setText(QApplication.translate("ScientificBasisDialog", "Hier finden Sie grundlegende Fachbeiträge zur Thematik") + ":") # buttons self.openButton.setText(QApplication.translate("ScientificBasisDialog", "Open article")) # Beitrag öffnen self.closeButton.setText(QApplication.translate("ScientificBasisDialog", "Close")) # Schließen
class ImportDialog(QDialog): def __init__(self, app): """ Init """ self.app = app super(ImportDialog, self).__init__() # define UI elements self.listOfProfiles = QListWidget(self) self.importButton = QPushButton(self) # initialize the UI self.init_ui() def init_ui(self): """ Initialize the actual UI :return: """ # Main window desktop = QDesktopWidget() screen_width = desktop.screen().width() screen_height = desktop.screen().height() app_width = 450 app_height = 375 self.setWindowTitle('Import profile') self.setGeometry( # this centers the window (screen_width / 2) - (app_width / 2), (screen_height / 2) - (app_height / 2), app_width, app_height) self.setFixedSize(self.size()) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # elements self.create_list_of_profiles() self.create_import_button() def create_list_of_profiles(self): """ Configure the list of profiles :return: """ self.listOfProfiles.setGeometry(20, 20, 410, 300) self.listOfProfiles.itemClicked.connect(self.enable_buttons) self.load_profiles() def create_import_button(self): """ Configure the save button :return: """ self.importButton.setGeometry(351, 325, 80, 30) self.importButton.setText('Import') self.importButton.setDisabled(True) self.importButton.clicked.connect(self.on_import) def load_profiles(self): """ Load mods into the list :param mods: :return: """ self.listOfProfiles.clear() for m in self.get_available_profiles(): # change the name to avoid conflicts - overwriting might cause problems if self.app.db.profile_exists(m[0]): m[0] = '{} ({})'.format(m[0], datetime.datetime.now()) item = QListWidgetItem() item.setText(m[0]) item.setData(Qt.UserRole, m[1]) self.listOfProfiles.addItem(item) self.listOfProfiles.sortItems(Qt.AscendingOrder) @staticmethod def get_available_profiles(): profiles = [] for p in os.listdir('profiles'): f = open('profiles/' + p, 'r') profiles.append(json.loads(f.read())) f.close() return profiles def enable_buttons(self): self.importButton.setEnabled(True) def on_import(self): """ Insert the profile into database :return: """ item = self.listOfProfiles.currentItem() # type: QListWidgetItem mods = json.dumps(item.data(Qt.UserRole)) self.app.db.save_mods(item.text(), mods) item.setFlags(item.flags() & ~Qt.ItemIsSelectable) item.setText(item.text() + ' *IMPORTED*') self.app.load_profiles()
class MikochikuAlarm(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.search_ch_id = "UC-hM6YJuNYVAmUWxeIr9FeA" self.ch_dic = { "ときのそら": "UCp6993wxpyDPHUpavwDFqgg", "AZKi": "UC0TXe_LYZ4scaW2XMyi5_kw", "ロボ子さん": "UCDqI2jOz0weumE8s7paEk6g", "さくらみこ": "UC-hM6YJuNYVAmUWxeIr9FeA", "白上フブキ": "UCdn5BQ06XqgXoAxIhbqw5Rg", "夏色まつり": "UCQ0UDLQCjY0rmuxCDE38FGg", "夜空メル": "UCD8HOxPs4Xvsm8H0ZxXGiBw", "赤井はあと": "UC1CfXB_kRs3C-zaeTG3oGyg", "アキ・ローゼンタール": "UCFTLzh12_nrtzqBPsTCqenA", "湊あくあ": "UC1opHUrw8rvnsadT-iGp7Cg", "癒月ちょこ": "UC1suqwovbL1kzsoaZgFZLKg", "百鬼あやめ": "UC7fk0CB07ly8oSl0aqKkqFg", "紫咲シオン": "UCXTpFs_3PqI41qX2d9tL2Rw", "大空スバル": "UCvzGlP9oQwU--Y0r9id_jnA", "大神ミオ": "UCp-5t9SrOQwXMU7iIjQfARg", "猫又おかゆ": "UCvaTdHTWBGv3MKj3KVqJVCw", "戌神ころね": "UChAnqc_AY5_I3Px5dig3X1Q", "不知火フレア": "UCvInZx9h3jC2JzsIzoOebWg", "白銀ノエル": "UCdyqAaZDKHXg4Ahi7VENThQ", "宝鐘マリン": "UCCzUftO8KOVkV4wQG1vkUvg", "兎田ぺこら": "UC1DCedRgGHBdm81E1llLhOQ", "潤羽るしあ": "UCl_gCybOJRIgOXw6Qb4qJzQ", "星街すいせい": "UC5CwaMl1eIgY8h02uZw7u8A", "天音かなた": "UCZlDXzGoo7d44bwdNObFacg", "桐生ココ": "UCS9uQI-jC3DE0L4IpXyvr6w", "角巻わため": "UCqm3BQLlJfvkTsX_hvm0UmA", "常闇トワ": "UC1uv2Oq6kNxgATlCiez59hw", "姫森ルーナ": "UCa9Y57gfeY0Zro_noHRVrnw" } self.old_video_id_list = [] self.initUI() def initUI(self): self.timer = QTimer(self) self.timer.timeout.connect(self.check_live) self.timer.setInterval(5000) self.timer.start() label = QLabel(self) label.setPixmap(QPixmap(resource_path("icon.ico"))) label.move(60, 70) self.alarm_cb = QCheckBox('配信が始まったらアラームを鳴らす', self) self.alarm_cb.move(20, 20) self.alarm_cb.toggle() # self.loop_cb = QCheckBox('アラームをループ再生する', self) # self.loop_cb.move(20, 40) # self.loop_cb.toggle() self.webbrowser_cb = QCheckBox('配信が始まったら自動でブラウザを開く', self) self.webbrowser_cb.move(20, 40) self.webbrowser_cb.toggle() self.alarm_stop = QPushButton("待機中", self) # self.alarm_stop.setCheckable(True) # self.alarm_stop.setEnabled(False) self.alarm_stop.move(80, 360) self.alarm_stop.clicked[bool].connect(self.stop_alarm) self.listWidget = QListWidget(self) self.listWidget.resize(300, 150) self.listWidget.addItem("ときのそら") self.listWidget.addItem("AZKi") self.listWidget.addItem("ロボ子さん") self.listWidget.addItem("さくらみこ") self.listWidget.addItem("白上フブキ") self.listWidget.addItem("夏色まつり") self.listWidget.addItem("夜空メル") self.listWidget.addItem("赤井はあと") self.listWidget.addItem("アキ・ローゼンタール") self.listWidget.addItem("湊あくあ") self.listWidget.addItem("癒月ちょこ") self.listWidget.addItem("百鬼あやめ") self.listWidget.addItem("紫咲シオン") self.listWidget.addItem("大空スバル") self.listWidget.addItem("大神ミオ") self.listWidget.addItem("猫又おかゆ") self.listWidget.addItem("戌神ころね") self.listWidget.addItem("不知火フレア") self.listWidget.addItem("白銀ノエル") self.listWidget.addItem("宝鐘マリン") self.listWidget.addItem("兎田ぺこら") self.listWidget.addItem("潤羽るしあ") self.listWidget.addItem("星街すいせい") self.listWidget.addItem("天音かなた") self.listWidget.addItem("桐生ココ") self.listWidget.addItem("角巻わため") self.listWidget.addItem("常闇トワ") self.listWidget.addItem("姫森ルーナ") self.listWidget.move(30, 200) self.listWidget.itemClicked.connect(self.clicked) self.setGeometry(300, 300, 400, 400) self.setWindowTitle('みこ畜アラーム') self.show() def clicked(self, qmodelindex): self.search_ch_id = self.ch_dic[self.listWidget.currentItem().text()] def check_live(self): buff_video_id_set = self.get_live_video_id(self.search_ch_id) print(self.listWidget.selectedIndexes()) if self.listWidget.selectedIndexes() is None: print("aaaa") self.search_ch_id = "" if buff_video_id_set: for getting_video_id in buff_video_id_set: if not getting_video_id == "" and not getting_video_id is None: if not getting_video_id in self.old_video_id_list: self.old_video_id_list.append(getting_video_id) if len(self.old_video_id_list) > 30: self.old_video_id_list = self.old_video_id_list[1:] print("") print("配信が始まりました") # self.alarm_stop.setEnabled(False) self.alarm_stop.click() self.alarm_stop.setText("ストップ") if self.webbrowser_cb.checkState(): webbrowser.open( "https://www.youtube.com/watch?v=" + getting_video_id) if self.alarm_cb.checkState(): self.alarm_sound() def stop_alarm(self): pygame.mixer.music.stop() self.alarm_stop.setEnabled(True) self.alarm_stop.setText("待機中") def alarm_sound(self): # loop = 1 # if self.loop_cb.checkState(): loop_count = 5 pygame.mixer.music.play(loop_count) pygame.mixer.music.play(loop_count) def get_live_video_id(self, search_ch_id): dict_str = "" video_id_set = set() try: session = requests.Session() headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36' } html = session.get("https://www.youtube.com/channel/" + search_ch_id, headers=headers, timeout=10) soup = BeautifulSoup(html.text, 'html.parser') keyword = 'window["ytInitialData"]' for scrp in soup.find_all("script"): if keyword in str(scrp): dict_str = str(scrp).split(' = ', 1)[1] dict_str = dict_str.replace('false', 'False') dict_str = dict_str.replace('true', 'True') index = dict_str.find("\n") dict_str = dict_str[:index - 1] dics = eval(dict_str) for section in dics.get("contents", {}).get( "twoColumnBrowseResultsRenderer", {}).get("tabs", {})[0].get("tabRenderer", {}).get("content", {}).get("sectionListRenderer", {}).get("contents", {}): for itemsection in section.get("itemSectionRenderer", {}).get("contents", {}): items = {} if "shelfRenderer" in itemsection: for items in itemsection.get("shelfRenderer", {}).get("content", {}).values(): for item in items.get("items", {}): for videoRenderer in item.values(): for badge in videoRenderer.get( "badges", {}): if badge.get( "metadataBadgeRenderer", {}).get( "style", {} ) == "BADGE_STYLE_TYPE_LIVE_NOW": video_id_set.add( videoRenderer.get( "videoId", "")) elif "channelFeaturedContentRenderer" in itemsection: for item in itemsection.get( "channelFeaturedContentRenderer", {}).get("items", {}): for badge in item.get("videoRenderer", {}).get("badges", {}): if badge.get("metadataBadgeRenderer", {}).get( "style", "") == "BADGE_STYLE_TYPE_LIVE_NOW": video_id_set.add( item.get("videoRenderer", {}).get("videoId", "")) except: return video_id_set return video_id_set
class MainWin(QMainWindow): lis = None img = None lay = None button = None edge_cut_text_field = None edge_cut_label = None blur_radius_text_field = None def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.lay = QHBoxLayout() self.setLayout(self.lay) self.statusBar().showMessage('Ready') self.setGeometry(100, 100, 900, 900) self.setMinimumSize(500, 500) self.setWindowTitle('Gluten Free Radioactive Green Beans') self.init_file_menu() self.init_list_view() self.init_image_viewer() self.init_text_fields() self.button = QPushButton("Process Image", self) self.button.setToolTip("This will process the given image and save it.") self.button.move(200, 850) self.button.clicked.connect(self.process_button_pressed) self.show() def init_image_viewer(self): self.img = QLabel(self) self.img.resize(800,800) self.img.move(200,20) self.lay.addWidget(self.img) def init_list_view(self): self.lis=QListWidget(self) self.lis.move(0, 20) self.lis.currentItemChanged.connect(self.list_selection_changed) self.lay.addWidget(self.lis) def init_file_menu(self): exit_item = QAction('&Exit', self) exit_item.setShortcut('Ctrl+Q') exit_item.setStatusTip('Exit Application') exit_item.triggered.connect(qApp.quit) import_item = QAction('&Import', self) import_item.setShortcut('Ctrl+I') import_item.triggered.connect(self.import_action) menubar = self.menuBar() file_menu = menubar.addMenu('&File') file_menu.addAction(import_item) file_menu.addAction(exit_item) def init_text_fields(self): self.edge_cut_text_field = QLineEdit(self) self.edge_cut_text_field.resize(50,24) self.edge_cut_text_field.textChanged.connect(self.edge_cut_changed) self.edge_cut_label = QLabel(self) self.edge_cut_label.setText("Edge Cut") self.edge_cut_label.resize(50,24) def edge_cut_changed(self): ld.set_preproc_edge_cut(int(self.edge_cut_text_field.text())) def import_action(self): filepath = self.show_import_folder_dialog() if(filepath == ''): return file_list = ld.clean_file_list(ld.get_files_in(filepath)) self.lis.addItems(file_list) def show_import_folder_dialog(self): options = QFileDialog.Options() return QFileDialog.getExistingDirectory(self,"QFileDialog.getOpenFileName()", options=options) def resizeEvent(self,event): self.respond_to_resize() def respond_to_resize(self): self.lis.setGeometry(0, 20, self.frameGeometry().width() // 5, self.frameGeometry().height() - 80) self.button.move(self.frameGeometry().width() // 5, 850) self.img.move(self.frameGeometry().width() // 5, 20) self.edge_cut_text_field.move((self.frameGeometry().width() // 4) + 150, 850) self.edge_cut_label.move(self.frameGeometry().width()//4 + 100 , 850) def list_selection_changed(self): if(self.lis.currentItem() == None): return qpm = QPixmap(self.lis.currentItem().text()) self.img.resize(qpm.width(),qpm.height()) self.img.setPixmap(qpm) QApplication.processEvents() def process_button_pressed(self): self.process_image() def process_image(self): if(self.lis.currentItem() == None): return current_selection = self.lis.currentItem().text() ld.process_image(current_selection) filepath = current_selection[:current_selection.rfind('/')] file_list = ld.clean_file_list(ld.get_files_in(filepath)) self.lis.clear() self.lis.addItems(file_list)
class window(QtWidgets.QMainWindow): def __init__(self): super(window,self).__init__() self.currentlocal=0 self.data=None self.checker=0 self.lastcolored=0 self.photo = QLabel(self) self.port=0 self.pixmap = QPixmap('photo.png') self.pixmap = self.pixmap.scaled(600, 300, QtCore.Qt.KeepAspectRatio) self.photo.setPixmap(self.pixmap) self.labelgif=QLabel(self) self.labelgif.setStyleSheet("QLabel { background-color : white;}"); self.labelgif.setGeometry(100,50,500,430) self.movie = QtGui.QMovie('data.gif', QtCore.QByteArray(),self.labelgif) self.movie.setSpeed(100) self.labelgif.setMovie(self.movie) self.movie.start() self.labelgif.setVisible(False) self.labelyazi=QLabel(self) self.labelgif1=QLabel(self) self.labelgif1.setStyleSheet("QLabel { background-color : white;}") self.labelyazi.setText('G'+"\u00F6"+"zl"+"\u0259"+"yin..") font1=QtGui.QFont('Times',17) self.labelyazi.setFont(font1) self.labelyazi.setVisible(False) self.labelyazi.setGeometry(350,150,150,60) self.labelgif1.setGeometry(150,100,489,289) self.movie1 = QtGui.QMovie('wait.gif', QtCore.QByteArray(),self.labelgif1) self.movie1.setSpeed(100) self.labelgif1.setMovie(self.movie1) self.movie1.start() self.labelgif1.setVisible(False) self.setWindowTitle("Diplom i\u015Fi v1") self.setWindowIcon(QtGui.QIcon('pyicon.png')) self.button = QPushButton('PyQt5 button', self)#button yaradildi self.listw=QListWidget(self)#listWidget yaradildi self.button1=QPushButton(self) self.buttonlocal=QPushButton(self) self.buttonlocal.setText('Qo\u015F') self.button1.setText("Temperaturu"+" " +"\u00F6"+"l"+"\u00E7") self.dial=QDial(self) self.lcd=QLCDNumber(self) self.label=QLabel(self) self.labelrefresh=QLabel(self) self.obj=[] self.listCOM=QListWidget(self) self.spin=QSpinBox(self) self.radiosan=QRadioButton(self) self.radiosan.setText("Saniy"+"\u0259") self.radiodeq=QRadioButton(self) self.radiodeq.setText("D"+"\u0259"+"qiq"+"\u0259") self.starting() self.initUI() def initUI(self): self.setFixedSize(700,500) self.dial.setNotchesVisible(True) self.labelrefresh.setText('Yenil\u0259m\u0259k \u00FC\u00E7\u00FCn F5 d\u00FCym\u0259sini s\u0131x\u0131n ') self.labelrefresh.setStyleSheet("QLabel{background-color: yellow; }") font=QtGui.QFont('Times',10,QtGui.QFont.Bold) self.labelrefresh.setFont(font) self.lcd.setVisible(False) self.photo.setVisible(False) self.photo.raise_() self.labelgif.raise_() self.labelgif1.raise_() self.labelyazi.raise_() self.spin.setRange(1,60) self.dial.setRange(1,60) self.button.setText("\u015E"+"\u0259"+"b\u0259k\u0259ni yoxla") self.button1.setEnabled(False) self.button.setEnabled(False) self.spin.setEnabled(False) self.dial.setEnabled(False) self.radiosan.setEnabled(False) self.radiodeq.setEnabled(False) self.label.setText('Qo\u015Fulmu'+'\u015F cihaz yoxdur') self.label.setStyleSheet("QLabel { background-color : #e20000; color : black; }"); newfont = QtGui.QFont('Times',11) self.label.setFont(newfont) #geometries self.setGeometry(40,50,700,500) self.button.setGeometry(20,40,120,50) self.listw.setGeometry(380,160,300,200) self.button1.setGeometry(575,40,120,50) self.dial.setGeometry(40,400,75,70) self.spin.setGeometry(150,425,50,25) self.radiosan.setGeometry(150,400,75,25) self.radiodeq.setGeometry(150,380,75,25) self.lcd.setGeometry(300,40,100,50) self.buttonlocal.setGeometry(150,40,125,50) self.label.setGeometry(520,440,155,30) self.listCOM.setGeometry(20,160,300,200) self.labelrefresh.setGeometry(20,100,220,30) self.photo.setGeometry(50,100,600,300) #events self.buttonlocal.clicked.connect(self.checklocal) self.button.clicked.connect(self.thread1) self.button.clicked.connect(self.threadnetwork) self.dial.valueChanged.connect(self.spin.setValue) self.spin.valueChanged.connect(self.dial.setValue) self.listCOM.doubleClicked.connect(self.showdialog) self.listw.doubleClicked.connect(self.showdialogremote) self.button1.clicked.connect(self.thread) # communication self.radiodeq.clicked.connect(self.spinvalue) self.radiosan.clicked.connect(self.dialvalue) self.button1.clicked.connect(self.threadback) def threadback(self): if self.radiodeq.isChecked() or self.radiosan.isChecked(): self.thread1=threading.Thread(target=self.send) self.thread1.start() else: pass def loading(self): m=loading() def send(self): try: self.currentlocal.open() remotestr=self.listw.currentItem().text() li=remotestr.split("-") xbee_network=self.currentlocal.get_network() remote=xbee_network.get_device_by_64(XBee64BitAddress.from_hex_string(li[0])) arr_64=self.currentlocal.get_64bit_addr() NEW_TIMEOUT_FOR_SYNC_OPERATIONS = 1 self.currentlocal.set_sync_ops_timeout(NEW_TIMEOUT_FOR_SYNC_OPERATIONS) if self.radiosan.isChecked(): self.currentlocal.send_data(remote,str(arr_64)+"-"+str(self.spin.value())) else: self.currentlocal.send_data(remote,str(arr_64)+"-"+str(self.spin.value()*60)) self.labelgif1.setVisible(False) self.labelgif1.setVisible(True) self.labelyazi.setVisible(True) while(True): self.data=self.currentlocal.read_data() if(self.data!=None): self.data=self.data.data.decode() self.labelgif1.setVisible(False) self.labelyazi.setVisible(False) break self.currentlocal.close() data_list=self.data.split(',') self.labelgif.setVisible(True) objects = [] performance=[] for i in range(1,len(data_list)): objects.append(i) for i in range(len(data_list)-1): li=data_list[i] li=li.split('-') performance.append(li[1]) y_pos = np.arange(len(objects)) objects=tuple(objects) plt.figure("Qrafik") plt.xticks(y_pos, objects) plt.ylabel('Temperatur') plt.xlabel('Zaman') plt.plot(y_pos,performance) self.labelgif.setVisible(False) plt.show() self.data=None except: print('salam') self.currentlocal.close() def showdialog(self): try: li=self.listCOM.currentItem().text().split('-') local=XBeeDevice(li[2],9600) local.open() arr_64=local.get_64bit_addr() arr_16=local.get_16bit_addr() arr_node=local.get_node_id() arr_pro=local.get_protocol() arr_hard=local.get_hardware_version() local.close() dlg=dialog(arr_64,arr_16,arr_node,arr_pro,arr_hard) except: pass #exception def showdialogremote(self): li=self.listw.currentItem().text().split('-') if self.checker !=0: self.lastcolored.setBackground(QtGui.QColor(255,255,255)) self.lastcolored=self.listw.currentItem() self.listw.currentItem().setBackground(QtGui.QColor(239, 255, 25)) try: self.currentlocal.open() xbee_network=self.currentlocal.get_network() remote=xbee_network.get_device_by_64(XBee64BitAddress.from_hex_string(li[0])) arr_64=remote.get_64bit_addr() arr_16=remote.get_16bit_addr() arr_node=remote.get_node_id() arr_pro=remote.get_protocol() arr_hard=remote.get_hardware_version() self.currentlocal.close() dlg=dialog(arr_64,arr_16,arr_node,arr_pro,arr_hard) self.checker=1 except: pass # exception def spinvalue(self): self.dial.setRange(1,60) self.spin.setRange(1,60) self.dial.setValue(1) def dialvalue(self): self.dial.setRange(4,60) self.spin.setRange(4,60) self.dial.setValue(4) def keyPressEvent(self, event): key = event.key() if key == QtCore.Qt.Key_F5: self.threadrefresh() def checklocal(self): try: if (self.currentlocal !=0): for i in range(0,self.listCOM.count()): self.listCOM.item(i).setBackground(QtGui.QColor(255, 255, 255)) self.listCOM.currentItem().setBackground(QtGui.QColor(97, 255, 66)) li=self.listCOM.currentItem().text().split('-') self.currentlocal = XBeeDevice(li[2], 9600) self.port=li[2] self.currentCOM=self.listCOM.currentItem().text() self.currentlocal.open() self.currentlocal.close() self.listw.clear() self.button1.setEnabled(True) self.button.setEnabled(True) self.spin.setEnabled(True) self.dial.setEnabled(True) self.radiosan.setEnabled(True) self.radiodeq.setEnabled(True) if platform.system()=='Linux': self.label.setGeometry(500,440,180,30) self.label.setText('Qo\u015Fulmu'+'\u015F port: '+str(li[2])) self.checker=0 self.label.setStyleSheet("QLabel { background-color : #22ce00; color : white; }") except: QMessageBox.about(self, 'Yanl\u0131\u015F', 'Lokal cihaz\u0131n portu do\u011Fru deyil') def refresh(self): self.listCOM.clear() index=0 if platform.system()=='Windows': for i in range(0,257): try: local_xbee = XBeeDevice('COM'+str(i), 9600) local_xbee.open() addr64=local_xbee.get_64bit_addr() noid=local_xbee.get_node_id() local_xbee.close() self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'COM'+str(i)) if(self.port=='COM'+str(i)): self.listCOM.item(index).setBackground(QtGui.QColor(97, 255, 66)) index+=1 except: pass elif platform.system()=='Linux': for i in range(257): try: local_xbee = XBeeDevice('/dev/ttyUSB'+str(i), 9600) local_xbee.open() addr64=local_xbee.get_64bit_addr() noid=local_xbee.get_node_id() local_xbee.close() self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'/dev/ttyUSB'+str(i)) if(self.port=='/dev/ttyUSB'+str(i)): self.listCOM.item(index).setBackground(QtGui.QColor(97, 255, 66)) index+=1 except: pass self.checker=0 def thread(self): if self.radiodeq.isChecked() or self.radiosan.isChecked(): self.thread=threading.Thread(target=self.timing) self.thread.start() else: QMessageBox.about(self, 'Yanl\u0131\u015F', 'Zaman vahidini se\u00E7in') def thread1(self): if self.radiodeq.isChecked() or self.radiosan.isChecked(): self.thread1=threading.Thread(target=self.scan) self.thread1.start() else: QMessageBox.about(self, 'Yanl\u0131\u015F', 'Zaman vahidini se\u00E7in') def threadnetwork(self): if self.radiodeq.isChecked() or self.radiosan.isChecked(): self.thread1=threading.Thread(target=self.network) self.thread1.start() else: pass def network(self): try: self.button1.setEnabled(False) self.buttonlocal.setEnabled(False) self.button.setEnabled(False) self.button1.setEnabled(False) self.spin.setEnabled(False) self.dial.setEnabled(False) self.radiosan.setEnabled(False) self.radiodeq.setEnabled(False) self.listw.clear() self.currentlocal.open() xbee_network=self.currentlocal.get_network() xbee_network.clear() listdev=[] def callback_device_discovered(remote): listdev.append(str(remote)) if self.radiosan.isChecked(): if(self.spin.value()>25): defe=int((self.spin.value())/25) qaliqsan=(self.spin.value())%25 for i in range(0,defe): xbee_network.set_discovery_timeout(22) xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) if(qaliqsan<4): add=q=4-qaliqsan xbee_network.set_discovery_timeout(qaliqsan+add) xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) else: xbee_network.set_discovery_timeout(qaliqsan) xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) self.currentlocal.close() else: xbee_network.set_discovery_timeout(self.spin.value()) xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) self.currentlocal.close() self.photo.setVisible(True) listdev=list(set(listdev)) for i in range(0,len(listdev)): self.listw.addItem(listdev[i]) QtCore.QThread.msleep(1000) self.photo.setEnabled(True) self.buttonlocal.setEnabled(True) self.button1.setEnabled(True) self.button.setEnabled(True) self.spin.setEnabled(True) self.dial.setEnabled(True) self.radiosan.setEnabled(True) self.radiodeq.setEnabled(True) self.photo.setVisible(False) if self.radiodeq.isChecked(): defe=int((self.spin.value()*60)/25) qaliqsan=(self.spin.value()*60)%25 for i in range(0,defe): xbee_network.set_discovery_timeout(22) # 24 seconds + saniye elave. xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) xbee_network.set_discovery_timeout(qaliqsan) # qaliq saniye. xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) self.currentlocal.close() else: xbee_network.set_discovery_timeout(self.spin.value()) # qaliq saniye xbee_network.add_device_discovered_callback(callback_device_discovered) xbee_network.start_discovery_process() while xbee_network.is_discovery_running(): QtCore.QThread.msleep(100) self.currentlocal.close() self.photo.setVisible(True) listdev=list(set(listdev)) for i in range(0,len(listdev)): self.listw.addItem(listdev[i]) QtCore.QThread.msleep(2000) self.buttonlocal.setEnabled(True) self.button1.setEnabled(True) self.button.setEnabled(True) self.spin.setEnabled(True) self.dial.setEnabled(True) self.radiosan.setEnabled(True) self.radiodeq.setEnabled(True) self.photo.setVisible(False) except: self.currentlocal.close() def threadrefresh(self): t=threading.Thread(target=self.refresh) t.start() #UI has been finished def timing(self): QtCore.QThread.msleep(1000) self.button1.setEnabled(False) if(self.radiodeq.isChecked()): self.lcd.setVisible(True) j=self.spin.value()*60 k=self.spin.value() if(k<10): self.lcd.display("0{}:00".format(k)) QtCore.QThread.msleep(1000) else: self.lcd.display("{}:00".format(k)) QtCore.QThread.msleep(1000) j-=1 k-=1 while(j>-1): if(k<10): if(j%60<10): if(j%60 is 0): self.lcd.display("0{}:0{}".format(k,j%60)) k-=1 j-=1 QtCore.QThread.msleep(1000) continue self.lcd.display("0{}:0{}".format(k,j%60)) app.processEvents() QtCore.QThread.msleep(1000) j-=1 else: self.lcd.display("0{}:{}".format(k,j%60)) QtCore.QThread.msleep(1000) j-=1 else: if(j%60 is 0): self.lcd.display("0{}:0{}".format(k,j%60)) k-=1 j-=1 QtCore.QThread.msleep(1000) continue if(j%60<10): self.lcd.display("{}:0{}".format(k,j%60)) QtCore.QThread.msleep(1000) j-=1 else: self.lcd.display("{}:{}".format(k,j%60)) QtCore.QThread.msleep(1000) j-=1 self.lcd.setVisible(False) self.button1.setEnabled(True) elif (self.radiosan.isChecked()): self.lcd.setVisible(True) timing=self.spin.value() for i in range(timing,-1,-1): if(i<10): self.lcd.display("00:0{}".format(i)) QtCore.QThread.msleep(1000) else: self.lcd.display("00:{}".format(i)) QtCore.QThread.msleep(1000) self.lcd.setVisible(False) self.button1.setEnabled(True) def starting(self): splash=QtWidgets.QSplashScreen(QtGui.QPixmap('splash.jpg'),QtCore.Qt.WindowStaysOnTopHint) splash.show() for i in range(0,257): app.processEvents() if (i is 50): splash.showMessage("<h1><font color=#608fdb>Proqram başladılır!</font></h1>", QtCore.Qt.AlignTop) QtCore.QThread.msleep(1000) try: if (platform.system() == 'Windows'): local_xbee = XBeeDevice('COM'+str(i), 9600) local_xbee.open() addr64=local_xbee.get_64bit_addr() noid=local_xbee.get_node_id() local_xbee.close() self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'COM'+str(i)) elif (platform.system() == 'Linux'): local_xbee = XBeeDevice('/dev/ttyUSB'+str(i), 9600) local_xbee.open() addr64=local_xbee.get_64bit_addr() noid=local_xbee.get_node_id() local_xbee.close() self.listCOM.addItem(str(addr64)+"-"+str(noid)+"-"+'/dev/ttyUSB'+str(i)) except: pass splash.close() def createlistw(self): self.listw.clear() for i in range(0,9): self.obj.append(i) self.obj[i]=elements() self.obj[i].t=[10,20,30,40,2,3,4,5,6] self.obj[i].s=[5,6,7,8,9,1,2,3,4,5,88] self.listw.addItem(str(self.obj[i].t[i])) def scan(self): self.button.setEnabled(False) if(self.radiodeq.isChecked()): self.lcd.setVisible(True) j=self.spin.value()*60 k=self.spin.value() if(k<10): self.lcd.display("0{}:00".format(k)) QtCore.QThread.msleep(1000) else: self.lcd.display("{}:00".format(k)) QtCore.QThread.msleep(1000) j-=1 k-=1 while(j>-1): if(k<10): if(j%60<10): if(j%60 is 0): self.lcd.display("0{}:0{}".format(k,j%60)) k-=1 j-=1 QtCore.QThread.msleep(1000) continue self.lcd.display("0{}:0{}".format(k,j%60)) app.processEvents() QtCore.QThread.msleep(1000) j-=1 else: self.lcd.display("0{}:{}".format(k,j%60)) QtCore.QThread.msleep(1000) j-=1 else: if(j%60 is 0): self.lcd.display("0{}:0{}".format(k,j%60)) k-=1 j-=1 QtCore.QThread.msleep(1000) continue if(j%60<10): self.lcd.display("{}:0{}".format(k,j%60)) QtCore.QThread.msleep(1000) j-=1 else: self.lcd.display("{}:{}".format(k,j%60)) QtCore.QThread.msleep(1000) j-=1 self.lcd.setVisible(False) self.button.setEnabled(True) elif (self.radiosan.isChecked()): self.lcd.setVisible(True) timing=self.spin.value() for i in range(timing,-1,-1): if(i<10): self.lcd.display("00:0{}".format(i)) QtCore.QThread.msleep(1000) else: self.lcd.display("00:{}".format(i)) QtCore.QThread.msleep(1000) self.lcd.setVisible(False) self.button.setEnabled(True)
class PostProcessor(QMainWindow): sim_results_changed = pyqtSignal() post_results_changed = pyqtSignal() figures_changed = pyqtSignal(list, str) def __init__(self, parent=None): QMainWindow.__init__(self, parent) self._settings = QSettings() self._logger = logging.getLogger(self.__class__.__name__) self.setWindowTitle("Processing") self.setWindowIcon(QIcon(get_resource("processing.png"))) self.mainFrame = QWidget(self) self.resize(1000, 600) # toolbar self.toolBar = QToolBar("file control") self.toolBar.setIconSize(QSize(24, 24)) self.addToolBar(self.toolBar) self.actLoad = QAction(self) self.actLoad.setText("load result file") self.actLoad.setIcon(QIcon(get_resource("load.png"))) self.actLoad.setDisabled(False) self.actLoad.triggered.connect(self.load_result_files) self.actPostLoad = QAction(self) self.actPostLoad.setText("load post-result file") self.actPostLoad.setIcon(QIcon(get_resource("load.png"))) self.actPostLoad.setDisabled(False) self.actPostLoad.triggered.connect(self.load_post_result_files) self.actSwitch = QAction(self) self.actSwitch.setText("switch display mode") self.actSwitch.setIcon(QIcon(get_resource("left_mode.png"))) self.actSwitch.setDisabled(False) self.actSwitch.triggered.connect(self.switch_sides) self.displayLeft = True self.spacer1 = QWidget() self.spacer2 = QWidget() self.spacer1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.actReloadMethods = QAction(self) self.actReloadMethods.setText("reload methods") self.actReloadMethods.setIcon(QIcon(get_resource("reload.png"))) self.actReloadMethods.setDisabled(False) self.actReloadMethods.triggered.connect(self.update_post_method_list) self.actReloadMetaMethods = QAction(self) self.actReloadMetaMethods.setText("reload meta methods") self.actReloadMetaMethods.setIcon(QIcon(get_resource("reload.png"))) self.actReloadMetaMethods.setDisabled(False) self.actReloadMetaMethods.triggered.connect( self.update_meta_method_list) self.toolBar.addAction(self.actLoad) self.toolBar.addAction(self.actReloadMethods) self.toolBar.addWidget(self.spacer1) self.toolBar.addAction(self.actSwitch) self.toolBar.addWidget(self.spacer2) self.toolBar.addAction(self.actReloadMetaMethods) self.toolBar.addAction(self.actPostLoad) # main window self.grid = QGridLayout(self.mainFrame) self.grid.setColumnMinimumWidth(0, 70) self.grid.setColumnStretch(0, 0) self.grid.setColumnStretch(1, 1) self.methodList = QListWidget(self) self.methodList.itemDoubleClicked.connect( self.post_processor_clicked) self.update_post_method_list() self.metaMethodList = QListWidget(self) self.metaMethodList.itemDoubleClicked.connect( self.meta_processor_clicked) self.update_meta_method_list() self.sim_result_list = QListWidget(self) self.sim_results_changed.connect(self.update_result_list) self.results = [] self.delShort = QShortcut(QKeySequence(Qt.Key_Delete), self.sim_result_list) self.delShort.activated.connect(self.remove_result_item) # figures self._figure_dict = {} self.figures_changed.connect(self.update_figure_lists) self.post_figure_list = QListWidget(self) self.post_figure_list.currentItemChanged.connect( self.current_figure_changed) self.meta_figure_list = QListWidget(self) self.meta_figure_list.currentItemChanged.connect( self.current_figure_changed) self.plotView = QWidget() self.lastFigure = None self.post_result_list = QListWidget(self) self.post_results_changed.connect(self.update_post_result_list) self.post_results = [] self.delShortPost = QShortcut(QKeySequence(Qt.Key_Backspace), self.post_result_list) self.delShortPost.activated.connect(self.remove_post_result_item) # log dock self.logBox = QPlainTextEdit(self) self.logBox.setReadOnly(True) # init logger for logging box self.textLogger = PlainTextLogger(logging.INFO) self.textLogger.set_target_cb(self.logBox.appendPlainText) logging.getLogger().addHandler(self.textLogger) self.grid.addWidget(QLabel("Result Files:"), 0, 0) self.grid.addWidget(self.sim_result_list, 1, 0) self.grid.addWidget(QLabel("Postprocessors:"), 2, 0) self.grid.addWidget(self.methodList, 3, 0) self.grid.addWidget(QLabel("Figures:"), 4, 0) self.grid.addWidget(self.post_figure_list, 5, 0) self.grid.addWidget(QLabel("Selected Figure:"), 0, 1) self.grid.addWidget(QLabel("Postprocessor Files:"), 0, 2) self.grid.addWidget(self.post_result_list, 1, 2) self.grid.addWidget(QLabel("Metaprocessors:"), 2, 2) self.grid.addWidget(self.metaMethodList, 3, 2) self.grid.addWidget(QLabel("Figures:"), 4, 2) self.grid.addWidget(self.meta_figure_list, 5, 2) self.grid.addWidget(self.logBox, 6, 0, 1, 3) self.mainFrame.setLayout(self.grid) self.setCentralWidget(self.mainFrame) # status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) def load_result_files(self): path = self._settings.value("path/simulation_results") dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFiles) dialog.setDirectory(path) dialog.setNameFilter("PyMoskito Result files (*.pmr)") if dialog.exec_(): files = dialog.selectedFiles() for single_file in files: if single_file: self._load_result_file(single_file) def _load_result_file(self, file_name): """ loads a result file """ self._logger.info("loading result file {}".format(file_name)) with open(file_name.encode(), "rb") as f: self.results.append(pickle.load(f)) self.sim_results_changed.emit() def update_result_list(self): self.sim_result_list.clear() for res in self.results: name = res["regime name"] self.sim_result_list.addItem(name) def remove_result_item(self): if self.sim_result_list.currentRow() >= 0: del self.results[self.sim_result_list.currentRow()] self.sim_result_list.takeItem(self.sim_result_list.currentRow()) def load_post_result_files(self): path = self._settings.value("path/processing_results") dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFiles) dialog.setDirectory(path) dialog.setNameFilter("Postprocessing Output files (*.pof)") if dialog.exec_(): files = dialog.selectedFiles() for single_file in files: if single_file: self._load_post_result_file(single_file) def _load_post_result_file(self, file_name): """ loads a post-result file (.pof) """ name = os.path.split(file_name)[-1][:-4] self._logger.info("loading result file {}".format(file_name)) with open(file_name.encode(), "rb") as f: results = pickle.load(f) results.update({"name": name}) self.post_results.append(results) self.post_results_changed.emit() def update_post_result_list(self): self.post_result_list.clear() for res in self.post_results: name = res["name"] self.post_result_list.addItem(name) def remove_post_result_item(self): if self.post_result_list.currentRow() >= 0: del self.post_results[self.post_result_list.currentRow()] self.post_result_list.takeItem(self.post_result_list.currentRow()) def update_post_method_list(self): self.methodList.clear() modules = pm.get_registered_processing_modules(PostProcessingModule) for mod in modules: self.methodList.addItem(mod[1]) def update_meta_method_list(self): self.metaMethodList.clear() modules = pm.get_registered_processing_modules(MetaProcessingModule) for mod in modules: self.metaMethodList.addItem(mod[1]) def post_processor_clicked(self, item): self.run_processor(str(item.text()), "post") def meta_processor_clicked(self, item): self.run_processor(str(item.text()), "meta") def run_processor(self, name, processor_type): if processor_type == "post": result_files = self.results base_cls = PostProcessingModule elif processor_type == "meta": result_files = self.post_results base_cls = MetaProcessingModule else: self._logger.error("unknown processor type {0}".format( processor_type)) raise ValueError("unknown processor type {0}".format( processor_type)) if not result_files: self._logger.warning("run_processor() Error: no result file loaded") return processor_cls = pm.get_processing_module_class_by_name(base_cls, name) processor = processor_cls() figs = [] try: self._logger.info("executing processor '{0}'".format(name)) figs = processor.process(result_files) except Exception as err: self._logger.exception("Error in processor") self.figures_changed.emit(figs, processor_type) self._logger.info("finished postprocessing") def update_figure_lists(self, figures, target_type): # remove no longer needed elements for item, fig in [(key, val[0]) for key, val in self._figure_dict.items() if val[1] == target_type]: if fig not in [new_fig["figure"] for new_fig in figures]: if target_type == "post": old_item = self.post_figure_list.takeItem( self.post_figure_list.row(item)) del old_item elif target_type == "meta": old_item = self.meta_figure_list.takeItem( self.meta_figure_list.row(item)) del old_item del self._figure_dict[item] # add new ones to internal storage for fig in figures: if fig["figure"] not in self._figure_dict.values(): new_entry = [(fig["name"], (QListWidgetItem(fig["name"]), fig["figure"], target_type) )] self._figure_dict.update(new_entry) # add to display for key, val in self._figure_dict.items(): if val[2] == "post": self.post_figure_list.addItem(val[0]) elif val[2] == "meta": self.meta_figure_list.addItem(val[0]) self.post_figure_list.setCurrentItem(self.post_figure_list.item(0)) self.meta_figure_list.setCurrentItem(self.meta_figure_list.item(0)) def current_figure_changed(self, current_item, last_item=None): if current_item is None: return figures = self._figure_dict if self.lastFigure: self.grid.removeWidget(self.lastFigure) self.lastFigure.setVisible(False) if current_item.text() in figures: figure_widget = figures[current_item.text()][1] self.grid.addWidget(figure_widget, 1, 1, 5, 1) figure_widget.setVisible(True) self.lastFigure = figure_widget def switch_sides(self): self.displayLeft = not self.displayLeft if self.displayLeft: self.actSwitch.setIcon(QIcon(get_resource("left_mode.png"))) self.post_figure_list.setFocus() self.current_figure_changed(self.post_figure_list.currentItem()) else: self.actSwitch.setIcon(QIcon(get_resource("right_mode.png"))) self.meta_figure_list.setFocus() self.current_figure_changed(self.meta_figure_list.currentItem())
class GlyphSetTab(QWidget): def __init__(self, parent=None): super().__init__(parent) self.name = self.tr("Glyph sets") self.defaultGlyphSetBox = QCheckBox( self.tr("Default glyph set:"), self) self.defaultGlyphSetDrop = QComboBox(self) self.defaultGlyphSetBox.toggled.connect(self.toggleGlyphSetDrop) self.glyphSetList = QListWidget(self) self.glyphSetList.setSortingEnabled(True) self.glyphSetContents = QPlainTextEdit(self) self.glyphSetList.currentItemChanged.connect( self.updateGlyphSetContents) self.glyphSetList.itemChanged.connect(self.renameGlyphSet) self._cachedName = None splitter = QSplitter(self) splitter.addWidget(self.glyphSetList) splitter.addWidget(self.glyphSetContents) self.addGlyphSetButton = QPushButton("+", self) self.addGlyphSetButton.clicked.connect(lambda: self.addGlyphSet()) self.removeGlyphSetButton = QPushButton("−", self) self.removeGlyphSetButton.clicked.connect(self.removeGlyphSet) self.importButton = QPushButton(self.tr("Import"), self) importMenu = QMenu(self) importMenu.addAction( self.tr("Import from current font"), self.importFromCurrentFont) self.importButton.setMenu(importMenu) self.glyphListBox = QCheckBox(self.tr("Glyph list path:"), self) self.glyphListEdit = QLineEdit(self) self.glyphListEdit.setReadOnly(True) self.glyphListButton = QPushButton(self.tr("Browse…"), self) self.glyphListButton.clicked.connect(self.getGlyphList) # TODO: find correct solution for this and maybe make a widget w # setSizesToText() # http://stackoverflow.com/a/19502467/2037879 textWidth = self.glyphListButton.fontMetrics().boundingRect( self.glyphListButton.text()).width() + 16 self.glyphListButton.setMaximumWidth(textWidth) self.glyphListBox.toggled.connect(self.glyphListEdit.setEnabled) self.glyphListBox.toggled.connect(self.glyphListButton.setEnabled) firstLayout = QGridLayout() l = 0 firstLayout.addWidget(self.defaultGlyphSetBox, l, 0, 1, 2) firstLayout.addWidget(self.defaultGlyphSetDrop, l, 3, 1, 3) l += 1 firstLayout.addWidget(splitter, l, 0, 1, 6) l += 1 firstLayout.addWidget(self.addGlyphSetButton, l, 0) firstLayout.addWidget(self.removeGlyphSetButton, l, 1) firstLayout.addWidget(self.importButton, l, 2) secondLayout = QHBoxLayout() secondLayout.addWidget(self.glyphListBox, 0) secondLayout.addWidget(self.glyphListEdit, 1) secondLayout.addWidget(self.glyphListButton, 2) mainLayout = QVBoxLayout(self) mainLayout.addLayout(firstLayout) mainLayout.addLayout(secondLayout) self.setLayout(mainLayout) self.readSettings() def addGlyphSet(self, glyphNames=[], glyphSetName=None): if glyphSetName is None: glyphSetName = self.tr("New glyph set") if glyphSetName in self.glyphSets: index = 1 while "%s %d" % (glyphSetName, index) in self.glyphSets: index += 1 glyphSetName = "%s %d" % (glyphSetName, index) self.glyphSets[glyphSetName] = glyphNames item = QListWidgetItem(glyphSetName, self.glyphSetList) item.setFlags(item.flags() | Qt.ItemIsEditable) self.glyphSetList.setCurrentItem(item) self.glyphSetList.editItem(item) self.removeGlyphSetButton.setEnabled(True) def removeGlyphSet(self): i = self.glyphSetList.currentRow() text = self.glyphSetList.takeItem(i).text() del self.glyphSets[text] if self.glyphSetList.count() < 2: self.removeGlyphSetButton.setEnabled(False) def renameGlyphSet(self): newKey = self.glyphSetList.currentItem() if newKey is None: return newKey = newKey.text() self.glyphSets[newKey] = self.glyphSets[self._cachedName] del self.glyphSets[self._cachedName] def importFromCurrentFont(self): font = QApplication.instance().currentFont() name = "%s %s" % (font.info.familyName, font.info.styleName) self.addGlyphSet(font.glyphOrder, name) def toggleGlyphSetDrop(self): sender = self.sender() self.defaultGlyphSetDrop.setEnabled(sender.isChecked()) def updateGlyphSetContents(self, current, previous): # store content of the textEdit in the glyphSet dict if previous is not None: glyphNames = self.glyphSetContents.toPlainText().split() self.glyphSets[previous.text()] = glyphNames # now update the text edit to current glyphSet glyphSetName = current.text() text = " ".join(self.glyphSets[glyphSetName]) self.glyphSetContents.setPlainText(text) # cache current name for renames self._cachedName = glyphSetName def getGlyphList(self): fileFormats = ( self.tr("Text file {}").format("(*.txt)"), self.tr("All files {}").format("(*.*)"), ) path, _ = QFileDialog.getOpenFileName( self, self.tr("Open File"), '', ";;".join(fileFormats) ) if path: self.glyphListEdit.setText(path) def readSettings(self): defaultGlyphSet = settings.defaultGlyphSet() self.defaultGlyphSetBox.setChecked(len(defaultGlyphSet)) self.glyphSets = settings.readGlyphSets() self.defaultGlyphSetDrop.clear() self.defaultGlyphSetDrop.addItems(self.glyphSets.keys()) self.glyphSetList.clear() glyphSetNames = self.glyphSets.keys() # Normally we should be enforcing this rather decently in the interface # already if glyphSetNames: for glyphSetName in glyphSetNames: item = QListWidgetItem(glyphSetName, self.glyphSetList) item.setFlags(item.flags() | Qt.ItemIsEditable) self.glyphSetList.setCurrentRow(0) self.removeGlyphSetButton.setEnabled(len(self.glyphSets) > 1) glyphListPath = settings.glyphListPath() self.glyphListBox.setChecked(bool(glyphListPath)) self.glyphListEdit.setEnabled(bool(glyphListPath)) self.glyphListEdit.setText(glyphListPath) self.glyphListButton.setEnabled(bool(glyphListPath)) def writeSettings(self): # store content of the textEdit in the glyphSet dict glyphNames = self.glyphSetContents.toPlainText().split() currentGlyphSet = self.glyphSetList.currentItem().text() self.glyphSets[currentGlyphSet] = glyphNames settings.writeGlyphSets(self.glyphSets) if not self.defaultGlyphSetBox.isChecked(): settings.setDefaultGlyphSet(None) else: defaultGlyphSet = self.defaultGlyphSetDrop.currentText() settings.setDefaultGlyphSet(defaultGlyphSet) if not self.glyphListBox.isChecked(): settings.setGlyphListPath(None) else: glyphListPath = self.glyphListEdit.text() if glyphListPath: settings.setGlyphListPath(glyphListPath) QApplication.instance().loadGlyphList()
class PostProcessor(QMainWindow): sim_results_changed = pyqtSignal() post_results_changed = pyqtSignal() figures_changed = pyqtSignal(list, str) def __init__(self, parent=None): QMainWindow.__init__(self, parent) self._settings = QSettings() self._logger = logging.getLogger(self.__class__.__name__) self.setWindowTitle("Processing") self.setWindowIcon(QIcon(get_resource("processing.png"))) self.mainFrame = QWidget(self) self.resize(1000, 600) # toolbar self.toolBar = QToolBar("file control") self.toolBar.setIconSize(QSize(24, 24)) self.addToolBar(self.toolBar) self.actLoad = QAction(self) self.actLoad.setText("load result file") self.actLoad.setIcon(QIcon(get_resource("load.png"))) self.actLoad.setDisabled(False) self.actLoad.triggered.connect(self.load_result_files) self.actPostLoad = QAction(self) self.actPostLoad.setText("load post-result file") self.actPostLoad.setIcon(QIcon(get_resource("load.png"))) self.actPostLoad.setDisabled(False) self.actPostLoad.triggered.connect(self.load_post_result_files) self.actSwitch = QAction(self) self.actSwitch.setText("switch display mode") self.actSwitch.setIcon(QIcon(get_resource("left_mode.png"))) self.actSwitch.setDisabled(False) self.actSwitch.triggered.connect(self.switch_sides) self.displayLeft = True self.spacer1 = QWidget() self.spacer2 = QWidget() self.spacer1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.spacer2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.actReloadMethods = QAction(self) self.actReloadMethods.setText("reload methods") self.actReloadMethods.setIcon(QIcon(get_resource("reload.png"))) self.actReloadMethods.setDisabled(False) self.actReloadMethods.triggered.connect(self.update_post_method_list) self.actReloadMetaMethods = QAction(self) self.actReloadMetaMethods.setText("reload meta methods") self.actReloadMetaMethods.setIcon(QIcon(get_resource("reload.png"))) self.actReloadMetaMethods.setDisabled(False) self.actReloadMetaMethods.triggered.connect( self.update_meta_method_list) self.toolBar.addAction(self.actLoad) self.toolBar.addAction(self.actReloadMethods) self.toolBar.addWidget(self.spacer1) self.toolBar.addAction(self.actSwitch) self.toolBar.addWidget(self.spacer2) self.toolBar.addAction(self.actReloadMetaMethods) self.toolBar.addAction(self.actPostLoad) # main window self.grid = QGridLayout(self.mainFrame) self.grid.setColumnMinimumWidth(0, 70) self.grid.setColumnStretch(0, 0) self.grid.setColumnStretch(1, 1) self.methodList = QListWidget(self) self.methodList.itemDoubleClicked.connect(self.post_processor_clicked) self.update_post_method_list() self.metaMethodList = QListWidget(self) self.metaMethodList.itemDoubleClicked.connect( self.meta_processor_clicked) self.update_meta_method_list() self.sim_result_list = QListWidget(self) self.sim_results_changed.connect(self.update_result_list) self.results = [] self.delShort = QShortcut(QKeySequence(Qt.Key_Delete), self.sim_result_list) self.delShort.activated.connect(self.remove_result_item) # figures self._figure_dict = {} self.figures_changed.connect(self.update_figure_lists) self.post_figure_list = QListWidget(self) self.post_figure_list.currentItemChanged.connect( self.current_figure_changed) self.meta_figure_list = QListWidget(self) self.meta_figure_list.currentItemChanged.connect( self.current_figure_changed) self.plotView = QWidget() self.lastFigure = None self.post_result_list = QListWidget(self) self.post_results_changed.connect(self.update_post_result_list) self.post_results = [] self.delShortPost = QShortcut(QKeySequence(Qt.Key_Backspace), self.post_result_list) self.delShortPost.activated.connect(self.remove_post_result_item) # log dock self.logBox = QPlainTextEdit(self) self.logBox.setReadOnly(True) # init logger for logging box self.textLogger = PlainTextLogger(logging.INFO) self.textLogger.set_target_cb(self.logBox.appendPlainText) logging.getLogger().addHandler(self.textLogger) self.grid.addWidget(QLabel("Result Files:"), 0, 0) self.grid.addWidget(self.sim_result_list, 1, 0) self.grid.addWidget(QLabel("Postprocessors:"), 2, 0) self.grid.addWidget(self.methodList, 3, 0) self.grid.addWidget(QLabel("Figures:"), 4, 0) self.grid.addWidget(self.post_figure_list, 5, 0) self.grid.addWidget(QLabel("Selected Figure:"), 0, 1) self.grid.addWidget(QLabel("Postprocessor Files:"), 0, 2) self.grid.addWidget(self.post_result_list, 1, 2) self.grid.addWidget(QLabel("Metaprocessors:"), 2, 2) self.grid.addWidget(self.metaMethodList, 3, 2) self.grid.addWidget(QLabel("Figures:"), 4, 2) self.grid.addWidget(self.meta_figure_list, 5, 2) self.grid.addWidget(self.logBox, 6, 0, 1, 3) self.mainFrame.setLayout(self.grid) self.setCentralWidget(self.mainFrame) # status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) def load_result_files(self): path = self._settings.value("path/simulation_results") dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFiles) dialog.setDirectory(path) dialog.setNameFilter("PyMoskito Result files (*.pmr)") if dialog.exec_(): files = dialog.selectedFiles() for single_file in files: if single_file: self._load_result_file(single_file) def _load_result_file(self, file_name): """ loads a result file """ self._logger.info("loading result file {}".format(file_name)) with open(file_name.encode(), "rb") as f: self.results.append(pickle.load(f)) self.sim_results_changed.emit() def update_result_list(self): self.sim_result_list.clear() for res in self.results: name = res["regime name"] self.sim_result_list.addItem(name) def remove_result_item(self): if self.sim_result_list.currentRow() >= 0: del self.results[self.sim_result_list.currentRow()] self.sim_result_list.takeItem(self.sim_result_list.currentRow()) def load_post_result_files(self): path = self._settings.value("path/processing_results") dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFiles) dialog.setDirectory(path) dialog.setNameFilter("Postprocessing Output files (*.pof)") if dialog.exec_(): files = dialog.selectedFiles() for single_file in files: if single_file: self._load_post_result_file(single_file) def _load_post_result_file(self, file_name): """ loads a post-result file (.pof) """ name = os.path.split(file_name)[-1][:-4] self._logger.info("loading result file {}".format(file_name)) with open(file_name.encode(), "rb") as f: results = pickle.load(f) results.update({"name": name}) self.post_results.append(results) self.post_results_changed.emit() def update_post_result_list(self): self.post_result_list.clear() for res in self.post_results: name = res["name"] self.post_result_list.addItem(name) def remove_post_result_item(self): if self.post_result_list.currentRow() >= 0: del self.post_results[self.post_result_list.currentRow()] self.post_result_list.takeItem(self.post_result_list.currentRow()) def update_post_method_list(self): self.methodList.clear() modules = pm.get_registered_processing_modules(PostProcessingModule) for mod in modules: self.methodList.addItem(mod[1]) def update_meta_method_list(self): self.metaMethodList.clear() modules = pm.get_registered_processing_modules(MetaProcessingModule) for mod in modules: self.metaMethodList.addItem(mod[1]) def post_processor_clicked(self, item): self.run_processor(str(item.text()), "post") def meta_processor_clicked(self, item): self.run_processor(str(item.text()), "meta") def run_processor(self, name, processor_type): if processor_type == "post": result_files = self.results base_cls = PostProcessingModule elif processor_type == "meta": result_files = self.post_results base_cls = MetaProcessingModule else: self._logger.error( "unknown processor type {0}".format(processor_type)) raise ValueError( "unknown processor type {0}".format(processor_type)) if not result_files: self._logger.warning( "run_processor() Error: no result file loaded") return processor_cls = pm.get_processing_module_class_by_name(base_cls, name) processor = processor_cls() figs = [] try: self._logger.info("executing processor '{0}'".format(name)) figs = processor.process(result_files) except Exception as err: self._logger.exception("Error in processor") self.figures_changed.emit(figs, processor_type) self._logger.info("finished postprocessing") def update_figure_lists(self, figures, target_type): # remove no longer needed elements for item, fig in [(key, val[0]) for key, val in self._figure_dict.items() if val[1] == target_type]: if fig not in [new_fig["figure"] for new_fig in figures]: if target_type == "post": old_item = self.post_figure_list.takeItem( self.post_figure_list.row(item)) del old_item elif target_type == "meta": old_item = self.meta_figure_list.takeItem( self.meta_figure_list.row(item)) del old_item del self._figure_dict[item] # add new ones to internal storage for fig in figures: if fig["figure"] not in self._figure_dict.values(): new_entry = [(fig["name"], (QListWidgetItem(fig["name"]), fig["figure"], target_type))] self._figure_dict.update(new_entry) # add to display for key, val in self._figure_dict.items(): if val[2] == "post": self.post_figure_list.addItem(val[0]) elif val[2] == "meta": self.meta_figure_list.addItem(val[0]) self.post_figure_list.setCurrentItem(self.post_figure_list.item(0)) self.meta_figure_list.setCurrentItem(self.meta_figure_list.item(0)) def current_figure_changed(self, current_item, last_item=None): if current_item is None: return figures = self._figure_dict if self.lastFigure: self.grid.removeWidget(self.lastFigure) self.lastFigure.setVisible(False) if current_item.text() in figures: figure_widget = figures[current_item.text()][1] self.grid.addWidget(figure_widget, 1, 1, 5, 1) figure_widget.setVisible(True) self.lastFigure = figure_widget def switch_sides(self): self.displayLeft = not self.displayLeft if self.displayLeft: self.actSwitch.setIcon(QIcon(get_resource("left_mode.png"))) self.post_figure_list.setFocus() self.current_figure_changed(self.post_figure_list.currentItem()) else: self.actSwitch.setIcon(QIcon(get_resource("right_mode.png"))) self.meta_figure_list.setFocus() self.current_figure_changed(self.meta_figure_list.currentItem())
class ErrorsWidget(QWidget): ############################################################################### # ERRORS WIDGET SIGNALS ############################################################################### """ pep8Activated(bool) lintActivated(bool) """ pep8Activated = pyqtSignal(bool) lintActivated = pyqtSignal(bool) ############################################################################### def __init__(self): super(ErrorsWidget, self).__init__() self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listErrors.setSortingEnabled(True) self.listPep8 = QListWidget() self.listPep8.setSortingEnabled(True) hbox_lint = QHBoxLayout() if settings.FIND_ERRORS: self.btn_lint_activate = QPushButton(_translate("ErrorsWidget", "Lint: ON")) else: self.btn_lint_activate = QPushButton(_translate("ErrorsWidget", "Lint: OFF")) self.errorsLabel = QLabel(_translate("ErrorsWidget", "Static Errors: %s") % 0) hbox_lint.addWidget(self.errorsLabel) hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_lint.addWidget(self.btn_lint_activate) vbox.addLayout(hbox_lint) vbox.addWidget(self.listErrors) hbox_pep8 = QHBoxLayout() if settings.CHECK_STYLE: self.btn_pep8_activate = QPushButton(_translate("ErrorsWidget", "PEP8: ON")) else: self.btn_pep8_activate = QPushButton(_translate("ErrorsWidget", "PEP8: OFF")) self.pep8Label = QLabel(_translate("ErrorsWidget", "PEP8 Errors: %s") % 0) hbox_pep8.addWidget(self.pep8Label) hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_pep8.addWidget(self.btn_pep8_activate) vbox.addLayout(hbox_pep8) vbox.addWidget(self.listPep8) self.listErrors.itemSelectionChanged.connect(self.errors_selected) self.listPep8.itemSelectionChanged.connect(self.pep8_selected) self.btn_lint_activate.clicked['bool'].connect(self.errors_selected) self.btn_pep8_activate.clicked['bool'].connect(self._turn_on_off_pep8) def _turn_on_off_lint(self): """Change the status of the lint checker state.""" settings.FIND_ERRORS = not settings.FIND_ERRORS if settings.FIND_ERRORS: self.btn_lint_activate.setText(_translate("ErrorsWidget", "Lint: ON")) else: self.btn_lint_activate.setText(_translate("ErrorsWidget", "Lint: OFF")) self.lintActivated.emit(settings.FIND_ERRORS) def _turn_on_off_pep8(self): """Change the status of the lint checker state.""" settings.CHECK_STYLE = not settings.CHECK_STYLE if settings.CHECK_STYLE: self.btn_pep8_activate.setText(_translate("ErrorsWidget", "PEP8: ON")) else: self.btn_pep8_activate.setText(_translate("ErrorsWidget", "PEP8: OFF")) self.pep8Activated.emit(settings.CHECK_STYLE) def errors_selected(self): editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget and self._outRefresh: lineno = int(self.listErrors.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def pep8_selected(self): editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget and self._outRefresh: lineno = int(self.listPep8.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, errors, pep8): self._outRefresh = False self.listErrors.clear() self.listPep8.clear() for lineno in errors.errorsSummary: linenostr = 'L%s\t' % str(lineno + 1) for data in errors.errorsSummary[lineno]: item = QListWidgetItem(linenostr + data) item.setToolTip(linenostr + data) item.setData(Qt.UserRole, lineno) self.listErrors.addItem(item) self.errorsLabel.setText(_translate("ErrorsWidget", "Static Errors: %s") % len(errors.errorsSummary)) for lineno in pep8.pep8checks: linenostr = 'L%s\t' % str(lineno + 1) for data in pep8.pep8checks[lineno]: item = QListWidgetItem(linenostr + data.split('\n')[0]) item.setToolTip(linenostr + data.split('\n')[0]) item.setData(Qt.UserRole, lineno) self.listPep8.addItem(item) self.pep8Label.setText(_translate("ErrorsWidget", "PEP8 Errors: %s") % len(pep8.pep8checks)) self._outRefresh = True def clear(self): """ Clear the widget """ self.listErrors.clear() self.listPep8.clear()
class ErrorsWidget(QDialog): ############################################################################### # ERRORS WIDGET SIGNALS ############################################################################### """ pep8Activated(bool) lintActivated(bool) """ pep8Activated = pyqtSignal(bool) lintActivated = pyqtSignal(bool) dockWidget = pyqtSignal("QObject*") undockWidget = pyqtSignal() changeTitle = pyqtSignal(str) ############################################################################### def __init__(self, parent=None): super(ErrorsWidget, self).__init__(parent, Qt.WindowStaysOnTopHint) self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listErrors.setSortingEnabled(True) self.listPep8 = QListWidget() self.listPep8.setSortingEnabled(True) hbox_lint = QHBoxLayout() if settings.FIND_ERRORS: self.btn_lint_activate = QPushButton(self.tr("Lint: ON")) else: self.btn_lint_activate = QPushButton(self.tr("Lint: OFF")) self.errorsLabel = QLabel(self.tr("Static Errors: %s") % 0) hbox_lint.addWidget(self.errorsLabel) hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_lint.addWidget(self.btn_lint_activate) vbox.addLayout(hbox_lint) vbox.addWidget(self.listErrors) hbox_pep8 = QHBoxLayout() if settings.CHECK_STYLE: self.btn_pep8_activate = QPushButton(self.tr("PEP8: ON")) else: self.btn_pep8_activate = QPushButton(self.tr("PEP8: OFF")) self.pep8Label = QLabel(self.tr("PEP8 Errors: %s") % 0) hbox_pep8.addWidget(self.pep8Label) hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_pep8.addWidget(self.btn_pep8_activate) vbox.addLayout(hbox_pep8) vbox.addWidget(self.listPep8) self.listErrors.itemClicked['QListWidgetItem*'].connect( self.errors_selected) # self.listErrors.itemActivated['QListWidgetItem*'].connect(self.errors_selected) self.listPep8.itemClicked['QListWidgetItem*'].connect( self.pep8_selected) # self.listPep8.itemActivated['QListWidgetItem*'].connect(self.pep8_selected) self.btn_lint_activate.clicked['bool'].connect(self._turn_on_off_lint) self.btn_pep8_activate.clicked['bool'].connect(self._turn_on_off_pep8) IDE.register_service('tab_errors', self) ExplorerContainer.register_tab(translations.TR_TAB_ERRORS, self) def install_tab(self): ide = IDE.getInstance() ide.goingDown.connect(self.close) def _turn_on_off_lint(self): """Change the status of the lint checker state.""" settings.FIND_ERRORS = not settings.FIND_ERRORS if settings.FIND_ERRORS: self.btn_lint_activate.setText(self.tr("Lint: ON")) self.listErrors.show() else: self.btn_lint_activate.setText(self.tr("Lint: OFF")) self.listErrors.hide() self.lintActivated.emit(settings.FIND_ERRORS) def _turn_on_off_pep8(self): """Change the status of the lint checker state.""" settings.CHECK_STYLE = not settings.CHECK_STYLE if settings.CHECK_STYLE: self.btn_pep8_activate.setText(self.tr("PEP8: ON")) self.listPep8.show() else: self.btn_pep8_activate.setText(self.tr("PEP8: OFF")) self.listPep8.hide() self.pep8Activated.emit(settings.CHECK_STYLE) def errors_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget and self._outRefresh: lineno = int(self.listErrors.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def pep8_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget and self._outRefresh: lineno = int(self.listPep8.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_pep8_list(self, pep8): self._outRefresh = False self.listPep8.clear() for lineno in pep8: linenostr = 'L%s\t' % str(lineno + 1) for data in pep8[lineno]: item = QListWidgetItem(linenostr + data.split('\n')[0]) item.setToolTip(linenostr + data.split('\n')[0]) item.setData(Qt.UserRole, lineno) self.listPep8.addItem(item) self.pep8Label.setText(self.tr("PEP8 Errors: %s") % len(pep8)) self._outRefresh = True def refresh_error_list(self, errors): self._outRefresh = False self.listErrors.clear() for lineno in errors: linenostr = 'L%s\t' % str(lineno + 1) for data in errors[lineno]: item = QListWidgetItem(linenostr + data) item.setToolTip(linenostr + data) item.setData(Qt.UserRole, lineno) self.listErrors.addItem(item) self.errorsLabel.setText(self.tr("Static Errors: %s") % len(errors)) self._outRefresh = True def clear(self): """ Clear the widget """ self.listErrors.clear() self.listPep8.clear() def reject(self): if self.parent() is None: self.dockWidget.emit(self) def closeEvent(self, event): self.dockWidget.emit(self) event.ignore()
class DebuggerMainWindow(object): def __init__(self, comm): self.comm = comm self.follow_state = True self.init_instances() self.init_widgets() self.init_actions() self.window.closeEvent = self.close_handler self.window.showMaximized() def run(self): self.poll_timer = QTimer() self.poll_timer.timeout.connect(self.poll_handler) self.comm.start_worker() self.poll_timer.start(1000) def poll_handler(self): self.comm.put_job(self.comm.get_agent_track) data = self.comm.take_data() for location_info, state in data: file_name, node_id = location_info i = self.get_instance(file_name) if i is None: text = "%s:%s" % (str(location_info), state) else: node = i.model.get_node(node_id) if node is not None: text = "%s: %s: %s" % (file_name, node.get_display_text(), state) else: text = "%s:%s" % (str(location_info), state) self.add_to_history_list(location_info, text) if self.follow_state: self.focus_last() def init_widgets(self): self.window = loadUi(MAIN_UI_PATH) self.mdi = self.window.mdiArea self.mdi.setViewMode(QMdiArea.TabbedView) self.mdi.setTabsMovable(True) self.mdi.setTabsClosable(True) self.mdi.setTabShape(QTabWidget.Rounded) self.dock_anchor = self.window.dockAnchor self.dock_anchor.layout().setAlignment(Qt.AlignTop) self.history_list = QListWidget() self.history_list.itemSelectionChanged.connect(self.list_item_selected) self.add_dock_content(self.history_list) def list_item_selected(self): citem = self.history_list.currentItem() self.focus_on_location(citem.location_info) def init_instances(self): self.instances = {} def remove_instance(self, ins): file_name = ins.file_name self.instances.pop(file_name) def add_instance(self, ins): file_name = ins.file_name self.instances[file_name] = ins def get_instance(self, file_name): if file_name in self.instances: return self.instances[file_name] else: full_path = GraphInstanceVM.get_full_path(file_name) model = GraphInstanceVM.get_model(full_path) if model is None: return None ins = GraphInstanceVM(model, self, file_name) return ins def init_actions(self): self.window.actionResume.triggered.connect(self.action_resume_handler) self.window.actionStop.triggered.connect(self.action_stop_handler) self.window.actionFollow.triggered.connect(self.action_follow_handler) self.window.actionHold.triggered.connect(self.action_hold_handler) def action_resume_handler(self): self.clear_list() self.comm.put_job(functools.partial(self.comm.track_agent, True)) def action_stop_handler(self): self.comm.put_job(functools.partial(self.comm.track_agent, False)) def action_follow_handler(self): self.follow_state = True def action_hold_handler(self): self.follow_state = False def close_handler(self, ev): # disable tracking for some agents self.poll_timer.stop() self.comm.put_job(self.comm.finish) self.comm.shutdown() def add_dock_content(self, widget): self.clear_dock_contents() self.dock_anchor.layout().addWidget(widget) def get_dock_contents(self): l = self.dock_anchor.layout() ret = [] for i in range(l.count()): ret.append(l.itemAt(i).widget()) return ret def clear_dock_contents(self): ws = self.get_dock_contents() for w in ws: w.deleteLater() def focus_on_location(self, location): file_name, node_id = location instance = self.get_instance(file_name) if instance is None: logger.fatal("can not find src file for %s" % file_name) return False ret = instance.focus_on(node_id) if ret is False: logger.fatal("can not find node %s for %s" % (node_id, file_name)) return False return True def add_to_history_list(self, location, text): item = HistoryListItem(location, text) self.history_list.addItem(item) def clear_list(self): self.history_list.clear() def focus_last(self): c = self.history_list.count() if c > 0: item = self.history_list.item(c-1) self.history_list.setCurrentItem(item) self.focus_on_location(item.location_info)
class Widget(QWidget): def __init__(self, gtoAction, parent=None): super(Widget, self).__init__(parent) # from gtoAction self.gtomain = gtoAction.gtomain self.info = gtoAction.info self.debug = gtoAction.debug try: # from main self.helper = self.gtomain.helper self.iface = self.gtomain.iface self.metadata = self.gtomain.metadata self.prj = self.gtomain.prj self.canvas = self.iface.mapCanvas() # tooldata self.config = gtoAction.config self.tools = gtoAction.tools self.layers = self.config.get('layers', None) # load ui uic.loadUi( os.path.join(os.path.dirname(__file__), 'gto_expression.ui'), self) self.btnOk.clicked.connect(lambda: self.EvalExpr( self.lblLayer.text(), self.lblExpr.text())) self.btnDelete.clicked.connect(self.deleteEntry) self.btnNew.clicked.connect(self.newEntry) self.cboQuieries.currentIndexChanged.connect(self.setData) self.loadData() self.setData() except Exception as e: self.info.err(e) def setIconSizes(self, toolbar): try: btns = self.findChildren(QToolButton) for btn in btns: btn.setIconSize(self.iface.iconSize()) except Exception as e: self.info.err(e) def reset(self, *args): # from gtotoolbar before cleared try: if self.debug: self.info.log("widget reset") except Exception as e: self.info.err(e) def newEntry(self): try: if self.selectLayer() == QDialog.Accepted: ok, sql = self.showQueryBuilder(self.iface.activeLayer(), False) if ok and sql: newName, ok = QInputDialog().getText( self, 'Neue Abfrage', "Name:") if newName and ok: if not self.cboQuieries.findText( newName, Qt.MatchExactly): self.info("Abfrage <%s> existiert bereits!" % newName) else: self.cboQuieries.addItem( newName, [sql, self.iface.activeLayer().name()]) self.cboQuieries.setCurrentIndex( self.cboQuieries.findText( newName, Qt.MatchExactly)) if self.debug: self.info.log(self.cboQuieries.currentData()) self.saveData() except Exception as e: self.info.err(e) def loadData(self): try: file = os.path.join(self.metadata.dirGTO, 'expressions.txt') if self.debug: self.info.log("Data file:", file) if os.path.isfile(file): f = open(file, 'r') content = f.readlines() for line in content: try: data = line.split('|') self.cboQuieries.addItem(data[0], [data[1], data[2]]) except Exception as e: self.info.err(e) f.close() os.remove(file) if self.debug: self.info.log("File data:", content) else: # json file = os.path.join(self.metadata.dirGTO, 'expressions.json') data = self.helper.readJson(file) if data is not None: for k in data.keys(): v = data[k] if self.debug: self.info.log(k, v) self.cboQuieries.addItem(k, [v["expression"], v["layer"]]) self.cboQuieries.repaint() except Exception as e: self.info.err(e) def deleteEntry(self): try: if self.info.gtoQuestion( 'Abfrage <{0}> löschen?'.format( self.cboQuieries.currentText()), "Abfrage löschen") == QMessageBox.Yes: self.cboQuieries.removeItem(self.cboQuieries.currentIndex()) if self.cboQuieries.count() == 0: self.lblLayer.setText('') self.lblExpr.setText('') self.saveData() except Exception as e: self.info.err(e) def saveData(self): try: file = os.path.join(self.metadata.dirGTO, 'expressions.json') if self.debug: self.info.log("saveData:", file) data = {} for i in range(self.cboQuieries.count()): idata = self.cboQuieries.itemData(i) data[self.cboQuieries.itemText(i)] = { "layer": idata[1], "expression": idata[0] } if self.debug: self.info.log("saveData", data) if os.path.isfile(file): os.remove(file) self.helper.writeJson(file, data) except Exception as e: self.info.err(e) def setData(self): try: data = self.cboQuieries.currentData() if data: expr = data[0] layname = data[1] self.lblLayer.setText(layname) self.lblExpr.setText(expr) except Exception as e: self.info.err(e) def EvalExpr(self, layername, expr): try: index = self.cboQuieries.currentIndex() layer = self.prj.mapLayersByName(layername)[0] context = QgsExpressionContext() scope = QgsExpressionContextScope() context.appendScope(scope) listOfResults = [] features = [feat for feat in layer.getFeatures()] for feat in features: scope.setFeature(feat) exp = QgsExpression(expr) if exp.evaluate(context): listOfResults.append(feat.id()) if len(listOfResults) == 0: self.info.msg('Kein Ergebnis!') else: layer.selectByIds(listOfResults) self.iface.setActiveLayer(layer) self.gtomain.runcmd(self.tools) self.cboQuieries.setCurrentIndex(index) except Exception as e: self.info.err(e) def showQueryBuilder(self, layer, filter, sql=None): try: if not layer: layer = self.iface.activeLayer() self.query_builder = QgsQueryBuilder(layer, self.iface.mainWindow()) if sql: self.query_builder.setSql(sql) self.query_builder.accept() result = self.query_builder.exec_() if self.debug: self.info.log("QueryBuilder", self.query_builder.sql(), result, layer.subsetString()) if not filter: layer.setSubsetString(None) return result, self.query_builder.sql() except Exception as e: self.info.err(e) def selectLayer(self, editable=False): try: self.dlgLayers = QDialog(self.iface.mainWindow()) self.dlgLayers.setWindowTitle('Neue Abfrage') self.lay = QVBoxLayout(self.dlgLayers) self.lay.addWidget(QLabel("Layerauswahl:")) self.LayerList = QListWidget() self.lay.addWidget(self.LayerList) self.btnBox = QDialogButtonBox(self.dlgLayers) self.btnBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self.lay.addWidget(self.btnBox) if self.layers != None: for ml in self.layers: try: lay = self.prj.mapLayersByName(ml)[0] item = QListWidgetItem(lay.name()) self.LayerList.addItem(item) except: pass else: vectorLayers = [ layer for layer in self.iface.mapCanvas().layers() ] for ml in vectorLayers: self.info.log(type(ml)) if isinstance(ml, QgsVectorLayer): item = QListWidgetItem(ml.name()) self.LayerList.addItem(item) if self.iface.activeLayer(): items = self.LayerList.findItems( self.iface.activeLayer().name(), Qt.MatchExactly) if len(items) > 0: self.LayerList.setCurrentItem(items[0]) self.btnBox.accepted.connect(self.setActiveLayer) self.btnBox.rejected.connect(self.dlgLayers.reject) return self.dlgLayers.exec_() except Exception as e: self.info.err((e)) def setActiveLayer(self): try: lay = self.LayerList.currentItem().text() lay = self.prj.mapLayersByName(lay)[0] self.iface.setActiveLayer(lay) self.dlgLayers.accept() except Exception as e: self.info.err((e))
class CollectionCueSettings(SettingsPage): Name = 'Edit Collection' def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout(self)) self.cuesWidget = QListWidget(self) self.cuesWidget.setAlternatingRowColors(True) self.layout().addWidget(self.cuesWidget) # Buttons self.dialogButtons = QDialogButtonBox(self) self.dialogButtons.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.layout().addWidget(self.dialogButtons) self.addButton = self.dialogButtons.addButton('Add', QDialogButtonBox.ActionRole) self.addButton.clicked.connect(self._add_dialog) self.delButton = self.dialogButtons.addButton('Remove', QDialogButtonBox.ActionRole) self.delButton.clicked.connect(self._remove_selected) self.cue_dialog = CueListDialog(cues=Application().cue_model) self.cue_dialog.list.setSelectionMode(QAbstractItemView.ExtendedSelection) def load_settings(self, settings): for target_id, action in settings.get('targets', []): target = Application().cue_model.get(target_id) if target is not None: self._add_cue(target, action) def get_settings(self): targets = [] for n in range(self.cuesWidget.count()): widget = self.cuesWidget.itemWidget(self.cuesWidget.item(n)) target_id, action = widget.get_target() targets.append((target_id, action)) return {'targets': targets} def _add_cue(self, cue, action): item = QListWidgetItem() item.setSizeHint(QSize(200, 30)) widget = CueItemWidget(cue, action, self.cue_dialog) self.cuesWidget.addItem(item) self.cuesWidget.setItemWidget(item, widget) self.cue_dialog.remove_cue(cue) def _add_dialog(self): if self.cue_dialog.exec_() == QDialog.Accepted: for target in self.cue_dialog.selected_cues(): self._add_cue(target, tuple(target.CueActions)[0].name) def _remove_selected(self): cue = self.cuesWidget.itemWidget(self.cuesWidget.currentItem()).target self.cuesWidget.takeItem(self.cuesWidget.currentRow()) self.cue_dialog.add_cue(cue)
class Gui(QMainWindow): mainText = None mast = None tenants = None inc = None rowStore = None Gen = None gen = None mastInput = None keyNum = 1 def __init__(self): super().__init__() self.initUI() def initUI(self): app_icon = QIcon() app_icon.addFile("key.png", QSize(256, 256)) self.setWindowIcon(app_icon) # open openFile = QAction('Open', self) openFile.setShortcut('Ctrl+O') openFile.setStatusTip('Open new File') openFile.triggered.connect(self.fileOpen) # save saveFile = QAction('Save', self) saveFile.setShortcut('Ctrl+S') saveFile.setStatusTip('Save new File') saveFile.triggered.connect(self.fileSave) printAction = QAction("Print", self) printAction.triggered.connect(self.printSetup) # exit exitAction = QAction('Exit', self) exitAction.triggered.connect(self.closeEvent) # menu object menubar = self.menuBar() # file drop down fileMenu = menubar.addMenu('&File') fileMenu.addAction(openFile) fileMenu.addAction(saveFile) fileMenu.addAction(printAction) fileMenu.addAction(exitAction) # widgets grid = QGridLayout() horiz = QVBoxLayout() bigHoriz = QHBoxLayout() horizLayout = QHBoxLayout() window = QWidget() window.setLayout(bigHoriz) leftPane = QFormLayout() bigHoriz.addLayout(leftPane) bigHoriz.addLayout(horiz) self.setCentralWidget(window) btn = QPushButton('Generate', self) btn.clicked.connect(lambda: self.runGen()) clearBtn = QPushButton("Clear", self) clearBtn.clicked.connect(self.clearList) self.mainText = QListWidget(self) self.mainText.itemSelectionChanged.connect(self.listItemClicked) self.mainText.setFont( QFontDatabase.systemFont(QFontDatabase.FixedFont)) self.mastInput = [] i = 0 while i < 6: t = QLineEdit() t.setMaxLength(1) t.setAlignment(Qt.AlignHCenter) t.textChanged.connect(self.textInputed) self.mastInput.append(t) i = i + 1 for e in self.mastInput: horizLayout.addWidget(e) self.mast = QLineEdit() self.tenants = QLineEdit() self.inc = QLineEdit() self.title = QLineEdit() self.title.setMinimumWidth(200) self.desc = QLineEdit() self.address = QLineEdit() self.contact = QLineEdit() self.phone = QLineEdit() self.email = QLineEdit() self.notes = QTextEdit() self.keyway = QLineEdit() label = QLabel("Master Cuts") incLabel = QLabel("Increment") tenantLabel = QLabel("Tenants") # add widgets to layouts leftPane.addRow(QLabel("Title"), self.title) leftPane.addRow(QLabel("Description"), self.desc) leftPane.addRow(QLabel("Keyway"), self.keyway) leftPane.addRow(QLabel("Address"), self.address) leftPane.addRow(QLabel("contact"), self.contact) leftPane.addRow(QLabel("Phone"), self.phone) leftPane.addRow(QLabel("Email"), self.email) leftPane.addRow(QLabel("Notes"), self.notes) grid.addWidget(incLabel, 3, 0) grid.addWidget(tenantLabel, 2, 0) grid.addWidget(label, 1, 0) grid.addWidget(btn, 0, 0) horiz.addWidget(self.mainText) horiz.addLayout(grid) # horiz.addLayout(horizLayout) grid.addWidget(clearBtn, 0, 1) grid.addWidget(self.tenants, 2, 1) grid.addWidget(self.inc, 3, 1) grid.addLayout(horizLayout, 1, 1) # window properties self.setGeometry(300, 300, 500, 425) self.setWindowTitle('PySchlageGen') self.show() def textInputed(self, string): if len(string) == 1: self.focusNextChild() def getGen(self): return self.gen def runGen(self): self.mainText.clear() self.keyNum = 1 text = self.mast.text() mastCuts = [] try: for e in self.mastInput: if e.text(): mastCuts.append(int(e.text())) tenants = int(self.tenants.text()) inc = int(self.inc.text()) mastCuts = list(map(int, mastCuts)) self.gen = schlageGen() self.gen.addMasterKey(mastCuts) output = self.gen.genSystem(tenants, inc) self.displayKeys(output) except: pass def displayKeys(self, output): i = 0 for o in output: if self.keyNum < 10: f = str(self.keyNum) + ": " elif self.keyNum < 100: f = str(self.keyNum) + ": " elif self.keyNum < 1000: f = str(self.keyNum) + ": " else: f = str(self.keyNum) + ":" for e in o: f = f + str(e) + " " item = QListWidgetItem(f) self.mainText.insertItem(i, item) i = i + 1 self.keyNum = self.keyNum + 1 def formatText(self, flist, space=True, inj=" "): out = "" for e in flist[:-1]: out = out + str(e) if space: out = out + inj out = out + str(flist[-1]) return out def printSetup(self): if self.gen != None: printSetup = PrintSetup(self) printSetup.exec() else: QMessageBox.about(self, "Error","Please generate a system before printing.") def clearList(self): self.title.clear() self.desc.clear() self.address.clear() self.keyway.clear() self.contact.clear() self.phone.clear() self.email.clear() self.keyNum = 1 self.notes.clear() self.mainText.clear() self.tenants.clear() self.inc.clear() for e in self.mastInput: e.clear() def listItemClicked(self): item = self.mainText.currentItem() flags = item.flags() if flags & Qt.ItemIsEnabled: if self.rowStore != None: self.mainText.takeItem(self.rowStore + 1) self.mainText.takeItem(self.rowStore + 1) tenCuts = self.gen.getSystem()[int(item.text().split(":")[0]) - 1] tenCuts = list(map(int, tenCuts)) output = self.gen.bittingCalc(tenCuts) row = self.mainText.currentRow() self.rowStore = row flags = item.flags() flags ^= Qt.ItemIsEnabled item = QListWidgetItem(" " + self.formatText(output[0])) item.setFlags(flags) item2 = QListWidgetItem(" " + self.formatText(output[1])) item2.setFlags(flags) self.mainText.insertItem(row + 1, item) self.mainText.insertItem(row + 2, item2) def fileOpen(self): self.clearList() home = expanduser("~") fname = QFileDialog.getOpenFileName(self, 'Open file', home, "*.mks") data = None if fname[0] != '': with open(fname[0], 'r') as infile: data = infile.read() sys = data.split("`") self.gen = schlageGen() master = list(map(int, sys[0])) self.gen.addMasterKey(master) del sys[0] self.inc.setText(str(sys[0])) del sys[0] self.title.setText(str(sys[0])) del sys[0] self.desc.setText(str(sys[0])) del sys[0] self.keyway.setText(str(sys[0])) del sys[0] self.address.setText(str(sys[0])) del sys[0] self.contact.setText(str(sys[0])) del sys[0] self.phone.setText(str(sys[0])) del sys[0] self.email.setText(str(sys[0])) del sys[0] self.notes.setPlainText(str(sys[0])) del sys[0] self.gen.setTenants(sys) self.displayKeys(sys) i = 0 while i < len(master): self.mastInput[i].setText(str(master[i])) i = i + 1 self.tenants.setText(str(len(sys))) def fileSave(self): if self.gen != None: home = expanduser("~") fname = QFileDialog.getSaveFileName(self, 'Open file', home, "*.mks") if fname[0]: with open(fname[0], "w") as thefile: thefile.write("%s`" % self.formatText( self.gen.getMasterKey(), False)) thefile.write("%s`" % self.inc.text()) thefile.write("%s`" % self.title.text()) thefile.write("%s`" % self.desc.text()) thefile.write("%s`" % self.keyway.text()) thefile.write("%s`" % self.address.text()) thefile.write("%s`" % self.contact.text()) thefile.write("%s`" % self.phone.text()) thefile.write("%s`" % self.email.text()) thefile.write("%s`" % self.notes.toPlainText()) for e in self.gen.getSystem()[:-1]: thefile.write("%s`" % self.formatText(e, False)) thefile.write("%s" % self.formatText( self.gen.getSystem()[-1], False)) else: QMessageBox.about(self, "Error","Please generate a system before saving.") def closeEvent(self, event): reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: sys.exit() else: if event: event.ignore()
class App(QDialog): def __init__(self): super().__init__() self.title = 'FIS results GUI' self.left = 50 self.top = 50 self.width = 1800 self.height = 1000 self.initUI() with open("config.json", "r") as config: self.config = json.load(config) with open("results.json", "r") as results: self.results = json.load(results) self.fillCategories() self.fillEvents() # Display graphs self.showGraphs() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) windowLayout = QGridLayout() self.categorySelectorGroupBox = QGroupBox("Category") self.eventSelectorGroupBox = QGroupBox("Event") self.statsGroupBox = QGroupBox("Stats") self.plotLine1GroupBox1 = QGroupBox("Podium per country") self.plotLine1GroupBox2 = QGroupBox("Controls") self.plotLine1GroupBox3 = QGroupBox("Breakdown per month") self.plotLine2GroupBox1 = QGroupBox("Race result") self.plotLine2GroupBox2 = QGroupBox("Statistic of the season") # self.plotLine2GroupBox3 = QGroupBox("Line2 Block 3") # self.bottomGroupBox = QGroupBox("Last Race") windowLayout.addWidget(self.plotLine1GroupBox1, 0, 2, 2, 3) windowLayout.addWidget(self.plotLine1GroupBox2, 0, 5, 2, 3) windowLayout.addWidget(self.plotLine1GroupBox3, 0, 8, 2, 3) windowLayout.addWidget(self.plotLine2GroupBox1, 2, 2, 2, 4) windowLayout.addWidget(self.plotLine2GroupBox2, 2, 6, 2, 5) # windowLayout.addWidget(self.plotLine2GroupBox3,2,8,2,3) windowLayout.addWidget(self.categorySelectorGroupBox, 0, 0, 2, 2) windowLayout.addWidget(self.eventSelectorGroupBox, 2, 0, 2, 2) # windowLayout.addWidget(self.bottomGroupBox,5,0,2,11) self.setLayout(windowLayout) self.show() def fillCategories(self): availablesCategories = list(self.config["resultsStruct"].keys()) availablesCategories.insert(0, "All") # Set default category "All" self.category = "All" self.categoryList = QListWidget() for category in availablesCategories: self.categoryList.addItem(str(category)) self.categoryList.itemClicked.connect(self.categorySelectedCallback) self.categorySelector = QVBoxLayout() self.categorySelector.addWidget(self.categoryList) self.categorySelectorGroupBox.setLayout(self.categorySelector) def categorySelectedCallback(self): newCategory = self.categoryList.currentItem().text() # print(f"Update selected category from {self.category} to {newCategory}") self.category = newCategory self.resetGraphsCategory() def fillEvents(self): self.availablesEvents = dataVisualisation.getEventsList(self.results) self.event = self.availablesEvents[0] self.eventList = QListWidget() for event in self.availablesEvents: # print(event) date = "{:02d}".format(event["date"]["day"]) + "/" + str( event["date"]["month"]) + "/" + str(event["date"]["year"]) self.eventList.addItem(date + ' | ' + str(event["place"]) + " - " + event["type"]) self.eventList.itemClicked.connect(self.eventSelectedCallback) self.eventSelector = QVBoxLayout() self.eventSelector.addWidget(self.eventList) self.eventSelectorGroupBox.setLayout(self.eventSelector) def eventSelectedCallback(self): newEventIndex = self.eventList.currentRow() # print(f"Update selected event from {self.event} to {self.availablesEvents[newEventIndex]}") self.event = self.availablesEvents[newEventIndex] self.resetGraphsEvents() def showGraphs(self): self.createCountryPodium() self.createEventResults() self.createDetailAthlete() self.createCountryResultsBreakdown() self.createControls() def resetGraphsCategory(self): # Reset podium per country while (self.podiumTable.rowCount() > 0): self.podiumTable.removeRow(0) self.fillCountryPodium() # self.resetGraphBreakdown() def resetGraphsEvents(self): while (self.eventTable.rowCount() > 0): self.eventTable.removeRow(0) self.fillEventResults() def resetGraphBreakdown(self): # discards the old graph self.ax.clear() # refresh canvas self.canvas.draw() # Reset all the labels in the controlBox # controlLayout.clearL for i in reversed(range(self.labelLayout.count())): # layoutToDel = self.labelLayout.itemAt(i) widgetToRemove = self.labelLayout.itemAt(i).widget() # remove it from the layout list self.labelLayout.removeWidget(widgetToRemove) # remove it from the gui widgetToRemove.setParent(None) def createControls(self): self.resetGraphButton = QPushButton(text="Reset graph") self.resetGraphButton.clicked.connect(self.resetGraphBreakdown) self.controlLayout = QVBoxLayout() self.controlLayout.addWidget(self.resetGraphButton) self.controlLayout.addStretch() self.labelLayout = QVBoxLayout() self.plotLine1GroupBox2.setLayout(self.controlLayout) self.controlLayout.addLayout(self.labelLayout) def createCountryPodium(self): self.podiumTable = QTableWidget() self.podiumTable.setHorizontalHeaderLabels( ["Country", " 1st Places ", " 2nd Places ", " 3rd Places "]) self.fillCountryPodium() self.podiumTable.resizeColumnToContents(1) self.podiumTable.resizeColumnToContents(2) self.podiumTable.resizeColumnToContents(3) self.countryPodium = QVBoxLayout() self.countryPodium.addWidget(self.podiumTable) self.plotLine1GroupBox1.setLayout(self.countryPodium) self.podiumTable.cellClicked.connect( self.countryMedalBreakdownCallback) def fillCountryPodium(self): data = dataVisualisation.countryPodiumTable(self.results, self.category) self.podiumTable.setRowCount(len(data)) self.podiumTable.setColumnCount(4) for i, country in enumerate(data): self.podiumTable.setItem(i, 0, QTableWidgetItem(country.name)) self.podiumTable.setItem(i, 1, QTableWidgetItem(str(country.first))) self.podiumTable.setItem(i, 2, QTableWidgetItem(str(country.second))) self.podiumTable.setItem(i, 3, QTableWidgetItem(str(country.third))) def countryMedalBreakdownCallback(self, row, column): if column == 0: self.country = self.podiumTable.item(row, 0).text() print(f"Show detailed info about the country : {self.country}") self.fillCountryResultsBreakdown() def createCountryResultsBreakdown(self): self.figure = Figure() self.canvas = FigureCanvas(self.figure) # create an axis self.ax = self.figure.add_subplot(111) # discards the old graph self.ax.clear() self.ax.set_xlabel("Months") self.ax.set_ylabel("Nb of podiums") layout = QVBoxLayout() layout.addWidget(self.canvas) self.plotLine1GroupBox3.setLayout(layout) def fillCountryResultsBreakdown(self): data = dataVisualisation.getCountryBreakdown(self.country, self.category) # plot data p = self.ax.plot(data[0], data[1], '*-') # refresh canvas self.canvas.draw() # Get color from last line added on the graph hexColor = p[0].get_color() # Show info in the control box desc = self.country + " : " + self.category labelColor = QLabel(desc) labelColor.setStyleSheet( f"background-color: {hexColor}; border: 1px solid black;") self.labelLayout.addWidget(labelColor) def createEventResults(self): self.eventTable = QTableWidget() self.fillEventResults() self.eventPodium = QVBoxLayout() self.eventPodium.addWidget(self.eventTable) self.plotLine2GroupBox1.setLayout(self.eventPodium) self.eventTable.cellClicked.connect(self.resultSelectionChanged) def resultSelectionChanged(self, row, column): if column == 0: self.detailedAthleteName = self.eventTable.item(row, 0).text() print( f"Show detailed info about the athlete : {self.detailedAthleteName}" ) # Remove all current stats for i in reversed(range(self.detailLayout.count())): self.detailLayout.itemAt(i).widget().deleteLater() self.fillDetailAthlete() def fillEventResults(self): if self.event['type'] == "Slalom" or self.event[ 'type'] == "Giant Slalom": self.eventTable.setHorizontalHeaderLabels([ " Athlete ", " Country ", " Run 1 ", " Run 2 ", " Diff (ms) ", " Total " ]) self.eventTable.setColumnCount(6) data = dataVisualisation.eventResultTable(self.event) self.eventTable.setRowCount(len(data)) for i, athlete in enumerate(data): self.eventTable.setItem( i, 0, QTableWidgetItem(str(athlete["name"])[0:22])) self.eventTable.setItem( i, 1, QTableWidgetItem(str(athlete["country"]))) self.eventTable.setItem(i, 2, QTableWidgetItem(str(athlete["run1"]))) self.eventTable.setItem(i, 3, QTableWidgetItem(str(athlete["run2"]))) self.eventTable.setItem(i, 4, QTableWidgetItem(str(athlete["diff"]))) if athlete["diff"] > 0: self.eventTable.item(i, 4).setBackground(QColor(237, 2, 2)) elif athlete["diff"] < 0: self.eventTable.item(i, 4).setBackground(QColor(98, 252, 3)) self.eventTable.setItem( i, 5, QTableWidgetItem(str(athlete["total"]))) self.eventTable.resizeColumnsToContents() elif self.event['type'] == "Super G" or self.event[ 'type'] == "Downhill": self.eventTable.setHorizontalHeaderLabels( [" Athlete ", " Country ", " Time "]) self.eventTable.setColumnCount(3) data = dataVisualisation.eventResultTable(self.event) self.eventTable.setRowCount(len(data)) for i, athlete in enumerate(data): self.eventTable.setItem( i, 0, QTableWidgetItem(str(athlete["name"])[0:22])) self.eventTable.setItem( i, 1, QTableWidgetItem(str(athlete["country"]))) self.eventTable.setItem(i, 2, QTableWidgetItem(str(athlete["time"]))) self.eventTable.resizeColumnsToContents() elif self.event['type'] == "Parallel": self.eventTable.setHorizontalHeaderLabels( [" Athlete ", " Country "]) self.eventTable.setColumnCount(2) data = dataVisualisation.eventResultTable(self.event) self.eventTable.setRowCount(len(data)) for i, athlete in enumerate(data): self.eventTable.setItem( i, 0, QTableWidgetItem(str(athlete["name"])[0:22])) self.eventTable.setItem( i, 1, QTableWidgetItem(str(athlete["country"]))) self.eventTable.resizeColumnsToContents() def createDetailAthlete(self): self.instructionAthlete = QLabel("Select an athlete first") self.detailLayout = QVBoxLayout() self.detailLayout.addWidget(self.instructionAthlete) self.plotLine2GroupBox2.setLayout(self.detailLayout) def fillDetailAthlete(self): data = dataVisualisation.getDetails(self.detailedAthleteName, self.results) # self.detailLayout.removeWidget(self.instructionAthlete) nameCountry = QLabel( f"Name : {data['name']} | Country : {data['country']}") numberOfRace = QLabel(f"Number of races : {data['numberOfRace']}") numberOfPodium = QLabel( f"Number of podiums : {data['numberOfPodium']}") bestRank = QLabel(f"Best rank : {data['bestRank']}") bestRace = QLabel(f"Best race : {data['bestRace']}") bestCategory = QLabel(f"Best category : {data['bestCategory']}") self.detailLayout.addWidget(nameCountry) self.detailLayout.addWidget(numberOfRace) self.detailLayout.addWidget(numberOfPodium) self.detailLayout.addWidget(bestRank) self.detailLayout.addWidget(bestRace) self.detailLayout.addWidget(bestCategory)
class SetColumnsDialog(QtWidgets.QDialog, FORM_CLASS): def __init__(self, parent=None): """Constructor.""" super(SetColumnsDialog, self).__init__(parent) #self.setupUi(self) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) p = self.palette() p.setColor(self.backgroundRole(), Qt.white) self.setPalette(p) self.resize(900,700) # attributes self.filename = None self.progress = QProgressBar(self) self.progress.setGeometry(20, 550, 480, 20) self.progress.setRange(0,0) self.progress.setVisible(False) self.progressInfo = QLabel(self) self.progressInfo.setText("Generando el reporte, por favor espere...") self.progressInfo.move(20, 570) newfont = QFont("Arial", 10) newfont.setItalic(True) self.progressInfo.setFont(newfont) self.progressInfo.setVisible(False) def showDialog(self, layer, columnList, fonafifoUrl): self.layer=layer self.columnList=columnList self.columnList.clear() self.fonafifoUrl = fonafifoUrl MAX_FOOTER = 600 # FONAFIFO logo pic = QLabel(self) pic.setGeometry(600, MAX_FOOTER-30, 150, 50) pixmap = QPixmap() pixmap.load(fonafifoUrl); pic.setPixmap(pixmap) self.labelHeader = QLabel(self) self.labelHeader.setText("Selección de Criterios") self.labelHeader.setStyleSheet('color: #076F00') self.labelHeader.move(10, 20) newfont = QFont("Times", 20, QFont.Bold) self.labelHeader.setFont(newfont) self.frame = QFrame(self) self.frame.setFrameShape(QFrame.HLine) self.frame.setFrameShadow(QFrame.Sunken) self.frame.move(5,55); self.frame.resize(1955,5) self.buttonDescargar = QPushButton('Cargar Tabla', self) self.buttonDescargar.move(20, 590) self.buttonDescargar.resize(200, 30) self.buttonDescargar.clicked.connect(self.looping) self.buttonCerrar = QPushButton('Cerrar', self) self.buttonCerrar.move(270, 590) self.buttonCerrar.resize(200, 30) self.buttonCerrar.clicked.connect(self.close) X = 1500 Y = 200 HEIGHT=30 WIDTH_LABEL=400 INCREMENT_Y=20 self.str_TOTAL = 'Total'; self.str_AMPHIBIA = 'Amphibia'; self.str_AVES = 'Aves'; self.str_MAMMALIA = 'Mammalia'; self.str_PLANTAE = 'Plantae'; self.str_REPTILIA = 'Reptilia'; self.str_REGISTROS_DE_PRESENCIA = 'Registros de presencia'; self.str_AREAS_DE_DISTRIBUCION = 'Áreas de distribución'; self.str_AMENAZADAS_UICN = 'Amenazadas IUCN'; self.str_EN_PELIGRO_DE_EXTINCION = 'En peligro de extinción'; self.str_CON_POBLACION_REDUCIDA = 'Con población reducida'; self.str_VEDADA = 'Vedadas'; self.str_CONT = ' --> '; self.list_class_pre = QListWidget(self) self.list_class_pre.addItem(self.str_TOTAL) self.list_class_pre.addItem(self.str_AMPHIBIA) self.list_class_pre.addItem(self.str_AVES) self.list_class_pre.addItem(self.str_MAMMALIA) self.list_class_pre.addItem(self.str_PLANTAE) self.list_class_pre.addItem(self.str_REPTILIA) self.list_class_pre.setCurrentRow(0) self.list_class_pre.setGeometry(10, 120, 150, 120) self.list_tipo_pre = QListWidget(self) self.list_tipo_pre.addItem(self.str_REGISTROS_DE_PRESENCIA) self.list_tipo_pre.addItem(self.str_AREAS_DE_DISTRIBUCION) self.list_tipo_pre.setCurrentRow(0) self.list_tipo_pre.setGeometry(10, 250, 150, 90) self.list_amenazas_pre = QListWidget(self) self.list_amenazas_pre.addItem("--") self.list_amenazas_pre.addItem(self.str_AMENAZADAS_UICN) self.list_amenazas_pre.addItem(self.str_EN_PELIGRO_DE_EXTINCION) self.list_amenazas_pre.addItem(self.str_CON_POBLACION_REDUCIDA) self.list_amenazas_pre.addItem(self.str_VEDADA) self.list_amenazas_pre.setCurrentRow(0) self.list_amenazas_pre.setGeometry(10, 350, 150, 90) self.botton_list_include = QPushButton(">>", self) self.botton_list_include.setGeometry(200, 120, 50, 50) self.botton_list_include.clicked.connect(self.chooseClassInclude) self.botton_list_exclude = QPushButton("<<", self) self.botton_list_exclude.setGeometry(200, 160, 50, 50) self.botton_list_exclude.clicked.connect(self.chooseClassExclude) self.list_class_post = QListWidget(self) self.list_class_post.setGeometry(300, 120, WIDTH_LABEL, 350) self.seleccionClass = ""; self.seleccionTipo = ""; self.seleccionAmenaza = ""; self.checkbox_presencia_total_especies = QCheckBox("Riqueza total de especies por registros de presencia", self) self.checkbox_presencia_total_especies.setGeometry(X,Y,WIDTH_LABEL,HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_especies_amenazadas = QCheckBox("Riqueza total de especies por registros de presencia - Amenazadas UICN", self) self.checkbox_presencia_total_especies_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_especies_amenazadas_lcvs = QCheckBox("Riqueza total de especies por registros de presencia - Amenazadas LCVS", self) self.checkbox_presencia_total_especies_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_presencia_total_mammalia = QCheckBox("Riqueza total de MAMMALIA por registros de presencia", self) self.checkbox_presencia_total_mammalia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_mammalia_amenazadas = QCheckBox("Riqueza total de MAMMALIA por registros de presencia - Amenazadas UICN", self) self.checkbox_presencia_total_mammalia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_mammalia_amenazadas_lcvs = QCheckBox("Riqueza total de MAMMALIA por registros de presencia - Amenazadas LCVS", self) self.checkbox_presencia_total_mammalia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_presencia_total_aves = QCheckBox("Riqueza total de AVES por registros de presencia", self) self.checkbox_presencia_total_aves.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_aves_amenazadas = QCheckBox("Riqueza total de AVES por registros de presencia - Amenazadas UICN", self) self.checkbox_presencia_total_aves_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_aves_amenazadas_lcvs = QCheckBox("Riqueza total de AVES por registros de presencia - Amenazadas LCVS", self) self.checkbox_presencia_total_aves_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_presencia_total_reptilia = QCheckBox("Riqueza total de REPTILIA por registros de presencia", self) self.checkbox_presencia_total_reptilia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_reptilia_amenazadas = QCheckBox("Riqueza total de REPTILIA por registros de presencia - Amenazadas UICN", self) self.checkbox_presencia_total_reptilia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_reptilia_amenazadas_lcvs = QCheckBox("Riqueza total de REPTILIA por registros de presencia - Amenazadas LCVS", self) self.checkbox_presencia_total_reptilia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_presencia_total_amphibia = QCheckBox("Riqueza total de AMPHIBIA por registros de presencia", self) self.checkbox_presencia_total_amphibia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_amphibia_amenazadas = QCheckBox("Riqueza total de AMPHIBIA por registros de presencia - Amenazadas UICN", self) self.checkbox_presencia_total_amphibia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_amphibia_amenazadas_lcvs = QCheckBox("Riqueza total de AMPHIBIA por registros de presencia - Amenazadas LCVS", self) self.checkbox_presencia_total_amphibia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_presencia_total_trees = QCheckBox("Riqueza total de PLANTAE por registros de presencia", self) self.checkbox_presencia_total_trees.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_trees_amenazadas = QCheckBox("Riqueza total de PLANTAE por registros de presencia - Amenazadas UICN", self) self.checkbox_presencia_total_trees_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_presencia_total_trees_amenazadas_lcvs = QCheckBox("Riqueza total de PLANTAE por registros de presencia - Amenazadas LCVS", self) self.checkbox_presencia_total_trees_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y = 70 X = 1450 self.checkbox_distribucion_total_especies = QCheckBox("Riqueza total de especies por áreas de distribución", self) self.checkbox_distribucion_total_especies.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_especies_amenazadas = QCheckBox("Riqueza total de especies por áreas de distribución - Amenazadas UICN", self) self.checkbox_distribucion_total_especies_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_especies_amenazadas_lcvs = QCheckBox("Riqueza total de especies por áreas de distribución - Amenazadas LCVS", self) self.checkbox_distribucion_total_especies_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_distribucion_total_mammalia = QCheckBox("Riqueza total de MAMMALIA por áreas de distribución", self) self.checkbox_distribucion_total_mammalia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_mammalia_amenazadas = QCheckBox("Riqueza total de MAMMALIA por áreas de distribución - Amenazadas UICN", self) self.checkbox_distribucion_total_mammalia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_mammalia_amenazadas_lcvs = QCheckBox("Riqueza total de MAMMALIA por áreas de distribución - Amenazadas LCVS", self) self.checkbox_distribucion_total_mammalia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_distribucion_total_aves = QCheckBox("Riqueza total de AVES por áreas de distribución", self) self.checkbox_distribucion_total_aves.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_aves_amenazadas = QCheckBox("Riqueza total de AVES por áreas de distribución - Amenazadas UICN", self) self.checkbox_distribucion_total_aves_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_aves_amenazadas_lcvs = QCheckBox("Riqueza total de AVES por áreas de distribución - Amenazadas LCVS", self) self.checkbox_distribucion_total_aves_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_distribucion_total_reptilia = QCheckBox("Riqueza total de REPTILIA por áreas de distribución", self) self.checkbox_distribucion_total_reptilia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_reptilia_amenazadas = QCheckBox("Riqueza total de REPTILIA por áreas de distribución - Amenazadas UICN", self) self.checkbox_distribucion_total_reptilia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_reptilia_amenazadas_lcvs = QCheckBox("Riqueza total de REPTILIA por áreas de distribución - Amenazadas LCVS", self) self.checkbox_distribucion_total_reptilia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_distribucion_total_amphibia = QCheckBox("Riqueza total de AMPHIBIA por áreas de distribución", self) self.checkbox_distribucion_total_amphibia.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_amphibia_amenazadas = QCheckBox("Riqueza total de AMPHIBIA por áreas de distribución - Amenazadas UICN", self) self.checkbox_distribucion_total_amphibia_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_amphibia_amenazadas_lcvs = QCheckBox("Riqueza total de AMPHIBIA por áreas de distribución - Amenazadas LCVS", self) self.checkbox_distribucion_total_amphibia_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y Y += INCREMENT_Y self.checkbox_distribucion_total_trees = QCheckBox("Riqueza total de PLANTAE por áreas de distribución", self) self.checkbox_distribucion_total_trees.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_trees_amenazadas = QCheckBox("Riqueza total de PLANTAE por áreas de distribución - Amenazadas UICN", self) self.checkbox_distribucion_total_trees_amenazadas.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) Y += INCREMENT_Y self.checkbox_distribucion_total_trees_amenazadas_lcvs = QCheckBox("Riqueza total de PLANTAE por áreas de distribución - Amenazadas LCVS", self) self.checkbox_distribucion_total_trees_amenazadas_lcvs.setGeometry(X, Y, WIDTH_LABEL, HEIGHT) self.show() def looping(self): self.progressInfo.setVisible(True) self.progress.setVisible(True) self.looptimer = QTimer() self.looptimer.setSingleShot(True) self.looptimer.timeout.connect(self.cargarTabla) self.looptimer.start(5000) def rellenarText(self, strClass): if (self.seleccionClass == strClass): if (self.seleccionTipo == self.str_REGISTROS_DE_PRESENCIA): const_REG_PRESENCIA = strClass + self.str_CONT + self.str_REGISTROS_DE_PRESENCIA if (self.seleccionAmenaza == '--'): self.list_class_post.addItem(const_REG_PRESENCIA) if (self.seleccionAmenaza == self.str_AMENAZADAS_UICN): self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_AMENAZADAS_UICN); if (self.seleccionAmenaza == self.str_EN_PELIGRO_DE_EXTINCION): self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_EN_PELIGRO_DE_EXTINCION); if (self.seleccionAmenaza == self.str_CON_POBLACION_REDUCIDA): self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_CON_POBLACION_REDUCIDA); if (self.seleccionAmenaza == self.str_VEDADA): if((self.seleccionClass == self.str_PLANTAE) | (self.seleccionClass == self.str_TOTAL)): self.list_class_post.addItem(const_REG_PRESENCIA + self.str_CONT + self.str_VEDADA); else: QMessageBox.about(self, 'Alerta!', 'La categoria "VEDADA" es exclusiva para Plantae'); self.agregarColumnas(strClass, self.seleccionAmenaza, "occurrence"); if (self.seleccionTipo == self.str_AREAS_DE_DISTRIBUCION): const_REG_DISTRIBUCION = strClass + self.str_CONT + self.str_AREAS_DE_DISTRIBUCION if (self.seleccionAmenaza == '--'): self.list_class_post.addItem(const_REG_DISTRIBUCION) if (self.seleccionAmenaza == self.str_AMENAZADAS_UICN): self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_AMENAZADAS_UICN); if (self.seleccionAmenaza == self.str_EN_PELIGRO_DE_EXTINCION): self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_EN_PELIGRO_DE_EXTINCION); if (self.seleccionAmenaza == self.str_CON_POBLACION_REDUCIDA): self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_CON_POBLACION_REDUCIDA); if (self.seleccionAmenaza == self.str_VEDADA): if((self.seleccionClass == self.str_PLANTAE) | (self.seleccionClass == self.str_TOTAL)): self.list_class_post.addItem(const_REG_DISTRIBUCION + self.str_CONT + self.str_VEDADA); else: QMessageBox.about(self, 'Alerta!', 'La categoria "VEDADA" es exclusiva para Plantae'); self.agregarColumnas(strClass, self.seleccionAmenaza, "distribution"); def agregarColumnas(self, strClass, strStatus, strType): if (strClass == self.str_TOTAL): if (strStatus == '--'): self.columnList.append("all_" + strType); self.columnList.append("all_" + strType + "_names"); if (strStatus == self.str_AMENAZADAS_UICN): self.columnList.append("all_iucn_threatened_" + strType); self.columnList.append("all_iucn_threatened_" + strType + "_names"); if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION): self.columnList.append("all_lcvs_pe_" + strType); self.columnList.append("all_lcvs_pe_" + strType + "_names"); if (strStatus == self.str_CON_POBLACION_REDUCIDA): self.columnList.append("all_lcvs_pr_" + strType); self.columnList.append("all_lcvs_pr_" + strType + "_names"); if (strStatus == self.str_VEDADA): self.columnList.append("all_lcvs_ve_" + strType); self.columnList.append("all_lcvs_ve_" + strType + "_names"); if (strClass == self.str_AMPHIBIA): if (strStatus == '--'): self.columnList.append("amphibia_" + strType); self.columnList.append("amphibia_" + strType + "_names"); if (strStatus == self.str_AMENAZADAS_UICN): self.columnList.append("amphibia_iucn_threatened_" + strType); self.columnList.append("amphibia_iucn_threatened_" + strType + "_names"); if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION): self.columnList.append("amphibia_lcvs_pe_" + strType); self.columnList.append("amphibia_lcvs_pe_" + strType + "_names"); if (strStatus == self.str_CON_POBLACION_REDUCIDA): self.columnList.append("amphibia_lcvs_pr_" + strType); self.columnList.append("amphibia_lcvs_pr_" + strType + "_names"); if (strClass == self.str_AVES): if (strStatus == '--'): self.columnList.append("aves_" + strType); self.columnList.append("aves_occurrence_names"); if (strStatus == self.str_AMENAZADAS_UICN): self.columnList.append("aves_iucn_threatened_" + strType); self.columnList.append("aves_iucn_threatened_" + strType + "_names"); if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION): self.columnList.append("aves_lcvs_pe_" + strType); self.columnList.append("aves_lcvs_pe_" + strType + "_names"); if (strStatus == self.str_CON_POBLACION_REDUCIDA): self.columnList.append("aves_lcvs_pr_" + strType); self.columnList.append("aves_lcvs_pr_" + strType + "_names"); if (strClass == self.str_MAMMALIA): if (strStatus == '--'): self.columnList.append("mammalia_" + strType); self.columnList.append("mammalia_" + strType + "_names"); if (strStatus == self.str_AMENAZADAS_UICN): self.columnList.append("mammalia_iucn_threatened_" + strType); self.columnList.append("mammalia_iucn_threatened_" + strType + "_names"); if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION): self.columnList.append("mammalia_lcvs_pe_" + strType); self.columnList.append("mammalia_lcvs_pe_" + strType + "_names"); if (strStatus == self.str_CON_POBLACION_REDUCIDA): self.columnList.append("mammalia_lcvs_pr_" + strType); self.columnList.append("mammalia_lcvs_pr_" + strType + "_names"); if (strClass == self.str_PLANTAE): if (strStatus == '--'): self.columnList.append("plantae_" + strType); self.columnList.append("plantae_" + strType + "_names"); if (strStatus == self.str_AMENAZADAS_UICN): self.columnList.append("plantae_iucn_threatened_" + strType); self.columnList.append("plantae_iucn_threatened_" + strType + "_names"); if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION): self.columnList.append("plantae_lcvs_pe_" + strType); self.columnList.append("plantae_lcvs_pe_" + strType + "_names"); if (strStatus == self.str_CON_POBLACION_REDUCIDA): self.columnList.append("plantae_lcvs_pr_" + strType); self.columnList.append("plantae_lcvs_pr_" + strType + "_names"); if (strStatus == self.str_VEDADA): self.columnList.append("plantae_lcvs_ve_" + strType); self.columnList.append("plantae_lcvs_ve_" + strType + "_names"); if (strClass == self.str_REPTILIA): if (strStatus == '--'): self.columnList.append("reptilia_" + strType); self.columnList.append("reptilia_" + strType + "_names"); if (strStatus == self.str_AMENAZADAS_UICN): self.columnList.append("reptilia_iucn_threatened_" + strType); self.columnList.append("reptilia_iucn_threatened_" + strType + "_names"); if (strStatus == self.str_EN_PELIGRO_DE_EXTINCION): self.columnList.append("reptilia_lcvs_pe_" + strType); self.columnList.append("reptilia_lcvs_pe_" + strType + "_names"); if (strStatus == self.str_CON_POBLACION_REDUCIDA): self.columnList.append("reptilia_lcvs_pr_" + strType); self.columnList.append("reptilia_lcvs_pr_" + strType + "_names"); def chooseClassInclude(self): for selectedItem in self.list_class_pre.selectedItems(): self.seleccionClass = self.list_class_pre.currentItem().text(); self.seleccionTipo = self.list_tipo_pre.currentItem().text(); self.seleccionAmenaza = self.list_amenazas_pre.currentItem().text(); self.rellenarText(self.str_TOTAL); self.rellenarText(self.str_AMPHIBIA); self.rellenarText(self.str_AVES); self.rellenarText(self.str_MAMMALIA); self.rellenarText(self.str_PLANTAE); self.rellenarText(self.str_REPTILIA); #self.list_class_post.addItem(self.list_class_pre.currentItem().text()) #self.list_class_pre.takeItem(self.list_class_pre.row(selectedItem)) def chooseClassExclude(self): for selectedItem in self.list_class_post.selectedItems(): self.list_class_pre.addItem(self.list_class_post.currentItem().text()) self.list_class_post.takeItem(self.list_class_post.row(selectedItem)) def cargarTabla(self): ############################################################################### ### VALIDACIONES ############################################################################### if self.checkbox_presencia_total_especies.isChecked(): self.columnList.append("spp_all_richness_occurrence") self.columnList.append("spp_all_richness_occurrence_names") if self.checkbox_presencia_total_especies_amenazadas.isChecked(): self.columnList.append("spp_all_threatened_richness_occurrence") self.columnList.append("spp_all_threatened_richness_occurrence_names") if self.checkbox_presencia_total_especies_amenazadas_lcvs.isChecked(): self.columnList.append("spp_all_lcvs_richness_occurrence") self.columnList.append("spp_all_lcvs_richness_occurrence_names") if self.checkbox_presencia_total_mammalia.isChecked(): self.columnList.append("spp_mammalia_richness_occurrence") self.columnList.append("spp_mammalia_richness_occurrence_names") if self.checkbox_presencia_total_mammalia_amenazadas.isChecked(): self.columnList.append("spp_mammalia_threatened_richness_occurrence") self.columnList.append("spp_mammalia_threatened_richness_occurrence_names") if self.checkbox_presencia_total_mammalia_amenazadas_lcvs.isChecked(): self.columnList.append("spp_mammalia_lcvs_richness_occurrence") self.columnList.append("spp_mammalia_lcvs_richness_occurrence_names") if self.checkbox_presencia_total_aves.isChecked(): self.columnList.append("spp_aves_richness_occurrence") self.columnList.append("spp_aves_richness_occurrence_names") if self.checkbox_presencia_total_aves_amenazadas.isChecked(): self.columnList.append("spp_aves_threatened_richness_occurrence") self.columnList.append("spp_aves_threatened_richness_occurrence_names") if self.checkbox_presencia_total_aves_amenazadas_lcvs.isChecked(): self.columnList.append("spp_aves_lcvs_richness_occurrence") self.columnList.append("spp_aves_lcvs_richness_occurrence_names") if self.checkbox_presencia_total_reptilia.isChecked(): self.columnList.append("spp_reptilia_richness_occurrence") self.columnList.append("spp_reptilia_richness_occurrence_names") if self.checkbox_presencia_total_reptilia_amenazadas.isChecked(): self.columnList.append("spp_reptilia_threatened_richness_occurrence") self.columnList.append("spp_reptilia_threatened_richness_occurrence_names") if self.checkbox_presencia_total_reptilia_amenazadas_lcvs.isChecked(): self.columnList.append("spp_reptilia_lcvs_richness_occurrence") self.columnList.append("spp_reptilia_lcvs_richness_occurrence_names") if self.checkbox_presencia_total_amphibia.isChecked(): self.columnList.append("spp_amphibia_richness_occurrence") self.columnList.append("spp_amphibia_richness_occurrence_names") if self.checkbox_presencia_total_amphibia_amenazadas.isChecked(): self.columnList.append("spp_amphibia_threatened_richness_occurrence") self.columnList.append("spp_amphibia_threatened_richness_occurrence_names") if self.checkbox_presencia_total_amphibia_amenazadas_lcvs.isChecked(): self.columnList.append("spp_amphibia_lcvs_richness_occurrence") self.columnList.append("spp_amphibia_lcvs_richness_occurrence_names") if self.checkbox_presencia_total_trees.isChecked(): self.columnList.append("spp_trees_richness_occurrence") self.columnList.append("spp_trees_richness_occurrence_names") if self.checkbox_presencia_total_trees_amenazadas.isChecked(): self.columnList.append("spp_trees_threatened_richness_occurrence") self.columnList.append("spp_trees_threatened_richness_occurrence_names") if self.checkbox_presencia_total_trees_amenazadas_lcvs.isChecked(): self.columnList.append("spp_trees_lcvs_richness_occurrence") self.columnList.append("spp_trees_lcvs_richness_occurrence_names") # DISTRIBUTION if self.checkbox_distribucion_total_especies.isChecked(): self.columnList.append("spp_all_richness_distribution") self.columnList.append("spp_all_richness_distribution_names") if self.checkbox_distribucion_total_especies_amenazadas.isChecked(): self.columnList.append("spp_all_threatened_richness_distribution") self.columnList.append("spp_all_threatened_richness_distribution_names") if self.checkbox_distribucion_total_especies_amenazadas_lcvs.isChecked(): self.columnList.append("spp_all_lcvs_richness_distribution") self.columnList.append("spp_all_lcvs_richness_distribution_names") if self.checkbox_distribucion_total_mammalia.isChecked(): self.columnList.append("spp_mammalia_richness_distribution") self.columnList.append("spp_mammalia_richness_distribution_names") if self.checkbox_distribucion_total_mammalia_amenazadas.isChecked(): self.columnList.append("spp_mammalia_threatened_richness_distribution") self.columnList.append("spp_mammalia_threatened_richness_distribution_names") if self.checkbox_distribucion_total_mammalia_amenazadas_lcvs.isChecked(): self.columnList.append("spp_mammalia_lcvs_richness_distribution") self.columnList.append("spp_mammalia_lcvs_richness_distribution_names") if self.checkbox_distribucion_total_aves.isChecked(): self.columnList.append("spp_aves_richness_distribution") self.columnList.append("spp_aves_richness_distribution_names") if self.checkbox_distribucion_total_aves_amenazadas.isChecked(): self.columnList.append("spp_aves_threatened_richness_distribution") self.columnList.append("spp_aves_threatened_richness_distribution_names") if self.checkbox_distribucion_total_aves_amenazadas_lcvs.isChecked(): self.columnList.append("spp_aves_lcvs_richness_distribution") self.columnList.append("spp_aves_lcvs_richness_distribution_names") if self.checkbox_distribucion_total_reptilia.isChecked(): self.columnList.append("spp_reptilia_richness_distribution") self.columnList.append("spp_reptilia_richness_distribution_names") if self.checkbox_distribucion_total_reptilia_amenazadas.isChecked(): self.columnList.append("spp_reptilia_threatened_richness_distribution") self.columnList.append("spp_reptilia_threatened_richness_distribution_names") if self.checkbox_distribucion_total_reptilia_amenazadas_lcvs.isChecked(): self.columnList.append("spp_reptilia_lcvs_richness_distribution") self.columnList.append("spp_reptilia_lcvs_richness_distribution_names") if self.checkbox_distribucion_total_amphibia.isChecked(): self.columnList.append("spp_amphibia_richness_distribution") self.columnList.append("spp_amphibia_richness_distribution_names") if self.checkbox_distribucion_total_amphibia_amenazadas.isChecked(): self.columnList.append("spp_amphibia_threatened_richness_distribution") self.columnList.append("spp_amphibia_threatened_richness_distribution_names") if self.checkbox_distribucion_total_amphibia_amenazadas_lcvs.isChecked(): self.columnList.append("spp_amphibia_lcvs_richness_distribution") self.columnList.append("spp_amphibia_lcvs_richness_distribution_names") if self.checkbox_distribucion_total_trees.isChecked(): self.columnList.append("spp_trees_richness_distribution") self.columnList.append("spp_trees_richness_distribution_names") if self.checkbox_distribucion_total_trees_amenazadas.isChecked(): self.columnList.append("spp_trees_threatened_richness_distribution") self.columnList.append("spp_trees_threatened_richness_distribution_names") if self.checkbox_distribucion_total_trees_amenazadas_lcvs.isChecked(): self.columnList.append("spp_trees_lcvs_richness_distribution") self.columnList.append("spp_trees_lcvs_richness_distribution_names") self.dlgIdentificarPoligono = IdentifyToolDialog() self.dlgIdentificarPoligono.showDialog(self.layer, self.columnList, self.progress, self.progressInfo, self.fonafifoUrl)
class ListEdit(QWidget): """A widget to edit a list of items (e.g. a list of directories).""" # emitted when anything changed in the listbox. changed = pyqtSignal() def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) layout = QGridLayout(self) self.setLayout(layout) self.addButton = QPushButton(icons.get('list-add'), '') self.editButton = QPushButton(icons.get('document-edit'), '') self.removeButton = QPushButton(icons.get('list-remove'), '') self.listBox = QListWidget() layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(0) layout.addWidget(self.listBox, 0, 0, 8, 1) layout.addWidget(self.addButton, 0, 1) layout.addWidget(self.editButton, 1, 1) layout.addWidget(self.removeButton, 2, 1) @self.addButton.clicked.connect def addClicked(): item = self.createItem() if self.openEditor(item): self.addItem(item) @self.editButton.clicked.connect def editClicked(): item = self.listBox.currentItem() item and self.editItem(item) @self.removeButton.clicked.connect def removeClicked(): item = self.listBox.currentItem() if item: self.removeItem(item) @self.listBox.itemDoubleClicked.connect def itemDoubleClicked(item): item and self.editItem(item) self.listBox.model().layoutChanged.connect(self.changed) def updateSelection(): selected = bool(self.listBox.currentItem()) self.editButton.setEnabled(selected) self.removeButton.setEnabled(selected) self.changed.connect(updateSelection) self.listBox.itemSelectionChanged.connect(updateSelection) updateSelection() app.translateUI(self) def translateUI(self): self.addButton.setText(_("&Add...")) self.editButton.setText(_("&Edit...")) self.removeButton.setText(_("&Remove")) def createItem(self): return QListWidgetItem() def addItem(self, item): self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def removeItem(self, item): self.listBox.takeItem(self.listBox.row(item)) self.changed.emit() def editItem(self, item): if self.openEditor(item): self.itemChanged(item) self.changed.emit() def setCurrentItem(self, item): self.listBox.setCurrentItem(item) def setCurrentRow(self, row): self.listBox.setCurrentRow(row) def openEditor(self, item): """Opens an editor (dialog) for the item. Returns True if the dialog was accepted and the item edited. Returns False if the dialog was cancelled (the item must be left unedited). """ pass def itemChanged(self, item): """Called after an item has been added or edited. Re-implement to do something at this moment if needed, e.g. alter the text or display of other items. """ pass def setValue(self, strings): """Sets the listbox to a list of strings.""" self.listBox.clear() self.listBox.addItems(strings) self.changed.emit() def value(self): """Returns the list of paths in the listbox.""" return [self.listBox.item(i).text() for i in range(self.listBox.count())] def setItems(self, items): """Sets the listbox to a list of items.""" self.listBox.clear() for item in items: self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def items(self): """Returns the list of items in the listbox.""" return [self.listBox.item(i) for i in range(self.listBox.count())] def clear(self): """Clears the listbox.""" self.listBox.clear() self.changed.emit()
class UsersGUI(QWidget): logginn = pyqtSignal(str, str, LogLevel) def __init__(self): super(UsersGUI, self).__init__() self.loggin = Logger('UsersGUI', self.logginn) self.nautaw = NautaWrap() self.nautaw.set_f_load_u_ugui(self.load_users) self.nauta = self.nautaw.nauta self.cl = QVBoxLayout() self.li = QListWidget() self.load_users() self.cl.addWidget(self.li) tt = QHBoxLayout() addu = qta.icon('mdi.account-plus', color='green', color_active='yellow') self.addu = QPushButton(addu, "") editu = qta.icon('mdi.account-edit', color='blue', color_active='yellow') self.editu = QPushButton(editu, "") remu = qta.icon('mdi.account-minus', color='red', color_active='yellow') self.remu = QPushButton(remu, "") tt.addWidget(self.addu) tt.addWidget(self.editu) tt.addWidget(self.remu) tt.addStretch() self.verif = QCheckBox("Verificar cuenta") tt.addWidget(self.verif) self.cl.addLayout(tt) self.setLayout(self.cl) self.addu.clicked.connect(self.adduser) self.editu.clicked.connect(self.edituser) self.remu.clicked.connect(self.deluser) def adduser(self): self.loggin.emit("Agregando cuenta.", LogLevel.INFORMATION) txt, ok = QInputDialog.getText(self, tr("Agregar Cuenta"), tr("Usuario"), 0, "") if not ok: self.loggin.emit("Operacion cancelada por el usuario.", LogLevel.INFORMATION) return user = txt txt, ok = QInputDialog.getText(self, tr("Agregar Cuenta"), tr("Contraseña"), 2, "") if not ok: self.loggin.emit("Operacion cancelada por el usuario.", LogLevel.INFORMATION) return passw = txt if self.verif.isChecked(): try: self.loggin.emit("Verificando cuenta {0}.".format(user), LogLevel.INFORMATION) self.nauta.card_add(user, passw, verify=True, raise_exception=True) except ConectionError: self.loggin.emit( "Parece que no hay connexion en este momento. No se puede verificar la cuenta. Desmarque verificar para poder agregarla.", LogLevel.WARNING) self.loggin.emit( "No se pudo agregar la cuenta por que no se pudo verificar.", LogLevel.INFORMATION) return except BadCredentials: self.loggin.emit("Cuenta incorrecta.", LogLevel.WARNING) self.loggin.emit( "No se pudo agregar la cuenta por que es incorrecta.", LogLevel.INFORMATION) return self.loggin.emit("Cuenta {0} agergada correctamente.".format(user), LogLevel.INFORMATION) self.nautaw.update_u() return self.nauta.card_add(user, passw, verify=False, raise_exception=False) self.loggin.emit("Cuenta {0} agergada correctamente.".format(user), LogLevel.INFORMATION) self.nautaw.update_u() def edituser(self): cc = self.li.currentItem() if not cc: return txt = cc.text() card = self.nauta.get_card(txt, try_update=False) userc = card.username passwc = card.password self.loggin.emit("Editando cuenta.", LogLevel.INFORMATION) txt, ok = QInputDialog.getText(self, tr("Editar Cuenta"), tr("Usuario"), 0, userc) if not ok: self.loggin.emit("Operacion cancelada por el usuario.", LogLevel.INFORMATION) return user = txt txt, ok = QInputDialog.getText(self, tr("Editar Cuenta"), tr("Contraseña"), 2, passwc) if not ok: self.loggin.emit("Operacion cancelada por el usuario.", LogLevel.INFORMATION) return passw = txt if self.verif.isChecked(): self.loggin.emit("Verificando cuenta {0}.".format(user), LogLevel.INFORMATION) try: vv = self.nauta.verify(user, passw) except (requests.exceptions.ConnectionError, requests.exceptions.ConnectTimeout): self.loggin.emit( "Parece que no hay connexion en este momento. No se puede verificar la cuenta. Desmarque verificar para poder editarla.", LogLevel.WARNING) self.loggin.emit( "No se pudo editar la cuenta por que no se pudo verificar.", LogLevel.INFORMATION) return if not vv: self.loggin.emit("Cuenta incorrecta.", LogLevel.WARNING) self.loggin.emit( "No se pudo editar la cuenta por que es incorrecta.", LogLevel.INFORMATION) return card = self.nauta.get_card(txt, try_update=True) self.nauta.card_update(userc, card.to_json()) self.loggin.emit("Cuenta {0} editada correctamente.".format(user), LogLevel.INFORMATION) self.nautaw.update_u() return self.nauta.card_update(userc, card.to_json()) self.loggin.emit("Cuenta {0} editada correctamente.".format(user), LogLevel.INFORMATION) self.nautaw.update_u() def deluser(self): cc = self.li.currentItem() if not cc: return txt = cc.text() card = self.nauta.get_card(txt, try_update=False) userc = card.username self.loggin.emit("Eliminando cuenta.", LogLevel.INFORMATION) if self.nautaw.active and self.nautaw.account == userc: self.loggin.emit( "Cuenta en uso. Es necesario desconnectarse primero.", LogLevel.INFORMATION) return ok = QMessageBox.question( self, "Eliminar cuenta", "Seguro que quiere eliminar la cuenta {0}?".format(userc)) if ok == QMessageBox.No: self.loggin.emit("Operacion cancelada por el usuario.", LogLevel.INFORMATION) return self.nauta.card_delete(userc) self.nautaw.update_u() def load_users(self): self.li.clear() for i in sorted(self.nauta.get_cards(as_dict=True), key=lambda x: x['username']): self.li.addItem(i['username'])