def update_songs_properties(self): index = self.ui.tableView_Songs.selectedIndexes() if len(index) > 0: assert isinstance(index[0], QModelIndex) row_id = index[0].sibling(index[0].row(), 0).data() query = QSqlQuery() query.prepare('SELECT t_artist.id, t_artist.name ' 'FROM t_song ' 'INNER JOIN t_song_artist ON t_song.id = t_song_artist.id_song ' 'INNER JOIN t_artist ON t_artist.id = t_song_artist.id_artist ' 'WHERE t_song.id = ' + str(row_id)) query.setForwardOnly(1) query.exec_() songs = QTreeWidgetItem() songs.setText(0, "Artists:") while query.next(): song = QTreeWidgetItem() song.setText(0, str(query.value(0)) + " - " + query.value(1)) songs.addChild(song) self.ui.treeWidget_Songs_Properties.clear() self.ui.treeWidget_Songs_Properties.addTopLevelItem(songs) self.ui.treeWidget_Songs_Properties.expandAll()
def get_overview_tree(self): top_tree_items = [] for individual in self.children: tree_item = QTreeWidgetItem([individual.name]) for session in individual.sessions: sess_item = QTreeWidgetItem([session.name]) tree_item.addChild(sess_item) if session.brain: epi_path_item = QTreeWidgetItem(['EPI: ' + session.brain.path.split('/')[-1]]) else: epi_path_item = QTreeWidgetItem(['EPI: None']) if session.mask: mask_path_item = QTreeWidgetItem(['Mask: ' + session.mask.path.split('/')[-1]]) else: mask_path_item = QTreeWidgetItem(['Mask: None']) if session.stimuli: stim_path_item = QTreeWidgetItem(['Stimuli: ' + session.stimuli.path.split('/')[-1]]) else: stim_path_item = QTreeWidgetItem(['Stimuli: None']) sess_item.addChildren([epi_path_item, mask_path_item, stim_path_item]) top_tree_items.append(tree_item) return top_tree_items
def update_game_properties(self): attraction = self.ui.comboBox_Game_Attraction.currentText().strip() if len(attraction) > 0: attraction_id, _ = attraction.split(" - ", 1) query = QSqlQuery() query.prepare('SELECT SUM(point), name ' 'FROM (SELECT t_point.point, t_competitor.name ' 'FROM t_point INNER JOIN t_competitor ON ' 't_point.id_competitor = t_competitor.id ' 'WHERE t_point.id_competitor_take = 1 ' 'AND t_point.id_attraction = ' + attraction_id + ' ' 'UNION ALL ' 'SELECT t_point.point, t_competitor.name ' 'FROM t_point INNER JOIN t_competitor ' 'ON t_point.id_competitor_take = t_competitor.id ' 'WHERE t_point.id_competitor_take != 1 ' 'AND t_point.id_attraction = ' + attraction_id + ') ' 'GROUP BY name ORDER BY SUM(point) DESC') query.setForwardOnly(1) query.exec_() points = QTreeWidgetItem() points.setText(0, "Points:") while query.next(): point = QTreeWidgetItem() point.setText(0, str(query.value(0)) + " - " + query.value(1)) points.addChild(point) self.ui.treeWidget_Game_Properties.clear() self.ui.treeWidget_Game_Properties.addTopLevelItem(points) self.ui.treeWidget_Game_Properties.expandAll()
def populateConfigParams(self, dlg): """ Populates the dialog with option items and widgets """ self.items = defaultdict(dict) tree = dlg.paramsTreeOL configure_export_action = QAction('...', self) configure_export_action.triggered.connect(self.configureExporter) params = getParams(configure_exporter_action=configure_export_action) for group, settings in params.items(): item = QTreeWidgetItem() item.setText(0, group) for param, value in settings.items(): subitem = self.createOptionItem(tree_widget=tree, parent_item=item, parameter=param, default_value=value) item.addChild(subitem) self.items[group][param] = subitem self.paramsTreeOL.addTopLevelItem(item) item.sortChildren(0, Qt.AscendingOrder) self.paramsTreeOL.expandAll() self.paramsTreeOL.resizeColumnToContents(0) self.paramsTreeOL.resizeColumnToContents(1) self.layer_search_combo.removeItem(1)
def update(self, network: Network): self.clear() self.addChild = self.addTopLevelItem chains = network.get_blockchains() n_chains = len(chains) for chain_id, interfaces in chains.items(): b = blockchain.blockchains.get(chain_id) if b is None: continue name = b.get_name() if n_chains > 1: x = QTreeWidgetItem([name + '@%d'%b.get_max_forkpoint(), '%d'%b.height()]) x.setData(0, Qt.UserRole, 1) x.setData(1, Qt.UserRole, b.get_id()) else: x = self for i in interfaces: star = ' *' if i == network.interface else '' item = QTreeWidgetItem([i.host + star, '%d'%i.tip]) item.setData(0, Qt.UserRole, 0) item.setData(1, Qt.UserRole, i.server) x.addChild(item) if n_chains > 1: self.addTopLevelItem(x) x.setExpanded(True) h = self.header() h.setStretchLastSection(False) h.setSectionResizeMode(0, QHeaderView.Stretch) h.setSectionResizeMode(1, QHeaderView.ResizeToContents) super().update()
def addLayer(self, layer): item = QTreeWidgetItem([layer.name], 0) for program in layer: child_item = QTreeWidgetItem([program.name], 0) item.addChild(child_item) child_item.setSelected(program.is_visible) self.ui.treeWidget_layers.addTopLevelItem(item) self.ui.treeWidget_layers.expandItem(item) item.setSelected(True)
def on_core_open_files(self, data): if not data: return core_item = QTreeWidgetItem(self.window().open_files_tree_widget) core_item.setText(0, "Core (%d)" % len(data["open_files"])) self.window().open_files_tree_widget.addTopLevelItem(core_item) for open_file in data["open_files"]: item = QTreeWidgetItem() item.setText(0, open_file["path"]) item.setText(1, "%d" % open_file["fd"]) core_item.addChild(item)
def fill_item(self, item: dict, parent: QTreeWidgetItem): tree_item = QTreeWidgetItem() tree_item.setChildIndicatorPolicy(QTreeWidgetItem.DontShowIndicatorWhenChildless) tree_item.setText(0, item['name']) if item['children'] is None: # set userdata = item_id only if this IS a LEAF node tree_item.setData(0, Qt.UserRole, item['item_id']) # column, role, data parent.addChild(tree_item) # recurse into children if item['children'] is not None: for oitem in item['children']: self.fill_item(oitem, tree_item)
def on_core_threads(self, data): if not data: return self.window().threads_tree_widget.clear() for thread_info in data["threads"]: thread_item = QTreeWidgetItem(self.window().threads_tree_widget) thread_item.setText(0, "%d" % thread_info["thread_id"]) thread_item.setText(1, thread_info["thread_name"]) self.window().threads_tree_widget.addTopLevelItem(thread_item) for frame in thread_info["frames"]: frame_item = QTreeWidgetItem() frame_item.setText(2, frame) thread_item.addChild(frame_item)
def show(self, mls): analysis_map = {"Domain Transition Analysis": DomainTransitionAnalysisTab, "Information Flow Analysis": InfoFlowAnalysisTab} components_map = {"Booleans": BoolQueryTab, "Commons": CommonQueryTab, "Roles": RoleQueryTab, "Object Classes": ObjClassQueryTab, "Types": TypeQueryTab, "Type Attributes": TypeAttributeQueryTab, "Users": UserQueryTab} rule_map = {"Constraints": ConstraintQueryTab, "RBAC Rules": RBACRuleQueryTab, "TE Rules": TERuleQueryTab} labeling_map = {"Fs_use_* Statements": FSUseQueryTab, "Genfscon Statements": GenfsconQueryTab, "Initial SID Statements": InitialSIDQueryTab, "Netifcon Statements": NetifconQueryTab, "Nodecon Statements": NodeconQueryTab, "Portcon Statements": PortconQueryTab} general_choices = {"Summary": SummaryTab} other_choices = {"Bounds": BoundsQueryTab, "Defaults": DefaultQueryTab} analysis_choices = {"Components": components_map, "Rules": rule_map, "Analyses": analysis_map, "Labeling": labeling_map, "General": general_choices, "Other": other_choices} if mls: rule_map["MLS Rules"] = MLSRuleQueryTab components_map["Categories"] = CategoryQueryTab components_map["Sensitivities"] = SensitivityQueryTab # populate the item list: self.analysisTypes.clear() for groupname, group in analysis_choices.items(): groupitem = QTreeWidgetItem(self.analysisTypes) groupitem.setText(0, groupname) groupitem._tab_class = None for entryname, cls in group.items(): item = QTreeWidgetItem(groupitem) item.setText(0, entryname) item._tab_class = cls groupitem.addChild(item) self.analysisTypes.expandAll() self.analysisTypes.sortByColumn(0, Qt.AscendingOrder) super(ChooseAnalysis, self).show()
def setInvoiceTreeList(self, treeList): print("controller.setInvoiceTreeList") self.ui.invList.clear() parentItem = self.ui.invList.invisibleRootItem() # first add key as parent then loop at value list for category in treeList.keys(): rootChildItem = QTreeWidgetItem() rootChildItem.setText(0, str(category)) # add children to rootChild for inv in treeList[category]: invNo = QTreeWidgetItem() invNo.setText(0, inv) rootChildItem.addChild(invNo) # add rootChild to invList parentItem.addChild(rootChildItem)
def update_competitors_properties(self): index = self.ui.tableView_Competitors.selectedIndexes() if len(index) > 0: assert isinstance(index[0], QModelIndex) row_id = index[0].sibling(index[0].row(), 0).data() query = QSqlQuery() query.prepare('SELECT DISTINCT t_event.id, t_event.name ' 'FROM t_competitor ' 'INNER JOIN t_point ON t_competitor.id = t_point.id_competitor ' 'INNER JOIN t_attraction ON t_attraction.id = t_point.id_attraction ' 'INNER JOIN t_event ON t_event.id = t_attraction.id_event ' 'WHERE t_competitor.id = ' + str(row_id)) query.setForwardOnly(1) query.exec_() events = QTreeWidgetItem() events.setText(0, "Events:") while query.next(): event = QTreeWidgetItem() event.setText(0, str(query.value(0)) + " - " + query.value(1)) events.addChild(event) inner_query = QSqlQuery() inner_query.prepare('SELECT DISTINCT t_attraction.id, t_attraction.name ' 'FROM t_competitor ' 'INNER JOIN t_point ON t_competitor.id = t_point.id_competitor ' 'INNER JOIN t_attraction ON t_attraction.id = t_point.id_attraction ' 'INNER JOIN t_event ON t_event.id = t_attraction.id_event ' 'WHERE t_event.id = ' + str(query.value(0)) + ' ' 'AND t_competitor.id = ' + str(row_id)) inner_query.setForwardOnly(1) inner_query.exec_() while inner_query.next(): attraction = QTreeWidgetItem() attraction.setText(0, str(inner_query.value(0)) + " - " + inner_query.value(1)) event.addChild(attraction) self.ui.treeWidget_Competitors_Properties.clear() self.ui.treeWidget_Competitors_Properties.addTopLevelItem(events) self.ui.treeWidget_Competitors_Properties.expandAll()
def setupUi(self): self.load_ui("choose_analysis.ui") self.buttonBox.accepted.connect(self.ok_clicked) self.analysisTypes.doubleClicked.connect(self.ok_clicked) # populate the item list: self.analysisTypes.clear() for groupname, group in self._analysis_choices.items(): groupitem = QTreeWidgetItem(self.analysisTypes) groupitem.setText(0, groupname) groupitem._tab_class = None for entryname, cls in group.items(): item = QTreeWidgetItem(groupitem) item.setText(0, entryname) item._tab_class = cls groupitem.addChild(item) self.analysisTypes.expandAll() self.analysisTypes.sortByColumn(0, Qt.AscendingOrder)
def _new_browser_item(self, type_, parent, rules=None, children=None): # build main item item = QTreeWidgetItem(parent if parent else self.browser) item.setText(0, str(type_)) item.type_ = type_ item.children = children if children else [] item.rules = rules if rules else [] item.child_populated = children is not None # add child items for child_type, child_rules in item.children: child_item = self._new_browser_item(child_type, item, rules=child_rules) item.addChild(child_item) item.setExpanded(children is not None) self.log.debug("Built item for {0} with {1} children and {2} rules".format( type_, len(item.children), len(item.rules))) return item
def load_open_files_tab(self): # Fill the open files (GUI) tree widget my_process = psutil.Process() self.window().open_files_tree_widget.clear() gui_item = QTreeWidgetItem(self.window().open_files_tree_widget) try: open_files = my_process.open_files() gui_item.setText(0, "GUI (%d)" % len(open_files)) self.window().open_files_tree_widget.addTopLevelItem(gui_item) for open_file in open_files: item = QTreeWidgetItem() item.setText(0, open_file.path) item.setText(1, "%d" % open_file.fd) gui_item.addChild(item) except psutil.AccessDenied as exc: gui_item.setText(0, "Unable to get open files for GUI (%s)" % exc) self.request_mgr = TriblerRequestManager() self.request_mgr.perform_request("debug/open_files", self.on_core_open_files)
def setDocuments(self, documents): """Display the specified documents in the list.""" # clear the treewidget for d in self.tree.invisibleRootItem().takeChildren(): for i in d.takeChildren(): i.doc = None # group the documents by directory dirs = {} for d in documents: path = d.url().toLocalFile() if path: dirname, filename = os.path.split(path) dirs.setdefault(dirname, []).append((filename, d)) for dirname in sorted(dirs, key=util.naturalsort): diritem = QTreeWidgetItem() diritem.setText(0, util.homify(dirname)) self.tree.addTopLevelItem(diritem) diritem.setExpanded(True) diritem.setFlags(Qt.ItemIsEnabled) diritem.setIcon(0, icons.get('folder-open')) for filename, document in sorted(dirs[dirname], key=lambda item: util.naturalsort(item[0])): fileitem = QTreeWidgetItem() diritem.addChild(fileitem) if documentwatcher.DocumentWatcher.instance(document).isdeleted(): itemtext = _("[deleted]") icon = "dialog-error" else: itemtext = _("[modified]") icon = "document-edit" fileitem.setIcon(0, icons.get(icon)) fileitem.setText(0, filename) fileitem.setText(1, itemtext) fileitem.doc = document # select the item if there is only one if len(dirs) == 1 and len(list(dirs.values())[0]) == 1: fileitem.setSelected(True) self.tree.resizeColumnToContents(0) self.tree.resizeColumnToContents(1) self.updateButtons()
def load_ui(self): sections = sorted( Preferences.configuration.keys(), key=lambda item: Preferences.configuration[item]['weight']) for section in sections: text = Preferences.configuration[section]['text'] Widget = Preferences.configuration[section]['widget'] widget = Widget(self) area = QScrollArea() area.setWidgetResizable(True) area.setWidget(widget) self.stacked.addWidget(area) index = self.stacked.indexOf(area) item = QTreeWidgetItem([text]) item.setData(0, Qt.UserRole, index) self.tree.addTopLevelItem(item) # Sort Item Children subcontent = Preferences.configuration[section].get( 'subsections', {}) subsections = sorted( subcontent.keys(), key=lambda item: subcontent[item]['weight']) for sub in subsections: text = subcontent[sub]['text'] Widget = subcontent[sub]['widget'] widget = Widget(self) area = QScrollArea() area.setWidgetResizable(True) area.setWidget(widget) self.stacked.addWidget(area) index = self.stacked.indexOf(area) subitem = QTreeWidgetItem([text]) subitem.setData(0, Qt.UserRole, index) item.addChild(subitem) self.tree.expandAll() self.tree.setCurrentIndex(self.tree.model().index(0, 0))
class MainDialog(QDialog, Ui_MainDialog): """The main dialog of QGIS2Web plugin.""" items = {} def __init__(self, iface): QDialog.__init__(self) self.setupUi(self) self.iface = iface self.previewUrl = None self.layer_search_combo = None self.exporter_combo = None self.feedback = FeedbackDialog(self) self.feedback.setModal(True) stgs = QSettings() self.restoreGeometry(stgs.value("qgis2web/MainDialogGeometry", QByteArray(), type=QByteArray)) if stgs.value("qgis2web/previewOnStartup", Qt.Checked) == Qt.Checked: self.previewOnStartup.setCheckState(Qt.Checked) else: self.previewOnStartup.setCheckState(Qt.Unchecked) if (stgs.value("qgis2web/closeFeedbackOnSuccess", Qt.Checked) == Qt.Checked): self.closeFeedbackOnSuccess.setCheckState(Qt.Checked) else: self.closeFeedbackOnSuccess.setCheckState(Qt.Unchecked) self.previewFeatureLimit.setText( stgs.value("qgis2web/previewFeatureLimit", "1000")) self.paramsTreeOL.setSelectionMode(QAbstractItemView.SingleSelection) self.preview = None if webkit_available: widget = QWebView() self.preview = widget try: # if os.environ["TRAVIS"]: self.preview.setPage(WebPage()) except: print("Failed to set custom webpage") webview = self.preview.page() webview.setNetworkAccessManager(QgsNetworkAccessManager.instance()) self.preview.settings().setAttribute( QWebSettings.DeveloperExtrasEnabled, True) else: widget = QTextBrowser() widget.setText(self.tr('Preview is not available since QtWebKit ' 'dependency is missing on your system')) self.right_layout.insertWidget(0, widget) self.populateConfigParams(self) self.populate_layers_and_groups(self) self.populateLayerSearch() writer = WRITER_REGISTRY.createWriterFromProject() self.setStateToWriter(writer) self.exporter = EXPORTER_REGISTRY.createFromProject() self.exporter_combo.setCurrentIndex( self.exporter_combo.findText(self.exporter.name())) self.exporter_combo.currentIndexChanged.connect( self.exporterTypeChanged) self.toggleOptions() if webkit_available: if self.previewOnStartup.checkState() == Qt.Checked: self.autoUpdatePreview() self.buttonPreview.clicked.connect(self.previewMap) else: self.buttonPreview.setDisabled(True) self.layersTree.model().dataChanged.connect(self.populateLayerSearch) self.ol3.clicked.connect(self.changeFormat) self.leaflet.clicked.connect(self.changeFormat) self.buttonExport.clicked.connect(self.saveMap) helpText = os.path.join(os.path.dirname(os.path.realpath(__file__)), "helpFile.md") self.helpField.setSource(QUrl.fromLocalFile(helpText)) if webkit_available: self.devConsole = QWebInspector(self.verticalLayoutWidget_2) self.devConsole.setFixedHeight(0) self.devConsole.setObjectName("devConsole") self.devConsole.setPage(self.preview.page()) self.devConsole.hide() self.right_layout.insertWidget(1, self.devConsole) self.filter = devToggleFilter() self.filter.devToggle.connect(self.showHideDevConsole) self.installEventFilter(self.filter) self.setModal(False) @pyqtSlot(bool) def showHideDevConsole(self, visible): self.devConsole.setVisible(visible) def changeFormat(self): self.autoUpdatePreview() self.toggleOptions() def exporterTypeChanged(self): new_exporter_name = self.exporter_combo.currentText() try: self.exporter = [ e for e in EXPORTER_REGISTRY.getExporters() if e.name() == new_exporter_name][0]() except: pass def currentMapFormat(self): """ Returns the currently selected map writer type """ return self.getWriterFactory().type() def getWriterFactory(self): """ Returns a factory to create the currently selected map writer """ if self.mapFormat.checkedButton() == self.ol3: return OpenLayersWriter elif self.mapFormat.checkedButton() == self.leaflet: return LeafletWriter def createWriter(self): """ Creates a writer object reflecting the current settings in the dialog """ writer = self.getWriterFactory()() (writer.layers, writer.groups, writer.popup, writer.visible, writer.json, writer.cluster, writer.getFeatureInfo) = self.getLayersAndGroups() writer.params = self.getParameters() return writer def showErrorMessage(self, error): """ Shows an error message in the preview window """ html = "<html>" html += "<head></head>" html += "<style>body {font-family: sans-serif;}</style>" html += "<body><h1>Error</h1>" html += "<p>qgis2web produced an error:</p><code>" html += error html += "</code></body></html>" if self.preview: self.preview.setHtml(html) def showFeedbackMessage(self, title, message): """ Shows a feedback message in the preview window """ html = "<html>" html += "<head></head>" html += "<style>body {font-family: sans-serif;}</style>" html += "<body><h1>{}</h1>".format(title) html += "<p>{}</p>".format(message) html += "</body></html>" if self.preview: self.preview.setHtml(html) def toggleOptions(self): currentWriter = self.getWriterFactory() for param, value in specificParams.items(): treeParam = self.paramsTreeOL.findItems(param, (Qt.MatchExactly | Qt.MatchRecursive))[0] if currentWriter == OpenLayersWriter: if value == "OL3": treeParam.setDisabled(False) else: treeParam.setDisabled(True) else: if value == "OL3": treeParam.setDisabled(True) else: treeParam.setDisabled(False) for option, value in specificOptions.items(): treeOptions = self.layersTree.findItems(option, (Qt.MatchExactly | Qt.MatchRecursive)) for treeOption in treeOptions: if currentWriter == OpenLayersWriter: if value == "OL3": treeOption.setDisabled(False) else: treeOption.setDisabled(True) else: if value == "OL3": treeOption.setDisabled(True) else: treeOption.setDisabled(False) def createPreview(self): writer = self.createWriter() return writer.write(self.iface, dest_folder=utils.tempFolder()).index_file def shouldAutoPreview(self): """ Returns a tuple, with a bool for whether the preview should automatically be generated, and a string for explanations as to why the preview cannot be automatically generated """ writer = self.createWriter() total_features = 0 for layer in writer.layers: if isinstance(layer, QgsVectorLayer): total_features += layer.featureCount() if total_features > int(self.previewFeatureLimit.text()): # Too many features => too slow! return (False, self.tr('<p>A large number of features are ' 'present in the map. Generating the ' 'preview may take some time.</p>' '<p>Click Update Preview to generate the ' 'preview anyway.</p>')) return (True, None) def autoUpdatePreview(self): """ Triggered when a preview will be automatically generated, i.e. not as a result of the user manually clicking the Update Preview button. """ (auto_preview, message) = self.shouldAutoPreview() if not auto_preview: self.showFeedbackMessage(self.tr('Preview Map'), message) else: self.previewMap() def previewMap(self): preview_file = self.createPreview() self.loadPreviewFile(preview_file) def saveMap(self): writer = self.createWriter() write_folder = self.exporter.exportDirectory() if not write_folder: return self.feedback.reset() self.feedback.show() results = writer.write(self.iface, dest_folder=write_folder, feedback=self.feedback) self.feedback.showFeedback('Success') if self.closeFeedbackOnSuccess.checkState() == Qt.Checked: self.feedback.close() result = self.exporter.postProcess(results, feedback=self.feedback) if result and (not os.environ.get('CI') and not os.environ.get('TRAVIS')): webbrowser.open_new_tab(self.exporter.destinationUrl()) def populate_layers_and_groups(self, dlg): """Populate layers on QGIS into our layers and group tree view.""" root_node = QgsProject.instance().layerTreeRoot() tree_groups = [] tree_layers = root_node.findLayers() self.layers_item = QTreeWidgetItem() self.layers_item.setText(0, "Layers and Groups") self.layersTree.setColumnCount(3) for tree_layer in tree_layers: layer = tree_layer.layer() if (layer.type() != QgsMapLayer.PluginLayer and layer.customProperty("ol_layer_type") is None): try: if layer.type() == QgsMapLayer.VectorLayer: testDump = layer.renderer().dump() layer_parent = tree_layer.parent() if layer_parent.parent() is None: item = TreeLayerItem(self.iface, layer, self.layersTree, dlg) self.layers_item.addChild(item) else: if layer_parent not in tree_groups: tree_groups.append(layer_parent) except: QgsMessageLog.logMessage(traceback.format_exc(), "qgis2web", level=Qgis.Critical) for tree_group in tree_groups: group_name = tree_group.name() group_layers = [ tree_layer.layer() for tree_layer in tree_group.findLayers()] item = TreeGroupItem(group_name, group_layers, self.layersTree) self.layers_item.addChild(item) self.layersTree.addTopLevelItem(self.layers_item) self.layersTree.expandAll() self.layersTree.resizeColumnToContents(0) self.layersTree.resizeColumnToContents(1) for i in range(self.layers_item.childCount()): item = self.layers_item.child(i) if item.checkState(0) != Qt.Checked: item.setExpanded(False) def populateLayerSearch(self): self.layer_search_combo.clear() self.layer_search_combo.addItem("None") (layers, groups, popup, visible, json, cluster, getFeatureInfo) = self.getLayersAndGroups() for count, layer in enumerate(layers): if layer.type() == layer.VectorLayer: options = [] fields = layer.fields() for f in fields: fieldIndex = fields.indexFromName(unicode(f.name())) editorWidget = layer.editorWidgetSetup(fieldIndex).type() if editorWidget == 'Hidden': continue options.append(unicode(f.name())) for option in options: displayStr = unicode(layer.name() + ": " + option) self.layer_search_combo.insertItem(0, displayStr) sln = utils.safeName(layer.name()) self.layer_search_combo.setItemData( self.layer_search_combo.findText(displayStr), sln + "_" + unicode(count)) def configureExporter(self): self.exporter.configure() def populateConfigParams(self, dlg): """ Populates the dialog with option items and widgets """ self.items = defaultdict(dict) tree = dlg.paramsTreeOL configure_export_action = QAction('...', self) configure_export_action.triggered.connect(self.configureExporter) params = getParams(configure_exporter_action=configure_export_action) for group, settings in params.items(): item = QTreeWidgetItem() item.setText(0, group) for param, value in settings.items(): subitem = self.createOptionItem(tree_widget=tree, parent_item=item, parameter=param, default_value=value) item.addChild(subitem) self.items[group][param] = subitem self.paramsTreeOL.addTopLevelItem(item) item.sortChildren(0, Qt.AscendingOrder) self.paramsTreeOL.expandAll() self.paramsTreeOL.resizeColumnToContents(0) self.paramsTreeOL.resizeColumnToContents(1) self.layer_search_combo.removeItem(1) def createOptionItem(self, tree_widget, parent_item, parameter, default_value): """create the tree item corresponding to an option parameter""" action = None if isinstance(default_value, dict): action = default_value['action'] default_value = default_value['option'] subitem = TreeSettingItem(parent_item, tree_widget, parameter, default_value, action) if parameter == 'Layer search': self.layer_search_combo = subitem.combo elif parameter == 'Exporter': self.exporter_combo = subitem.combo return subitem def setStateToWriter(self, writer): """ Sets the dialog state to match the specified writer """ self.selectMapFormat(writer) self.setStateToParams(writer.params) def setStateToParams(self, params): """ Sets the dialog state to match the specified parameters """ for group, settings in self.items.items(): for param, item in settings.items(): value = params[group][param] item.setValue(value) def selectMapFormat(self, writer): """ Updates dialog state to match the specified writer format """ self.ol3.setChecked(isinstance(writer, OpenLayersWriter)) self.leaflet.setChecked(isinstance(writer, LeafletWriter)) def loadPreviewFile(self, file): """ Loads a web based preview from a local file path """ self.previewUrl = QUrl.fromLocalFile(file) if self.preview: self.preview.settings().clearMemoryCaches() self.preview.setUrl(self.previewUrl) def getParameters(self): parameters = defaultdict(dict) for group, settings in self.items.items(): for param, item in settings.items(): parameters[group][param] = item.value() if param == "Layer search": parameters["Appearance"]["Search layer"] = ( self.layer_search_combo.itemData( self.layer_search_combo.currentIndex())) return parameters def saveParameters(self): """ Saves current dialog state to project """ WRITER_REGISTRY.saveWriterToProject(self.createWriter()) EXPORTER_REGISTRY.writeToProject(self.exporter) def getLayersAndGroups(self): layers = [] groups = {} popup = [] visible = [] json = [] cluster = [] getFeatureInfo = [] for i in range(self.layers_item.childCount()): item = self.layers_item.child(i) if isinstance(item, TreeLayerItem): if item.checkState(0) == Qt.Checked: layers.append(item.layer) popup.append(item.popup) visible.append(item.visible) json.append(item.json) cluster.append(item.cluster) getFeatureInfo.append(item.getFeatureInfo) else: group = item.name groupLayers = [] if item.checkState(0) != Qt.Checked: continue for layer in item.layers: groupLayers.append(layer) layers.append(layer) popup.append({}) if item.visible: visible.append(True) else: visible.append(False) if hasattr(item, "json") and item.json: json.append(True) else: json.append(False) if hasattr(item, "cluster") and item.cluster: cluster.append(True) else: cluster.append(False) if hasattr(item, "getFeatureInfo") and item.getFeatureInfo: getFeatureInfo.append(True) else: getFeatureInfo.append(False) groups[group] = groupLayers[::-1] return (layers[::-1], groups, popup[::-1], visible[::-1], json[::-1], cluster[::-1], getFeatureInfo[::-1]) def reject(self): self.saveParameters() (layers, groups, popup, visible, json, cluster, getFeatureInfo) = self.getLayersAndGroups() for layer, pop, vis in zip(layers, popup, visible): attrDict = {} for attr in pop: attrDict['attr'] = pop[attr] layer.setCustomProperty("qgis2web/popup/" + attr, pop[attr]) layer.setCustomProperty("qgis2web/Visible", vis) QSettings().setValue( "qgis2web/MainDialogGeometry", self.saveGeometry()) QSettings().setValue("qgis2web/previewOnStartup", self.previewOnStartup.checkState()) QSettings().setValue("qgis2web/closeFeedbackOnSuccess", self.closeFeedbackOnSuccess.checkState()) QSettings().setValue("qgis2web/previewFeatureLimit", self.previewFeatureLimit.text()) QDialog.close(self) def closeEvent(self, event): if self.devConsole or self.devConsole.isVisible() and self.preview: del self.devConsole del self.preview self.reject() event.accept()
def setupTab6(self, tab): """Advance widgets for preview panel""" container = QHBoxLayout() scrollArea = QScrollArea() scrollArea.setWidgetResizable(True) w = QWidget() w.setMinimumSize(QSize(400, 500)) layout = QVBoxLayout() w.setLayout(layout) scrollArea.setWidget(w) container.addWidget(scrollArea) tab.setLayout(container) # List lay = QHBoxLayout() layout.addLayout(lay) list1 = QListWidget() list1.addItems(["aaa", "bbb", "ccc"]) list2 = QListWidget() list2.addItem( QListWidgetItem(QIcon(":appres.img/Flag_blueHS.png"), "blue")) list2.addItem( QListWidgetItem(QIcon(":appres.img/Flag_redHS.png"), "red")) list2.addItem( QListWidgetItem(QIcon(":appres.img/Flag_greenHS.png"), "green")) list2.setViewMode(QListWidget.IconMode) lay.addWidget(list1) lay.addWidget(list2) # Table lay = QHBoxLayout() layout.addLayout(lay) t1 = QTableWidget() t1.setRowCount(3) t1.setColumnCount(3) for i in range(3): for j in range(3): t1.setItem(i, j, QTableWidgetItem(str((i + 1) * (j + 1)))) t1.item(i, j).setTextAlignment(Qt.AlignCenter) t1.setColumnWidth(0, 50) t1.setColumnWidth(1, 50) t1.setColumnWidth(2, 50) t1.setEditTriggers(QTableWidget.AllEditTriggers) t2 = QTableWidget() t2.setRowCount(3) t2.setColumnCount(3) t2.setHorizontalHeaderLabels(["Name", "Gender", "Age"]) t2.setVerticalHeaderLabels(["1st", "2rd", "3th"]) t2.setItem(0, 0, QTableWidgetItem("july")) c = QComboBox() c.addItems(["Male", "Famale"]) t2.setCellWidget(0, 1, c) t2.cellWidget(0, 1).setCurrentIndex(1) t2.setItem(0, 2, QTableWidgetItem("10")) t2.setItem(1, 0, QTableWidgetItem("john")) c = QComboBox() c.addItems(["Male", "Famale"]) c.setEditable(True) t2.setCellWidget(1, 1, c) t2.setItem(1, 2, QTableWidgetItem("11")) t2.resizeColumnsToContents() t2.setEditTriggers(QTableWidget.EditKeyPressed | QTableWidget.SelectedClicked | QTableWidget.AnyKeyPressed | QTableWidget.DoubleClicked) lay.addWidget(t1) lay.addWidget(t2) # Tree lay = QHBoxLayout() layout.addLayout(lay) tree1 = QTreeWidget() tree1.setColumnCount(2) tree1.setHeaderLabels(["Key", "Value"]) node1 = QTreeWidgetItem() node1.setText(0, "root") node1.setText(1, "0") node1.setIcon(0, QIcon(":appres.img/home.png")) tree1.addTopLevelItem(node1) node11 = QTreeWidgetItem() node11.setText(0, "child1") icon = QIcon(":appres.img/book_angle.png") icon.addPixmap(QPixmap(":appres.img/book_open.png"), QIcon.Normal, QIcon.On) node11.setIcon(0, icon) nodea = QTreeWidgetItem() nodea.setText(0, "red") nodea.setBackground(1, QBrush(Qt.red)) nodeb = QTreeWidgetItem() nodeb.setText(0, "gray") nodeb.setBackground(1, QBrush(Qt.gray)) nodec = QTreeWidgetItem() nodec.setText(0, "green") nodec.setBackground(1, QBrush(Qt.green)) node11.addChildren([nodea, nodeb, nodec]) node12 = QTreeWidgetItem() node12.setText(0, "child2") node12.setText(1, "child2") node13 = QTreeWidgetItem() node13.setText(0, "child3") node13.setText(1, "child3") node12.setIcon(0, icon) node13.setIcon(0, icon) node1.addChild(node11) node1.addChild(node12) node1.addChild(node13) tree1.expand(tree1.model().index(0, 0)) tree1.expandItem(node11) tree2 = QTreeView() folder = QDirModel() tree2.setModel(folder) lay.addWidget(tree1) lay.addWidget(tree2)
class tree(QWidget): '''Copied from Jiliang's Github: https://github.com/ligerliu/pyH5_GUI/blob/master/pyH5_GUI/NewTree.py ''' (FILE, FILE_PATH, H5GROUP) = range(3) def __init__(self): super().__init__() self.title = 'Tree of h5 data' self.left = 10 self.top = 10 self.width = 720 self.height = 640 self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.datalayout = QVBoxLayout() self.tree = QTreeWidget() header = QTreeWidgetItem(['File']) self.tree.setHeaderItem(header) self.datalayout.addWidget(self.tree) self.group_root = None def clear(self): self.tree.clear() def add_group(self, group): self.group_name = os.path.basename(group) self.group_file_path = group self.group_root = QTreeWidgetItem( self.tree, [self.group_name, self.group_file_path, '']) def add_file(self, h5file, group=None): self.h5_file_path = h5file self.f = h5py.File(h5file, 'r') self.filename = self.f.filename.split('/')[-1] if group is None: self.tree_root = QTreeWidgetItem( self.tree, [self.filename, self.h5_file_path, '']) self.add_branch(self.tree_root, self.f) else: #print('add group here') if self.group_root is None: self.add_group(group) hdf_branch = QTreeWidgetItem( [self.filename, self.h5_file_path, '']) print(self.filename, self.h5_file_path) self.group_root.addChild(hdf_branch) self.add_branch(hdf_branch, self.f) self.tree.setColumnWidth(0, 250) self.tree.setColumnWidth(1, 0) self.tree.setColumnWidth(2, 0) def add_branch(self, tree_root, h5file): for _ in h5file.keys(): #print(_) branch = QTreeWidgetItem([ str(h5file[_].name).split('/')[-1], str(self.h5_file_path), str(h5file[_].name) ]) tree_root.addChild(branch) if isinstance(h5file[_], h5py.Group): self.add_branch(branch, h5file[_]) @pyqtSlot(QTreeWidgetItem, int) def onItemClicked(self, item): print(self.filename, item.text(2))
class Worker: """ Manages remote workers and informs the user about the status of remote workers """ okFont = QFont() staleFont = QFont() staleFont.setItalic(True) # TODO: Make yellow errorFont = QFont() errorFont.setBold(True) # TODO: Make red def __init__(self, parent): self.parent = parent self.workerAccepted = False # Whether or not the worker accepted the controller self.workerTreeItem = QTreeWidgetItem() self.monitorState = {} self.inbuf = "" self.connection = None self.requestJar = {} # Refresh monitors every 5 seconds self.monitorTimer = QTimer() self.monitorTimer.timeout.connect(self.requestMonitors) self.monitorTimer.start(5000) # self.errorIcon = QIcon("resources/icons/exclamation.png") def messagecallback(self, message): self.inbuf += message self.parseInbuf() def createTreeitem(self): self.workerTreeItem.setText(0, str(self.connection.ip) + ":" + str(self.connection.port)) self.parent.workerDockWidget.workerTree.addTopLevelItem(self.workerTreeItem) def __del__(self): if self.workerTreeItem is not None: self.parent.workerDockWidget.workerTree.invisibleRootItem().removeChild(self.workerTreeItem) def parseInbuf(self): if self.inbuf: splitbuf = self.inbuf.split("\n") messageToProcess = "" if len(splitbuf) > 1: messageToProcess = splitbuf[0] self.inbuf = str.join("\n", splitbuf[1:]) if messageToProcess: self.processMessage(messageToProcess) def processMessage(self, message): try: message = json.loads(message) except json.JSONDecodeError: return # TODO: output error try: if not (isinstance(message["status"][0], str) and isinstance(message["status"][1], int)): raise TypeError() except KeyError: return # TODO: output error except TypeError: return # TODO: output error except IndexError: return # TODO: Check for msgid # Parse ok messages if message["status"][0] == "ok": if message["status"][1] == 0: if "message" in message: print("Warning: Received unknown 'ok' code: " + str(message["message"])) else: print("Warning: Received unknown 'ok' code. No human readable message included.") elif message["status"][1] == 1: self.workerAccepted = True print("Accpeted by worker") self.createTreeitem() self.requestMonitors() self.workerTreeItem.setExpanded(True) # Automatically expand it on creation self.connected() # Parse error messages if message["status"][0] == "error": if message["status"][1] == 0: print("Received") elif message["status"][1] == 1: self.workerAccepted = False self.createTreeitem() self.connectionLost() print("Rejected by worker") # Parse reply messages if "reply" in message and "refid" in message: if "datareply" in message["reply"]: # Handle datareplies if message["refid"] in self.requestJar: # Check if reply can be correlated to a request if "datarequest" in self.requestJar[message["refid"]] and "datareply" in message["reply"]: # Request was a datarequest if self.requestJar[message["refid"]]["datarequest"] == "monitors": # Request was a request for monitors self.monitors = message["reply"]["datareply"] self.handleMonitors() del self.requestJar[message["refid"]] # Delete request from requestJar else: print("Error: Unknown refid in reply: " + str(message["refid"])) return def requestMonitors(self): if not self.connection.valid: self.connection.reconnect() if self.connection.valid: self.connected() if self.workerAccepted: request = {"msgid": uuid.uuid4().hex, "status":["command", 0], "command":{"datarequest":"monitors"}} self.requestJar[request["msgid"]] = request["command"] self.connection.outbuf += json.dumps(request) + "\n" def handleMonitors(self): for monitor in self.monitors: if monitor not in self.monitorState: monitorTreeitem = QTreeWidgetItem() monitorTreeitem.setText(0, monitor) self.workerTreeItem.addChild(monitorTreeitem) self.monitorState[monitor] = {"state": "new", "treeitem": monitorTreeitem, "sheet": None} self.monitorState[monitor]["sheet"] = self.parent.sheethandler.newMonitorSheet(str(self.connection.ip) + ":" + str(self.connection.port) + " - " + monitor, monitorTreeitem) for key in self.monitorState: if key in self.monitors: self.monitorState[key]["state"] = "ok" else: self.monitorState[key]["state"] = "stale" self.monitorState[key]["treeitem"].setFont(0, Worker.staleFont) def connectionLost(self): self.workerTreeItem.setFont(0, Worker.errorFont) self.workerTreeItem.setIcon(0, self.errorIcon) self.workerTreeItem.setToolTip(0, "Connection lost...") self.monitors = [] self.handleMonitors() def connected(self): """ Called when connection is successfully established """ self.workerTreeItem.setFont(0, Worker.okFont) self.workerTreeItem.setIcon(0, QIcon()) self.workerTreeItem.setToolTip(0, "Worker in good health") def startRepeat(self, monitor): """ Start monitor code execution. If it's already running, restart it from scratch. """ request = {"msgid": uuid.uuid4().hex, "status": ["command", 0], "command": {"monitor": monitor, "setrunning": "start"}} self.connection.outbuf += json.dumps(request) + "\n" self.monitorState[monitor]["state"] = "ok" def stop(self, monitor): """ Stop monitor code execution. """ request = {"msgid": uuid.uuid4().hex, "status": ["command", 0], "command": {"monitor": monitor, "setrunning": "stop"}} self.connection.outbuf += json.dumps(request) + "\n" self.monitorState[monitor]["state"] = "stopped"
class TaskViewer(QTreeWidget): """ Class implementing the task viewer. @signal displayFile(str, int) emitted to go to a file task """ displayFile = pyqtSignal(str, int) def __init__(self, parent, project): """ Constructor @param parent the parent (QWidget) @param project reference to the project object """ super(TaskViewer, self).__init__(parent) self.setSortingEnabled(True) self.setExpandsOnDoubleClick(False) self.__headerItem = QTreeWidgetItem( ["", "", self.tr("Summary"), self.tr("Filename"), self.tr("Line"), ""]) self.__headerItem.setIcon( 0, UI.PixmapCache.getIcon("taskCompleted.png")) self.__headerItem.setIcon( 1, UI.PixmapCache.getIcon("taskPriority.png")) self.setHeaderItem(self.__headerItem) self.header().setSortIndicator(2, Qt.AscendingOrder) self.__resizeColumns() self.tasks = [] self.copyTask = None self.projectOpen = False self.project = project self.projectTasksScanFilter = "" from .TaskFilter import TaskFilter self.taskFilter = TaskFilter() self.taskFilter.setActive(False) self.__projectTasksSaveTimer = AutoSaver(self, self.saveProjectTasks) self.__projectTasksMenu = QMenu( self.tr("P&roject Tasks"), self) self.__projectTasksMenu.addAction( self.tr("&Regenerate project tasks"), self.__regenerateProjectTasks) self.__projectTasksMenu.addSeparator() self.__projectTasksMenu.addAction( self.tr("&Configure scan options"), self.__configureProjectTasksScanOptions) self.__menu = QMenu(self) self.__menu.addAction(self.tr("&New Task..."), self.__newTask) self.subtaskItem = self.__menu.addAction( self.tr("New &Sub-Task..."), self.__newSubTask) self.__menu.addSeparator() self.projectTasksMenuItem = self.__menu.addMenu( self.__projectTasksMenu) self.__menu.addSeparator() self.gotoItem = self.__menu.addAction( self.tr("&Go To"), self.__goToTask) self.__menu.addSeparator() self.copyItem = self.__menu.addAction( self.tr("&Copy"), self.__copyTask) self.pasteItem = self.__menu.addAction( self.tr("&Paste"), self.__pasteTask) self.pasteMainItem = self.__menu.addAction( self.tr("Paste as &Main Task"), self.__pasteMainTask) self.deleteItem = self.__menu.addAction( self.tr("&Delete"), self.__deleteTask) self.__menu.addSeparator() self.markCompletedItem = self.__menu.addAction( self.tr("&Mark Completed"), self.__markCompleted) self.__menu.addAction( self.tr("Delete Completed &Tasks"), self.__deleteCompleted) self.__menu.addSeparator() self.__menu.addAction( self.tr("P&roperties..."), self.__editTaskProperties) self.__menu.addSeparator() self.__menuFilteredAct = self.__menu.addAction( self.tr("&Filtered display")) self.__menuFilteredAct.setCheckable(True) self.__menuFilteredAct.setChecked(False) self.__menuFilteredAct.triggered[bool].connect(self.__activateFilter) self.__menu.addAction( self.tr("Filter c&onfiguration..."), self.__configureFilter) self.__menu.addSeparator() self.__menu.addAction( self.tr("Resi&ze columns"), self.__resizeColumns) self.__menu.addSeparator() self.__menu.addAction(self.tr("Configure..."), self.__configure) self.__backMenu = QMenu(self) self.__backMenu.addAction(self.tr("&New Task..."), self.__newTask) self.__backMenu.addSeparator() self.backProjectTasksMenuItem = self.__backMenu.addMenu( self.__projectTasksMenu) self.__backMenu.addSeparator() self.backPasteItem = self.__backMenu.addAction( self.tr("&Paste"), self.__pasteTask) self.backPasteMainItem = self.__backMenu.addAction( self.tr("Paste as &Main Task"), self.__pasteMainTask) self.__backMenu.addSeparator() self.backDeleteCompletedItem = self.__backMenu.addAction( self.tr("Delete Completed &Tasks"), self.__deleteCompleted) self.__backMenu.addSeparator() self.__backMenuFilteredAct = self.__backMenu.addAction( self.tr("&Filtered display")) self.__backMenuFilteredAct.setCheckable(True) self.__backMenuFilteredAct.setChecked(False) self.__backMenuFilteredAct.triggered[bool].connect( self.__activateFilter) self.__backMenu.addAction( self.tr("Filter c&onfiguration..."), self.__configureFilter) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Resi&ze columns"), self.__resizeColumns) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Configure..."), self.__configure) self.__activating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.itemActivated.connect(self.__taskItemActivated) self.setWindowIcon(UI.PixmapCache.getIcon("pymakr.png")) self.__generateTopLevelItems() def __generateTopLevelItems(self): """ Private method to generate the 'Extracted Tasks' item. """ self.__extractedItem = QTreeWidgetItem(self, [self.tr("Extracted Tasks")]) self.__manualItem = QTreeWidgetItem(self, [self.tr("Manual Tasks")]) for itm in [self.__extractedItem, self.__manualItem]: itm.setFirstColumnSpanned(True) itm.setExpanded(True) itm.setHidden(True) font = itm.font(0) font.setUnderline(True) itm.setFont(0, font) def __checkTopLevelItems(self): """ Private slot to check the 'Extracted Tasks' item for children. """ for itm in [self.__extractedItem, self.__manualItem]: visibleCount = itm.childCount() for index in range(itm.childCount()): if itm.child(index).isHidden(): visibleCount -= 1 itm.setHidden(visibleCount == 0) def __resort(self): """ Private method to resort the tree. """ self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.header().resizeSections(QHeaderView.ResizeToContents) self.header().setStretchLastSection(True) def findParentTask(self, parentUid): """ Public method to find a parent task by its ID. @param parentUid uid of the parent task (string) @return reference to the task (Task) """ if not parentUid: return None parentTask = None for task in self.tasks: if task.getUuid() == parentUid: parentTask = task break return parentTask def __refreshDisplay(self): """ Private method to refresh the display. """ for task in self.tasks: task.setHidden(not self.taskFilter.showTask(task)) self.__checkTopLevelItems() self.__resort() self.__resizeColumns() def __taskItemActivated(self, itm, col): """ Private slot to handle the activation of an item. @param itm reference to the activated item (QTreeWidgetItem) @param col column the item was activated in (integer) """ if not self.__activating and \ itm is not self.__extractedItem and \ itm is not self.__manualItem: self.__activating = True fn = itm.getFilename() if fn: self.displayFile.emit(fn, itm.getLineno()) else: self.__editTaskProperties() self.__activating = False def __showContextMenu(self, coord): """ Private slot to show the context menu of the list. @param coord the position of the mouse pointer (QPoint) """ itm = self.itemAt(coord) coord = self.mapToGlobal(coord) if itm is None or \ itm is self.__extractedItem or \ itm is self.__manualItem: self.backProjectTasksMenuItem.setEnabled(self.projectOpen) if self.copyTask: self.backPasteItem.setEnabled(True) self.backPasteMainItem.setEnabled(True) else: self.backPasteItem.setEnabled(False) self.backPasteMainItem.setEnabled(False) self.backDeleteCompletedItem.setEnabled( bool(self.tasks)) self.__backMenu.popup(coord) else: self.projectTasksMenuItem.setEnabled(self.projectOpen) if itm.getFilename(): self.gotoItem.setEnabled(True) self.deleteItem.setEnabled(True) self.markCompletedItem.setEnabled(False) self.copyItem.setEnabled(False) self.subtaskItem.setEnabled(False) else: self.gotoItem.setEnabled(False) self.deleteItem.setEnabled(True) self.markCompletedItem.setEnabled(True) self.copyItem.setEnabled(True) self.subtaskItem.setEnabled(True) if self.copyTask: self.pasteItem.setEnabled(True) self.pasteMainItem.setEnabled(True) else: self.pasteItem.setEnabled(False) self.pasteMainItem.setEnabled(False) self.__menu.popup(coord) def setProjectOpen(self, o=False): """ Public slot to set the project status. @param o flag indicating the project status """ self.projectOpen = o def addTask(self, summary, priority=1, filename="", lineno=0, completed=False, _time=0, isProjectTask=False, taskType=Task.TypeTodo, description="", uid="", parentTask=None): """ Public slot to add a task. @param summary summary text of the task (string) @param priority priority of the task (0=high, 1=normal, 2=low) @param filename filename containing the task (string) @param lineno line number containing the task (integer) @param completed flag indicating completion status (boolean) @param _time creation time of the task (float, if 0 use current time) @param isProjectTask flag indicating a task related to the current project (boolean) @param taskType type of the task (one of Task.TypeFixme, Task.TypeTodo, Task.TypeWarning, Task.TypeNote) @param description explanatory text of the task (string) @param uid unique id of the task (string) @param parentTask reference to the parent task item (Task) @return reference to the task item (Task) """ if parentTask: parentUid = parentTask.getUuid() else: parentUid = "" task = Task(summary, priority, filename, lineno, completed, _time, isProjectTask, taskType, self.project, description, uid, parentUid) self.tasks.append(task) if parentTask: parentTask.addChild(task) parentTask.setExpanded(True) elif filename: self.__extractedItem.addChild(task) else: self.__manualItem.addChild(task) task.setHidden(not self.taskFilter.showTask(task)) self.__checkTopLevelItems() self.__resort() self.__resizeColumns() if isProjectTask: self.__projectTasksSaveTimer.changeOccurred() return task def addFileTask(self, summary, filename, lineno, taskType=Task.TypeTodo, description=""): """ Public slot to add a file related task. @param summary summary text of the task (string) @param filename filename containing the task (string) @param lineno line number containing the task (integer) @param taskType type of the task (one of Task.TypeFixme, Task.TypeTodo, Task.TypeWarning, Task.TypeNote) @param description explanatory text of the task (string) """ self.addTask(summary, filename=filename, lineno=lineno, isProjectTask=( self.project and self.project.isProjectSource(filename)), taskType=taskType, description=description) def getProjectTasks(self): """ Public method to retrieve all project related tasks. @return copy of tasks (list of Task) """ tasks = [task for task in self.tasks if task.isProjectTask()] return tasks[:] def getGlobalTasks(self): """ Public method to retrieve all non project related tasks. @return copy of tasks (list of Task) """ tasks = [task for task in self.tasks if not task.isProjectTask()] return tasks[:] def clearTasks(self): """ Public slot to clear all tasks from display. """ self.tasks = [] self.clear() self.__generateTopLevelItems() def clearProjectTasks(self, fileOnly=False): """ Public slot to clear project related tasks. @keyparam fileOnly flag indicating to clear only file related project tasks (boolean) """ for task in reversed(self.tasks[:]): if (fileOnly and task.isProjectFileTask()) or \ (not fileOnly and task.isProjectTask()): if self.copyTask == task: self.copyTask = None parent = task.parent() parent.removeChild(task) self.tasks.remove(task) del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() def clearFileTasks(self, filename, conditionally=False): """ Public slot to clear all tasks related to a file. @param filename name of the file (string) @param conditionally flag indicating to clear the tasks of the file checking some conditions (boolean) """ if conditionally: if self.project and self.project.isProjectSource(filename): # project related tasks will not be cleared return if not Preferences.getTasks("ClearOnFileClose"): return for task in self.tasks[:]: if task.getFilename() == filename: if self.copyTask == task: self.copyTask = None self.__extractedItem.removeChild(task) self.tasks.remove(task) if task.isProjectTask: self.__projectTasksSaveTimer.changeOccurred() del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() def __editTaskProperties(self): """ Private slot to handle the "Properties" context menu entry. """ from .TaskPropertiesDialog import TaskPropertiesDialog task = self.currentItem() dlg = TaskPropertiesDialog(task, self, self.projectOpen) ro = task.getFilename() != "" if ro: dlg.setReadOnly() if dlg.exec_() == QDialog.Accepted and not ro: summary, priority, completed, isProjectTask, description = \ dlg.getData() task.setSummary(summary) task.setPriority(priority) task.setCompleted(completed) task.setProjectTask(isProjectTask) task.setDescription(description) self.__projectTasksSaveTimer.changeOccurred() def __newTask(self): """ Private slot to handle the "New Task" context menu entry. """ from .TaskPropertiesDialog import TaskPropertiesDialog dlg = TaskPropertiesDialog(None, self, self.projectOpen) if dlg.exec_() == QDialog.Accepted: summary, priority, completed, isProjectTask, description = \ dlg.getData() self.addTask(summary, priority, completed=completed, isProjectTask=isProjectTask, description=description) def __newSubTask(self): """ Private slot to handle the "New Sub-Task" context menu entry. """ parentTask = self.currentItem() projectTask = parentTask.isProjectTask() from .TaskPropertiesDialog import TaskPropertiesDialog dlg = TaskPropertiesDialog(None, self, self.projectOpen) dlg.setSubTaskMode(projectTask) if dlg.exec_() == QDialog.Accepted: summary, priority, completed, isProjectTask, description = \ dlg.getData() self.addTask(summary, priority, completed=completed, isProjectTask=isProjectTask, description=description, parentTask=parentTask) def __markCompleted(self): """ Private slot to handle the "Mark Completed" context menu entry. """ task = self.currentItem() task.setCompleted(True) def __deleteCompleted(self): """ Private slot to handle the "Delete Completed Tasks" context menu entry. """ for task in reversed(self.tasks[:]): if task.isCompleted(): if self.copyTask == task: self.copyTask = None parent = task.parent() parent.removeChild(task) self.tasks.remove(task) if task.isProjectTask: self.__projectTasksSaveTimer.changeOccurred() del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() ci = self.currentItem() if ci: ind = self.indexFromItem(ci, self.currentColumn()) self.scrollTo(ind, QAbstractItemView.PositionAtCenter) def __copyTask(self): """ Private slot to handle the "Copy" context menu entry. """ task = self.currentItem() self.copyTask = task def __pasteTask(self): """ Private slot to handle the "Paste" context menu entry. """ if self.copyTask: parent = self.copyTask.parent() if not isinstance(parent, Task): parent = None self.addTask(self.copyTask.summary, priority=self.copyTask.priority, completed=self.copyTask.completed, description=self.copyTask.description, isProjectTask=self.copyTask._isProjectTask, parentTask=parent) def __pasteMainTask(self): """ Private slot to handle the "Paste as Main Task" context menu entry. """ if self.copyTask: self.addTask(self.copyTask.summary, priority=self.copyTask.priority, completed=self.copyTask.completed, description=self.copyTask.description, isProjectTask=self.copyTask._isProjectTask) def __deleteSubTasks(self, task): """ Private method to delete all sub-tasks. @param task task to delete sub-tasks of (Task) """ for subtask in task.takeChildren(): if self.copyTask == subtask: self.copyTask = None if subtask.childCount() > 0: self.__deleteSubTasks(subtask) self.tasks.remove(subtask) def __deleteTask(self): """ Private slot to handle the "Delete Task" context menu entry. """ task = self.currentItem() if self.copyTask == task: self.copyTask = None if task.childCount() > 0: self.__deleteSubTasks(task) parent = task.parent() parent.removeChild(task) self.tasks.remove(task) if task.isProjectTask: self.__projectTasksSaveTimer.changeOccurred() del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() ci = self.currentItem() if ci: ind = self.indexFromItem(ci, self.currentColumn()) self.scrollTo(ind, QAbstractItemView.PositionAtCenter) def __goToTask(self): """ Private slot to handle the "Go To" context menu entry. """ task = self.currentItem() self.displayFile.emit(task.getFilename(), task.getLineno()) def handlePreferencesChanged(self): """ Public slot to react to changes of the preferences. """ for task in self.tasks: task.colorizeTask() def __activateFilter(self, on): """ Private slot to handle the "Filtered display" context menu entry. @param on flag indicating the filter state (boolean) """ if on and not self.taskFilter.hasActiveFilter(): res = E5MessageBox.yesNo( self, self.tr("Activate task filter"), self.tr( """The task filter doesn't have any active filters.""" """ Do you want to configure the filter settings?"""), yesDefault=True) if not res: on = False else: self.__configureFilter() on = self.taskFilter.hasActiveFilter() self.taskFilter.setActive(on) self.__menuFilteredAct.setChecked(on) self.__backMenuFilteredAct.setChecked(on) self.__refreshDisplay() def __configureFilter(self): """ Private slot to handle the "Configure filter" context menu entry. """ from .TaskFilterConfigDialog import TaskFilterConfigDialog dlg = TaskFilterConfigDialog(self.taskFilter) if dlg.exec_() == QDialog.Accepted: dlg.configureTaskFilter(self.taskFilter) self.__refreshDisplay() def __configureProjectTasksScanOptions(self): """ Private slot to configure scan options for project tasks. """ filter, ok = QInputDialog.getText( self, self.tr("Scan Filter Patterns"), self.tr("Enter filename patterns of files" " to be excluded separated by a comma:"), QLineEdit.Normal, self.projectTasksScanFilter) if ok: self.projectTasksScanFilter = filter def __regenerateProjectTasks(self): """ Private slot to handle the "Regenerated project tasks" context menu entry. """ markers = { Task.TypeWarning: Preferences.getTasks("TasksWarningMarkers").split(), Task.TypeNote: Preferences.getTasks("TasksNoteMarkers").split(), Task.TypeTodo: Preferences.getTasks("TasksTodoMarkers").split(), Task.TypeFixme: Preferences.getTasks("TasksFixmeMarkers").split(), } files = self.project.pdata["SOURCES"] # apply file filter filterList = [f.strip() for f in self.projectTasksScanFilter.split(",") if f.strip()] if filterList: for filter in filterList: files = [f for f in files if not fnmatch.fnmatch(f, filter)] # remove all project tasks self.clearProjectTasks(fileOnly=True) # now process them progress = E5ProgressDialog( self.tr("Extracting project tasks..."), self.tr("Abort"), 0, len(files), self.tr("%v/%m Files")) progress.setMinimumDuration(0) progress.setWindowTitle(self.tr("Tasks")) count = 0 for file in files: progress.setLabelText( self.tr("Extracting project tasks...\n{0}").format(file)) progress.setValue(count) QApplication.processEvents() if progress.wasCanceled(): break fn = os.path.join(self.project.ppath, file) # read the file and split it into textlines try: text, encoding = Utilities.readEncodedFile(fn) lines = text.splitlines() except (UnicodeError, IOError): count += 1 progress.setValue(count) continue # now search tasks and record them lineIndex = 0 for line in lines: lineIndex += 1 shouldBreak = False for taskType, taskMarkers in markers.items(): for taskMarker in taskMarkers: index = line.find(taskMarker) if index > -1: task = line[index:] self.addFileTask(task, fn, lineIndex, taskType) shouldBreak = True break if shouldBreak: break count += 1 progress.setValue(len(files)) def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("tasksPage") def saveProjectTasks(self): """ Public method to write the project tasks. """ if self.projectOpen and Preferences.getTasks("TasksProjectAutoSave"): self.project.writeTasks()
def _troubleshoot_complete(): _ = self.appdata._ results = self.thread.result self.loading.close() if results == None: self.widgets.open_dialog( self.widgets.dialog_warning, _("Troubleshooting Failed"), _("The troubleshooter for this backend is not available for this operating system." )) return elif results == str: self.widgets.open_dialog( self.widgets.dialog_error, _("Troubleshooting Failed"), _("The troubleshooter was not expecting that! The process failed as an exception was thrown." ), None, results) return self.result_window = shared.get_ui_widget(self.appdata, "troubleshooter", QDialog) label = self.result_window.findChild(QLabel, "Title") tree = self.result_window.findChild(QTreeWidget, "Results") column = tree.invisibleRootItem() if not self.appdata.system_qt_theme: self.result_window.findChild(QPushButton, "Close").setIcon( self.widgets.get_icon_qt("general", "close")) all_passed = True for result in results: item = QTreeWidgetItem() item.setText(0, _("Passed") if result["passed"] else _("Failed")) item.setText(1, result["test_name"]) item.setIcon(0, QIcon(common.get_icon("general", "success"))) # Provide suggestions on failures if not result["passed"]: item.setIcon(0, QIcon(common.get_icon("general", "serious"))) all_passed = False suggestion = result["suggestion"].split(". ") for line in suggestion: subitem = QTreeWidgetItem() subitem.setText(1, "• " + line) subitem.setToolTip(1, line) subitem.setDisabled(True) item.addChild(subitem) column.addChild(item) def _close_troubleshooter(): self.result_window.close() self.result_window.findChild( QPushButton, "Close").clicked.connect(_close_troubleshooter) tree.expandAll() self.result_window.setWindowTitle( _("Troubleshooter for []").replace("[]", self.human_name)) if all_passed: label.setText(_("Everything appears to be in working order!")) self.result_window.open()
import sys from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QApplication, QWidget if __name__ == '__main__': app = 0 if QApplication.instance(): app = QApplication.instance() else: app = QApplication(sys.argv) l1 = QTreeWidgetItem(["String A", "String B", "String C"]) l2 = QTreeWidgetItem(["String AA", "String BB", "String CC"]) for i in range(3): l1_child = QTreeWidgetItem(["Child A" + str(i), "Child B" + str(i), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): l2_child = QTreeWidgetItem(["Child AA" + str(j), "Child BB" + str(j), "Child CC" + str(j)]) l2.addChild(l2_child) w = QWidget() w.resize(510, 210) tw = QTreeWidget(w) tw.resize(500, 200) tw.setColumnCount(3) tw.setHeaderLabels(["Column 1", "Column 2", "Column 3"]) tw.addTopLevelItem(l1) tw.addTopLevelItem(l2)
def on_update(self): self.wallet = self.parent.wallet item = self.currentItem() current_address = item.data(0, Qt.UserRole) if item else None self.clear() receiving_addresses = self.wallet.get_receiving_addresses() change_addresses = self.wallet.get_change_addresses() if self.parent.fx and self.parent.fx.get_fiat_address_config(): fx = self.parent.fx else: fx = None account_item = self sequences = [0, 1] if change_addresses else [0] for is_change in sequences: if len(sequences) > 1: name = _("Receiving") if not is_change else _("Change") seq_item = QTreeWidgetItem([name, '', '', '', '']) account_item.addChild(seq_item) if not is_change: seq_item.setExpanded(True) else: seq_item = account_item used_item = QTreeWidgetItem([_("Used"), '', '', '', '']) used_flag = False addr_list = change_addresses if is_change else receiving_addresses for address in addr_list: num = len(self.wallet.get_address_history(address)) is_used = self.wallet.is_used(address) balance = sum(self.wallet.get_addr_balance(address)) address_text = address.to_ui_string() label = self.wallet.labels.get(address.to_storage_string(), '') balance_text = self.parent.format_amount(balance, whitespaces=True) columns = [address_text, label, balance_text, "%d" % num] if fx: rate = fx.exchange_rate() fiat_balance = fx.value_str(balance, rate) columns.insert(3, fiat_balance) address_item = QTreeWidgetItem(columns) address_item.setTextAlignment(2, Qt.AlignRight) address_item.setFont(2, QFont(MONOSPACE_FONT)) if fx: address_item.setTextAlignment(3, Qt.AlignRight) address_item.setFont(3, QFont(MONOSPACE_FONT)) address_item.setFont(0, QFont(MONOSPACE_FONT)) address_item.setData(0, Qt.UserRole, address) address_item.setData(0, Qt.UserRole + 1, True) # label can be edited if self.wallet.is_frozen(address): address_item.setBackground(0, QColor('lightblue')) if self.wallet.is_beyond_limit(address, is_change): address_item.setBackground(0, QColor('red')) if is_used: if not used_flag: seq_item.insertChild(0, used_item) used_flag = True used_item.addChild(address_item) else: seq_item.addChild(address_item) if address == current_address: self.setCurrentItem(address_item)
def summary(self, view): """ Displays a summary of classifier performance. The summary is organized in a tree structure. :param view: the widget where the summary is displayed :type view: QTreeWidget """ view.clear() name_item = QTreeWidgetItem(view) name_item.setText(0, 'Name') name_item.setText(1, self.name()) name_item.setToolTip(1, self.name()) type_item = QTreeWidgetItem(view) type_item.setText(0, 'Type') type_item.setText(1, self.type()) params_item = QTreeWidgetItem(view) params_item.setText(0, 'Parameters') # show classifier hyperparameters params = self.params() for param in params: param_item = QTreeWidgetItem() param_item.setText(0, param) param_item.setToolTip(0, param) value = params[param] if value == None: param_item.setText(1, 'None') else: param_item.setText(1, str(value)) params_item.addChild(param_item) metrics_item = QTreeWidgetItem(view) metrics_item.setText(0, 'Performance') # show metrics on training data train_metrics_item = QTreeWidgetItem(metrics_item) train_metrics_item.setText(0, 'Training') train_metrics = self.metrics('train') train_metrics.summary(train_metrics_item) # show metrics on validation data val_metrics_item = QTreeWidgetItem(metrics_item) val_metrics_item.setText(0, 'Validation') val_metrics = self.metrics('val') if val_metrics is not None: val_metrics.summary(val_metrics_item) # show metrics on test data test_metrics = self.metrics('test') if test_metrics is not None: test_metrics_item = QTreeWidgetItem(metrics_item) test_metrics_item.setText(0, 'Test') test_metrics.summary(test_metrics_item) comment_item = QTreeWidgetItem(view) comment_item.setText(0, 'Comment') comment_text_item = QTreeWidgetItem(comment_item) comment_text_item.setFirstColumnSpanned(True) comment_text_item.setText(0, self.comment())
def on_update(self): def item_path( item ): # Recursively builds the path for an item eg 'parent_name/item_name' return item.text(0) if not item.parent() else item_path( item.parent()) + "/" + item.text(0) def remember_expanded_items(root): # Save the set of expanded items... so that address list updates don't annoyingly collapse # our tree list widget due to the update. This function recurses. Pass self.invisibleRootItem(). expanded_item_names = set() for i in range(0, root.childCount()): it = root.child(i) if it and it.childCount(): if it.isExpanded(): expanded_item_names.add(item_path(it)) expanded_item_names |= remember_expanded_items( it) # recurse return expanded_item_names def restore_expanded_items(root, expanded_item_names): # Recursively restore the expanded state saved previously. Pass self.invisibleRootItem(). for i in range(0, root.childCount()): it = root.child(i) if it and it.childCount(): restore_expanded_items( it, expanded_item_names) # recurse, do leaves first old = bool(it.isExpanded()) new = bool(item_path(it) in expanded_item_names) if old != new: it.setExpanded(new) if not self._ca_cb_registered and self.wallet.network: self.wallet.network.register_callback( self._ca_updated_minimal_chash_callback, ['ca_updated_minimal_chash']) self._ca_cb_registered = True had_item_count = self.topLevelItemCount() sels = self.selectedItems() addresses_to_re_select = { item.data(0, self.DataRoles.address) for item in sels } expanded_item_names = remember_expanded_items(self.invisibleRootItem()) del sels # avoid keeping reference to about-to-be delete C++ objects self.clear() # Note we take a shallow list-copy because we want to avoid # race conditions with the wallet while iterating here. The wallet may # touch/grow the returned lists at any time if a history comes (it # basically returns a reference to its own internal lists). The wallet # may then, in another thread such as the Synchronizer thread, grow # the receiving or change addresses on Deterministic wallets. While # probably safe in a language like Python -- and especially since # the lists only grow at the end, we want to avoid bad habits. # The performance cost of the shallow copy below is negligible for 10k+ # addresses even on huge wallets because, I suspect, internally CPython # does this type of operation extremely cheaply (probably returning # some copy-on-write-semantics handle to the same list). receiving_addresses = list(self.wallet.get_receiving_addresses()) change_addresses = list(self.wallet.get_change_addresses()) if self.parent.fx and self.parent.fx.get_fiat_address_config(): fx = self.parent.fx else: fx = None account_item = self sequences = [0, 1] if change_addresses else [0] items_to_re_select = [] for is_change in sequences: if len(sequences) > 1: name = _("Receiving") if not is_change else _("Change") seq_item = QTreeWidgetItem([name, '', '', '', '', '']) account_item.addChild(seq_item) if not had_item_count: # first time we create this widget, auto-expand the default address list seq_item.setExpanded(True) expanded_item_names.add(item_path(seq_item)) else: seq_item = account_item hidden_item = QTreeWidgetItem( [_("Empty") if is_change else _("Used"), '', '', '', '', '']) has_hidden = False addr_list = change_addresses if is_change else receiving_addresses # Cash Account support - we do this here with the already-prepared addr_list for performance reasons ca_list_all = self.wallet.cashacct.get_cashaccounts(addr_list) ca_by_addr = defaultdict(list) for info in ca_list_all: ca_by_addr[info.address].append(info) del ca_list_all # / cash account for n, address in enumerate(addr_list): num = len(self.wallet.get_address_history(address)) if is_change: is_hidden = self.wallet.is_empty(address) else: is_hidden = self.wallet.is_used(address) balance = sum(self.wallet.get_addr_balance(address)) address_text = address.to_ui_string() # Cash Accounts ca_info, ca_list = None, ca_by_addr.get(address) if ca_list: # Add Cash Account emoji -- the emoji used is the most # recent cash account registration for said address ca_list.sort( key=lambda x: ((x.number or 0), str(x.collision_hash))) for ca in ca_list: # grab minimal_chash and stash in an attribute. this may kick off the network ca.minimal_chash = self.wallet.cashacct.get_minimal_chash( ca.name, ca.number, ca.collision_hash) ca_info = self._ca_get_default(ca_list) if ca_info: address_text = ca_info.emoji + " " + address_text # /Cash Accounts label = self.wallet.labels.get(address.to_storage_string(), '') balance_text = self.parent.format_amount(balance, whitespaces=True) columns = [address_text, str(n), label, balance_text, str(num)] if fx: rate = fx.exchange_rate() fiat_balance = fx.value_str(balance, rate) columns.insert(4, fiat_balance) address_item = SortableTreeWidgetItem(columns) if ca_info: # Set Cash Accounts: tool tip.. this will read the minimal_chash attribute we added to this object above self._ca_set_item_tooltip(address_item, ca_info) address_item.setTextAlignment(3, Qt.AlignRight) address_item.setFont(3, self.monospace_font) if fx: address_item.setTextAlignment(4, Qt.AlignRight) address_item.setFont(4, self.monospace_font) # Set col0 address font to monospace address_item.setFont(0, self.monospace_font) # Set UserRole data items: address_item.setData(0, self.DataRoles.address, address) address_item.setData(0, self.DataRoles.can_edit_label, True) # label can be edited if ca_list: # Save the list of cashacct infos, if any address_item.setData(0, self.DataRoles.cash_accounts, ca_list) if self.wallet.is_frozen(address): address_item.setBackground(0, ColorScheme.BLUE.as_color(True)) address_item.setToolTip( 0, _("Address is frozen, right-click to unfreeze")) if self.wallet.is_beyond_limit(address, is_change): address_item.setBackground(0, ColorScheme.RED.as_color(True)) if is_change and self.wallet.is_retired_change_addr(address): address_item.setForeground(0, ColorScheme.GRAY.as_color()) old_tt = address_item.toolTip(0) if old_tt: old_tt += "\n" address_item.setToolTip( 0, old_tt + _("Change address is retired")) if is_hidden: if not has_hidden: seq_item.insertChild(0, hidden_item) has_hidden = True hidden_item.addChild(address_item) else: seq_item.addChild(address_item) if address in addresses_to_re_select: items_to_re_select.append(address_item) for item in items_to_re_select: # NB: Need to select the item at the end becasue internally Qt does some index magic # to pick out the selected item and the above code mutates the TreeList, invalidating indices # and other craziness, which might produce UI glitches. See #1042 item.setSelected(True) # Now, at the very end, enforce previous UI state with respect to what was expanded or not. See #1042 restore_expanded_items(self.invisibleRootItem(), expanded_item_names)
def initUI(self): # set basic self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) # status bar self.status = self.statusBar() self.status.setSizeGripEnabled(True) # 显示右下角 self.status.showMessage("StatusBar Ready ...") # menu bar self.menu = QMenu() self.menu.addAction('&Open') self.menu.addAction('&Exit') self.menuBar = QMenuBar() fileAct = self.menuBar.addAction('&File') fileAct.setMenu(self.menu) self.menuBar.addAction('&About') self.setMenuBar(self.menuBar) # 2 widget self.tree = QTreeWidget() self.tree.setColumnCount(1) #设置列数 self.tree.setHeaderLabels(['QProfiler items']) #设置树形控件头部的标题 self.tree.setIndentation(20) # 项目的缩进 #设置根节点 Perfmon = QTreeWidgetItem() Perfmon.setText(0, 'Perfmon') perfmon_00 = QTreeWidgetItem() perfmon_00.setText(0, 'perfmon_00') Perfmon.addChild(perfmon_00) perfmon_01 = QTreeWidgetItem() perfmon_01.setText(0, 'perfmon_01') Perfmon.addChild(perfmon_01) perfmon_02 = QTreeWidgetItem() perfmon_02.setText(0, 'perfmon_02') Perfmon.addChild(perfmon_02) perfmon_03 = QTreeWidgetItem() perfmon_03.setText(0, 'perfmon_03') Perfmon.addChild(perfmon_03) self.tree.addTopLevelItem(Perfmon) # separator line self.line = QFrame() self.line.setGeometry(QRect(250, 340, 3, 61)) self.line.setFrameShape(QFrame.VLine) self.line.setFrameShadow(QFrame.Sunken) self.tab = self.createTabWidget() hLayout = QHBoxLayout() hLayout.addWidget(self.tree) hLayout.addWidget(self.line) hLayout.addWidget(self.tab) #hLayout.setStretch(0, 1) # set layout widget = QWidget() widget.setLayout(hLayout) self.setCentralWidget( widget ) # 如果时 QMainWindow, layout 只能设置在centralWidget上, 所以是需要一个 widget 作为 centralWdiget self.show()
class DeviceDialog(QDialog, Ui_DeviceDialog): """ Function and Event handling class for the Ui_DeviceDialog. """ qtcb_enumerate = pyqtSignal(str, str, str, type((0,)), type((0,)), int, int) qtcb_connected = pyqtSignal(int) def __init__(self, parent): QDialog.__init__(self, parent, get_modeless_dialog_flags()) self._logger_window = parent self.device_name_by_device_identifier = {} for display_name, device_spec in device_specs.items(): self.device_name_by_device_identifier[device_spec['class'].DEVICE_IDENTIFIER] = display_name self.qtcb_enumerate.connect(self.cb_enumerate) self.qtcb_connected.connect(self.cb_connected) self.host = None self.port = None self.secret = None self.ipcon = IPConnection() self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED, self.qtcb_connected.emit) self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE, self.qtcb_enumerate.emit) self.setupUi(self) self.btn_add_device.clicked.connect(self.btn_add_device_clicked) self.btn_refresh.clicked.connect(self.btn_refresh_clicked) self.btn_close.clicked.connect(self.btn_close_clicked) self.tree_widget.itemActivated.connect(self.add_item) self.connected_uids = [] self.available_item = QTreeWidgetItem(['No devices available']) self.supported_item = QTreeWidgetItem(['Supported devices']) self.tree_widget.addTopLevelItem(self.available_item) self.tree_widget.addTopLevelItem(self.supported_item) for device_name in device_specs: self.supported_item.addChild(QTreeWidgetItem([device_name])) self.supported_item.sortChildren(0, Qt.AscendingOrder) self.supported_item.setExpanded(True) def cb_connected(self, connect_reason): self.tree_widget.clearSelection() self.available_item.takeChildren() self.available_item.setExpanded(True) self.available_item.setText(0, 'No devices available at {0}:{1}'.format(self.host, self.port)) self.connected_uids = [] if self.secret != None: self.ipcon.set_auto_reconnect(False) # don't auto-reconnect on authentication error try: self.ipcon.authenticate(self.secret) except: try: self.ipcon.disconnect() except: pass if connect_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT: extra = ' after auto-reconnect' else: extra = '' self.available_item.setText(0, 'Could not authenticate' + extra) return self.ipcon.set_auto_reconnect(True) try: self.ipcon.enumerate() except: pass def cb_enumerate(self, uid, connected_uid, position, hardware_version, firmware_version, device_identifier, enumeration_type): if enumeration_type in [IPConnection.ENUMERATION_TYPE_AVAILABLE, IPConnection.ENUMERATION_TYPE_CONNECTED]: if uid not in self.connected_uids: display_name = self.device_name_by_device_identifier.get(device_identifier) if display_name != None: self.connected_uids.append(uid) self.available_item.addChild(QTreeWidgetItem(['{0} [{1}]'.format(display_name, uid)])) self.available_item.setText(0, 'Devices available at {0}:{1}'.format(self.host, self.port)) self.available_item.sortChildren(0, Qt.AscendingOrder) else: if uid in self.connected_uids: self.connected_uids.remove(uid) for i in range(self.available_item.childCount()): child = self.available_item.child(i) if '[{0}]'.format(uid) in child.text(0): self.available_item.takeChild(i) break if self.available_item.childCount() == 0: self.available_item.setText(0, 'No devices available at {0}:{1}'.format(self.host, self.port)) def btn_add_device_clicked(self): for item in self.tree_widget.selectedItems(): if item == self.available_item or item == self.supported_item: continue self._logger_window.add_device_to_tree(self.create_device_config(item.text(0))) def btn_refresh_clicked(self): try: self.ipcon.disconnect() except: pass self.tree_widget.clearSelection() self.available_item.takeChildren() self.available_item.setExpanded(True) self.connected_uids = [] self.host = self._logger_window.combo_host.currentText() self.port = self._logger_window.spin_port.value() if self._logger_window.check_authentication.isChecked(): self.secret = self._logger_window.edit_secret.text() try: self.secret.encode('ascii') except: self.secret = None self.available_item.setText(0, 'Authentication secret cannot contain non-ASCII characters') return else: self.secret = None try: self.ipcon.connect(self.host, self.port) self.available_item.setText(0, 'No devices available at {0}:{1}'.format(self.host, self.port)) except: self.available_item.setText(0, 'Could not connect to {0}:{1}'.format(self.host, self.port)) def btn_close_clicked(self): self.close() def add_item(self, item): if item == self.available_item or item == self.supported_item: return self._logger_window.add_device_to_tree(self.create_device_config(item.text(0))) def create_device_config(self, item_text): name, uid = Utilities.parse_device_name(item_text) # FIXME device_spec = device_specs[name] if uid == None: # FIXME uid = '' device = { 'host': 'default', 'name': name, 'uid': uid, 'values': {}, 'options': {} } for value_spec in device_spec['values']: device['values'][value_spec['name']] = {'interval': 0} if value_spec['subvalues'] != None: device['values'][value_spec['name']]['subvalues'] = {} for subvalue_name in value_spec['subvalues']: device['values'][value_spec['name']]['subvalues'][subvalue_name] = True if device_spec['options'] != None: for option_spec in device_spec['options']: device['options'][option_spec['name']] = {'value': option_spec['default']} return device
def create_complex_node(self, key, value, root=None): # 0: key, 1:value, 2:type 3:file/image path sub_node = None if isinstance(value, (int, float)): if root is None: sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) sub_node.setText(1, str(value)) sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable) else: sub_node = create_tree_item(key=key, value=value, edit=True) root.addChild(sub_node) root.setExpanded(True) elif isinstance(value, str): if root is None: sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) sub_node.setText(1, str(value)) if key not in DISABLE_EDIT_KEYS: sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable) else: enable_edit = False if key in [ ITEM_TYPE_ELEMENT_NAME, ITEM_CONDITION_NAME, ITEM_CONDITIONS_NAME ]: enable_edit = True sub_node = create_tree_item(key=key, value=value, edit=enable_edit) root.addChild(sub_node) if key == 'algorithm': self._create_algorithm_node(key=key, value=value, node=sub_node) elif key == 'type': self._set_type_node(key, value, sub_node) elif isinstance(value, dict): if root is None: sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) else: sub_node = create_tree_item(key=key) root.addChild(sub_node) if key == 'refer': sub_node.setText(2, ITEM_TYPE_REFER_TASK) for sub_key, sub_value in value.items(): self.create_complex_node(key=sub_key, value=sub_value, root=sub_node) sub_node.setExpanded(True) elif isinstance(value, list): if key == 'elements': sub_node = QTreeWidgetItem(self.__right_tree) sub_node.setText(0, key) sub_node.setText(2, ITEM_TYPE_ELEMENTS) sub_node.setFlags(sub_node.flags() | Qt.ItemIsEditable) else: sub_node = root for sub_value in value: rename_key = key[:-1] sub_type = ITEM_TYPE_ELEMENT if rename_key == 'template': sub_type = ITEM_TYPE_TEMPLATE enable_edit = False ss_node = create_tree_item(key=rename_key, node_type=sub_type, edit=enable_edit) sub_node.addChild(ss_node) for ss_key, ss_value in sub_value.items(): self.create_complex_node(key=ss_key, value=ss_value, root=ss_node) ss_node.setExpanded(True) sub_node.setExpanded(True) if sub_node is None: return if key in SCENE_HIDDEN_KEYS: sub_node.setHidden(True)
class TreeController(object): """ Idea is that the tree is entirely controlled by modifying the main_model. After modification, update_tree() is called, which will populate accordingly. """ def __init__(self, model, view, ctrl): """ :param MyModel model: :param view: """ self.model = model self.view = view self.pctrl = ctrl.plot # this is only needed to trigger canvas update, if tree change. tw = view.treeWidget # QTreeWidgetItem placeholders, only the top level nodes. self.tctx = None self.tvdx = None self.tplans = None self.tdos = None self.tlet = None # These "articial" objects are made since they do not exist in pytrip.model self._doscol = DosCollection() self._letcol = LetCollection() self._plancol = PlanCollection() # setup the submenus: self.tmc = TreeMenuController(model, view, ctrl) # self, else it goes out of scope? # connect checkbox change state to callback tw.itemClicked.connect(self.on_checked_changed) def on_checked_changed(self, pos): """ If checkbox is changed in the TreeWidget, then then corresponding object is removed or added to the plot_model. """ logger.debug("on_checked_changed() {}".format(pos)) pm = self.model.plot obj = pos.data(0, Qt.UserRole) # state = pos.data(0, Qt.CheckStateRole) # tw = self.view.tw if pos.checkState(0) == Qt.Unchecked: if isinstance(obj, pt.CtxCube): logger.debug("set pm.ctx = None") pm.ctx = None if isinstance(obj, pt.Voi): logger.debug("remove Voi {}".format(obj.name)) if obj in pm.vois: pm.vois.remove(obj) else: logger.warning("Tried to remove Voi {} which is not in pm.vois.") if isinstance(obj, pte.Plan): logger.debug("remove Plan {}".format(obj.name)) if obj in pm.plans: pm.plans.remove(obj) else: logger.warning("Tried to remove Plan {} which is not in pm.plans.") # TODO: Field if isinstance(obj, pt.DosCube): logger.debug("set pm.dos = None") pm.dos = None if isinstance(obj, pt.LETCube): logger.debug("set pm.let = None") pm.let = None else: # select something and add it to model.plot logger.debug("{} isChecked(True)".format(pos)) if isinstance(obj, pt.CtxCube): pm.ctx = obj if isinstance(obj, pt.Voi): if obj not in pm.vois: pm.vois.append(obj) if isinstance(obj, pt.DosCube): pm.dos = obj if isinstance(obj, pt.LETCube): pm.let = obj # trigger update plot after model was changed. self.pctrl.update_viewcanvas() for i, item in enumerate(pm.vois): logger.debug("pm.vois {}:{}".format(i, item.name)) def update_tree(self): """ Syncs the tree with the main_model, adding and removing items accordingly. """ logger.debug("update_tree()") self._model_sync_add_items() self._model_sync_remove_items() def _model_sync_add_items(self): """ Syncs the tree with the main_model, adding and removing items accordingly. TODO: this can probably be programmed more elegantly. """ self._add_ctx() self._add_vdxvoi() self._add_plans() self._add_dos() self._add_let() def _add_ctx(self): """ """ model = self.model tw = self.view.treeWidget # CTX data if model.ctx and not self._in_tree(model.ctx): # Add CTX to tree widget. tw.setHeaderLabels(["'{}'".format(model.ctx.basename)]) # TODO:patient name self.tctx = QTreeWidgetItem([model.ctx.basename]) self.tctx.setData(0, Qt.UserRole, model.ctx) tw.addTopLevelItem(self.tctx) self.tctx.setCheckState(0, Qt.Checked) def _add_vdxvoi(self): """ """ model = self.model tw = self.view.treeWidget # VDX data if model.vdx and not self._in_tree(model.vdx): self.tvdx = QTreeWidgetItem(["ROIs: " + model.vdx.basename]) self.tvdx.setData(0, Qt.UserRole, model.vdx) tw.addTopLevelItem(self.tvdx) self.tvdx.setExpanded(True) # VOIs if model.vdx and model.vdx.vois: vois = model.vdx.vois for i, voi in enumerate(vois): # Add only Vois which are not in the tree. if not self._in_tree(voi): self.tvdx.addChild(QTreeWidgetItem([voi.name])) child = self.tvdx.child(i) child.setData(0, Qt.UserRole, voi) child.setCheckState(0, Qt.Checked) def _add_plans(self): """ """ model = self.model tw = self.view.treeWidget # Plans node: if model.plans and not self.tplans: self.tplans = QTreeWidgetItem(["Plans:"]) self.tplans.setData(0, Qt.UserRole, self._plancol) tw.addTopLevelItem(self.tplans) self.tplans.setExpanded(True) # Plans has one child for each plan. if model.plans: for i, plan in enumerate(model.plans): # Add only plans, which are not already in the tree if not self._in_tree(plan): self.tplans.addChild(QTreeWidgetItem([plan.basename])) child = self.tplans.child(i) child.setData(0, Qt.UserRole, plan) child.setCheckState(0, Qt.Checked) def _add_dos(self): """ """ model = self.model tw = self.view.treeWidget # Add the top level DOS node: if model.dos and not self.tdos: self.tdos = QTreeWidgetItem(["Dose Cubes"]) self.tdos.setData(0, Qt.UserRole, self._doscol) tw.addTopLevelItem(self.tdos) self.tdos.setExpanded(True) # Each DosCube will be treated as a child to the top level DOS node. if model.dos: for i, dos in enumerate(model.dos): if not self._in_tree(dos): self.tdos.addChild(QTreeWidgetItem([dos.basename])) child = self.tdos.child(i) child.setData(0, Qt.UserRole, dos) child.setCheckState(0, Qt.Checked) def _add_let(self): """ """ model = self.model tw = self.view.treeWidget # Add the top level LET node: if model.let and not self.tlet: self.tlet = QTreeWidgetItem(["LET Cubes"]) self.tlet.setData(0, Qt.UserRole, self._letcol) tw.addTopLevelItem(self.tlet) self.tlet.setExpanded(True) # Each LETCube will be treated as a child to the top level DOS node. if model.let: for i, let in enumerate(model.let): if not self._in_tree(let): self.tlet.addChild(QTreeWidgetItem([let.basename])) child = self.tlet.child(i) child.setData(0, Qt.UserRole, let) child.setCheckState(0, Qt.Checked) def _model_sync_remove_items(self): """ Sync TreeWidget with data model. If items are found in TreeWidget, which are not found in data model, the item will be removed from TreeWidget. """ tw = self.view.treeWidget lo = self._flat_model() root = tw.invisibleRootItem() count = root.childCount() # Check if TreeWidget item data object is found in model. # if not, remove it from TreeWidget. for i in range(count): item = root.child(i) if item: _obj = item.data(0, Qt.UserRole) if _obj not in lo: (item.parent() or root).removeChild(item) count2 = item.childCount() for j in range(count2): item2 = item.child(j) if item2: _obj = item2.data(0, Qt.UserRole) if _obj not in lo: (item2.parent() or root).removeChild(item) def _flat_model(self): """ Produces a searchable and flat array of model data which should be displayed in the TreeWidget. This array will be used for syncing the treeWidget items with the model items. """ model = self.model # Check for items to be removed. # First lets make a flat list of all pytrip objects in the model (called "lo"): lo = [model.ctx, model.vdx] if model.vdx: if model.vdx.vois: lo += model.vdx.vois # extend the list with a list of voi objects if model.dos: lo += model.dos if model.let: lo += model.let if model.plans: lo += model.plans for plan in model.plans: if plan.fields: lo += plan.fields # TODO: this part needs some rework. # The top level nodes: plans, dos and let # should not be removed, if they hold data. They do not have a class, tough # Therefore this little hack for now: if model.dos: lo += [self._doscol] if model.let: lo += [self._letcol] if model.plans: lo += [self._plancol] return lo def _in_tree(self, obj): """ Crawls the entire treewidget, and search for the object. Returns corresponding QTreeWidgetItem, if found, else None. :params PyTRiPobject obj: such as CtxCube, DosCube, VdxCube, Plan, ...etc """ tw = self.view.treeWidget root = tw.invisibleRootItem() count = root.childCount() for i in range(count): child = root.child(i) _obj = child.data(0, Qt.UserRole) if obj == _obj: return child count2 = child.childCount() for j in range(count2): child2 = child.child(j) _obj = child2.data(0, Qt.UserRole) if obj == _obj: return child2 return None
class AdBlockTreeWidget(E5TreeWidget): """ Class implementing a tree widget for the AdBlock configuration dialog. """ def __init__(self, subscription, parent=None): """ Constructor @param subscription reference to the subscription (AdBlockSubscription) @param parent reference to the parent widget (QWidget) """ super(AdBlockTreeWidget, self).__init__(parent) self.__subscription = subscription self.__topItem = None self.__ruleToBeSelected = "" self.__itemChangingBlock = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.setDefaultItemShowMode(E5TreeWidget.ItemsExpanded) self.setHeaderHidden(True) self.setAlternatingRowColors(True) self.customContextMenuRequested.connect(self.__contextMenuRequested) self.itemChanged.connect(self.__itemChanged) self.__subscription.changed.connect(self.__subscriptionChanged) self.__subscription.rulesChanged.connect(self.__subscriptionChanged) def subscription(self): """ Public method to get a reference to the subscription. @return reference to the subscription (AdBlockSubscription) """ return self.__subscription def showRule(self, rule): """ Public method to highlight the given rule. @param rule AdBlock rule to be shown (AdBlockRule) """ if rule: self.__ruleToBeSelected = rule.filter() if not self.__topItem: return if self.__ruleToBeSelected: items = self.findItems(self.__ruleToBeSelected, Qt.MatchRecursive) if items: item = items[0] self.setCurrentItem(item) self.scrollToItem(item, QAbstractItemView.PositionAtCenter) self.__ruleToBeSelected = "" def refresh(self): """ Public method to refresh the tree. """ QApplication.setOverrideCursor(Qt.WaitCursor) self.__itemChangingBlock = True self.clear() boldFont = QFont() boldFont.setBold(True) self.__topItem = QTreeWidgetItem(self) self.__topItem.setText(0, self.__subscription.title()) self.__topItem.setFont(0, boldFont) self.addTopLevelItem(self.__topItem) allRules = self.__subscription.allRules() index = 0 for rule in allRules: item = QTreeWidgetItem(self.__topItem) item.setText(0, rule.filter()) item.setData(0, Qt.UserRole, index) if self.__subscription.canEditRules(): item.setFlags(item.flags() | Qt.ItemIsEditable) self.__adjustItemFeatures(item, rule) index += 1 self.expandAll() self.showRule(None) self.__itemChangingBlock = False QApplication.restoreOverrideCursor() QApplication.processEvents() def addRule(self, filter=""): """ Public slot to add a new rule. @param filter filter to be added (string) """ if not self.__subscription.canEditRules(): return if not filter: filter = QInputDialog.getText( self, self.tr("Add Custom Rule"), self.tr("Write your rule here:"), QLineEdit.Normal) if filter == "": return from .AdBlockRule import AdBlockRule rule = AdBlockRule(filter, self.__subscription) offset = self.__subscription.addRule(rule) item = QTreeWidgetItem() item.setText(0, filter) item.setData(0, Qt.UserRole, offset) item.setFlags(item.flags() | Qt.ItemIsEditable) self.__itemChangingBlock = True self.__topItem.addChild(item) self.__itemChangingBlock = False self.__adjustItemFeatures(item, rule) def removeRule(self): """ Public slot to remove the current rule. """ item = self.currentItem() if item is None or \ not self.__subscription.canEditRules() or \ item == self.__topItem: return offset = item.data(0, Qt.UserRole) self.__subscription.removeRule(offset) self.deleteItem(item) def __contextMenuRequested(self, pos): """ Private slot to show the context menu. @param pos position for the menu (QPoint) """ if not self.__subscription.canEditRules(): return item = self.itemAt(pos) if item is None: return menu = QMenu() menu.addAction(self.tr("Add Rule"), self.addRule) menu.addSeparator() act = menu.addAction(self.tr("Remove Rule"), self.removeRule) if item.parent() is None: act.setDisabled(True) menu.exec_(self.viewport().mapToGlobal(pos)) def __itemChanged(self, itm): """ Private slot to handle the change of an item. @param itm changed item (QTreeWidgetItem) """ if itm is None or self.__itemChangingBlock: return self.__itemChangingBlock = True offset = itm.data(0, Qt.UserRole) oldRule = self.__subscription.rule(offset) if itm.checkState(0) == Qt.Unchecked and oldRule.isEnabled(): # Disable rule rule = self.__subscription.setRuleEnabled(offset, False) self.__adjustItemFeatures(itm, rule) elif itm.checkState(0) == Qt.Checked and not oldRule.isEnabled(): # Enable rule rule = self.__subscription.setRuleEnabled(offset, True) self.__adjustItemFeatures(itm, rule) elif self.__subscription.canEditRules(): from .AdBlockRule import AdBlockRule # Custom rule has been changed rule = self.__subscription.replaceRule( AdBlockRule(itm.text(0), self.__subscription), offset) self.__adjustItemFeatures(itm, rule) self.__itemChangingBlock = False def __copyFilter(self): """ Private slot to copy the current filter to the clipboard. """ item = self.currentItem() if item is not None: QApplication.clipboard().setText(item.text(0)) def __subscriptionChanged(self): """ Private slot handling a subscription change. """ self.refresh() self.__itemChangingBlock = True self.__topItem.setText( 0, self.tr("{0} (recently updated)").format( self.__subscription.title())) self.__itemChangingBlock = False def __adjustItemFeatures(self, itm, rule): """ Private method to adjust an item. @param itm item to be adjusted (QTreeWidgetItem) @param rule rule for the adjustment (AdBlockRule) """ if not rule.isEnabled(): font = QFont() font.setItalic(True) itm.setForeground(0, QColor(Qt.gray)) if not rule.isComment() and not rule.isHeader(): itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(0, Qt.Unchecked) itm.setFont(0, font) return itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(0, Qt.Checked) if rule.isCSSRule(): itm.setForeground(0, QColor(Qt.darkBlue)) itm.setFont(0, QFont()) elif rule.isException(): itm.setForeground(0, QColor(Qt.darkGreen)) itm.setFont(0, QFont()) else: itm.setForeground(0, QColor()) itm.setFont(0, QFont()) def keyPressEvent(self, evt): """ Protected method handling key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_C and \ evt.modifiers() & Qt.ControlModifier: self.__copyFilter() elif evt.key() == Qt.Key_Delete: self.removeRule() else: super(AdBlockTreeWidget, self).keyPressEvent(evt)
def on_update(self): def remember_expanded_items(): # save the set of expanded items... so that address list updates don't # annoyingly collapse our tree list widget due to the update. expanded_item_names = set() for i in range(0, self.topLevelItemCount()): it = self.topLevelItem(i) if it and it.childCount(): if it.isExpanded(): expanded_item_names.add(it.text(0)) for j in range(0, it.childCount()): it2 = it.child(j) if it2 and it2.childCount() and it2.isExpanded(): expanded_item_names.add( it.text(0) + "/" + it2.text(0)) return expanded_item_names def restore_expanded_items(seq_item, used_item, expanded_item_names): # restore expanded items. if (isinstance(seq_item, QTreeWidgetItem) and not seq_item.isExpanded() and seq_item.text(0) in expanded_item_names): seq_item.setExpanded(True) used_item_name = (used_item.text(0) if not used_item.parent() else used_item.parent().text(0) + "/" + used_item.text(0)) if not used_item.isExpanded( ) and used_item_name in expanded_item_names: used_item.setExpanded(True) self.wallet = self.parent.wallet had_item_count = self.topLevelItemCount() item = self.currentItem() current_address = item.data(0, Qt.UserRole) if item else None expanded_item_names = remember_expanded_items() self.clear() receiving_addresses = self.wallet.get_receiving_addresses() change_addresses = self.wallet.get_change_addresses() account_item = self sequences = [0, 1] if change_addresses else [0] if app_state.fx and app_state.fx.get_fiat_address_config(): fx = app_state.fx else: fx = None for is_change in sequences: if len(sequences) > 1: name = _("Receiving") if not is_change else _("Change") seq_item = QTreeWidgetItem([name, '', '', '', '', '']) account_item.addChild(seq_item) # first time we create this widget, auto-expand the default address list if not is_change and not had_item_count: seq_item.setExpanded(True) else: seq_item = account_item used_item = QTreeWidgetItem([_("Used"), '', '', '', '', '']) used_flag = False addr_list = change_addresses if is_change else receiving_addresses for n, address in enumerate(addr_list): num = len(self.wallet.get_address_history(address)) is_used = self.wallet.is_used(address) balance = sum(self.wallet.get_addr_balance(address)) address_text = address.to_string() label = self.wallet.labels.get(address.to_string(), '') balance_text = self.parent.format_amount(balance, whitespaces=True) columns = [address_text, str(n), label, balance_text, str(num)] if fx: rate = fx.exchange_rate() fiat_balance = fx.value_str(balance, rate) columns.insert(4, fiat_balance) address_item = SortableTreeWidgetItem(columns) address_item.setTextAlignment(3, Qt.AlignRight) address_item.setFont(3, self.monospace_font) if fx: address_item.setTextAlignment(4, Qt.AlignRight) address_item.setFont(4, self.monospace_font) address_item.setFont(0, self.monospace_font) address_item.setData(0, Qt.UserRole, address) address_item.setData(0, Qt.UserRole + 1, True) # label can be edited if self.wallet.is_frozen(address): address_item.setBackground(0, QColor('lightblue')) if self.wallet.is_beyond_limit(address, is_change): address_item.setBackground(0, QColor('red')) if is_used: if not used_flag: seq_item.insertChild(0, used_item) used_flag = True used_item.addChild(address_item) else: seq_item.addChild(address_item) if address == current_address: self.setCurrentItem(address_item) restore_expanded_items(seq_item, used_item, expanded_item_names)
def __init__(self, dialog): super(Shortcuts, self).__init__(dialog) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.scheme = SchemeSelector(self) layout.addWidget(self.scheme) self.tree = QTreeWidget(self) self.tree.setHeaderLabels([_("Command"), _("Shortcut")]) self.tree.setRootIsDecorated(False) self.tree.setColumnCount(2) self.tree.setAllColumnsShowFocus(True) self.tree.setAnimated(True) layout.addWidget(self.tree) self.edit = QPushButton(icons.get("preferences-desktop-keyboard-shortcuts"), '') layout.addWidget(self.edit) # signals self.scheme.currentChanged.connect(self.slotSchemeChanged) self.scheme.changed.connect(self.changed) self.tree.currentItemChanged.connect(self.slotCurrentItemChanged) self.tree.itemDoubleClicked.connect(self.editCurrentItem) self.edit.clicked.connect(self.editCurrentItem) # make a dict of all actions with the actions as key and the names as # value, with the collection prepended (for loading/saving) win = dialog.parent() allactions = {} for collection in actioncollectionmanager.manager(win).actionCollections(): for name, action in collection.actions().items(): allactions[action] = (collection, name) # keep a list of actions not in the menu structure left = list(allactions.keys()) def add_actions(menuitem, actions): """Add actions to a QTreeWidgetItem.""" for a in actions: if a.menu(): item = build_menu_item(a) if item.childCount(): menuitem.addChild(item) elif a in left: left.remove(a) menuitem.addChild(ShortcutItem(a, *allactions[a])) menuitem.setFlags(Qt.ItemIsEnabled) # disable selection def build_menu_item(action): """Return a QTreeWidgetItem with children for all the actions in the submenu.""" menuitem = QTreeWidgetItem() text = qutil.removeAccelerator(action.text()) menuitem.setText(0, _("Menu {name}").format(name=text)) add_actions(menuitem, action.menu().actions()) return menuitem # present the actions nicely ordered as in the menus for a in win.menuBar().actions(): menuitem = build_menu_item(a) if menuitem.childCount(): self.tree.addTopLevelItem(menuitem) # sort leftover actions left.sort(key=lambda i: i.text()) # show actions that are left, grouped by collection titlegroups = {} for a in left[:]: # copy collection, name = allactions[a] if collection.title(): titlegroups.setdefault(collection.title(), []).append(a) left.remove(a) for title in sorted(titlegroups): item = QTreeWidgetItem(["{0}:".format(title)]) for a in titlegroups[title]: item.addChild(ShortcutItem(a, *allactions[a])) self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection # show other actions that were not in the menus item = QTreeWidgetItem([_("Other commands:")]) for a in left: if a.text() and not a.menu(): item.addChild(ShortcutItem(a, *allactions[a])) if item.childCount(): self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection self.tree.expandAll() item = self.tree.topLevelItem(0).child(0) if _lastaction: # find the previously selected item for i in self.items(): if i.name == _lastaction: item = i break self.tree.setCurrentItem(item) self.tree.resizeColumnToContents(0)
class AdBlockTreeWidget(E5TreeWidget): """ Class implementing a tree widget for the AdBlock configuration dialog. """ def __init__(self, subscription, parent=None): """ Constructor @param subscription reference to the subscription (AdBlockSubscription) @param parent reference to the parent widget (QWidget) """ super(AdBlockTreeWidget, self).__init__(parent) self.__subscription = subscription self.__topItem = None self.__ruleToBeSelected = "" self.__itemChangingBlock = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.setDefaultItemShowMode(E5TreeWidget.ItemsExpanded) self.setHeaderHidden(True) self.setAlternatingRowColors(True) self.customContextMenuRequested.connect(self.__contextMenuRequested) self.itemChanged.connect(self.__itemChanged) self.__subscription.changed.connect(self.__subscriptionChanged) self.__subscription.rulesChanged.connect(self.__subscriptionChanged) def subscription(self): """ Public method to get a reference to the subscription. @return reference to the subscription (AdBlockSubscription) """ return self.__subscription def showRule(self, rule): """ Public method to highlight the given rule. @param rule AdBlock rule to be shown (AdBlockRule) """ if rule: self.__ruleToBeSelected = rule.filter() if not self.__topItem: return if self.__ruleToBeSelected: items = self.findItems(self.__ruleToBeSelected, Qt.MatchRecursive) if items: item = items[0] self.setCurrentItem(item) self.scrollToItem(item, QAbstractItemView.PositionAtCenter) self.__ruleToBeSelected = "" def refresh(self): """ Public method to refresh the tree. """ QApplication.setOverrideCursor(Qt.WaitCursor) self.__itemChangingBlock = True self.clear() boldFont = QFont() boldFont.setBold(True) self.__topItem = QTreeWidgetItem(self) self.__topItem.setText(0, self.__subscription.title()) self.__topItem.setFont(0, boldFont) self.addTopLevelItem(self.__topItem) allRules = self.__subscription.allRules() index = 0 for rule in allRules: item = QTreeWidgetItem(self.__topItem) item.setText(0, rule.filter()) item.setData(0, Qt.UserRole, index) if self.__subscription.canEditRules(): item.setFlags(item.flags() | Qt.ItemIsEditable) self.__adjustItemFeatures(item, rule) index += 1 self.expandAll() self.showRule(None) self.__itemChangingBlock = False QApplication.restoreOverrideCursor() QApplication.processEvents() def addRule(self, filter=""): """ Public slot to add a new rule. @param filter filter to be added (string) """ if not self.__subscription.canEditRules(): return if not filter: filter = QInputDialog.getText(self, self.tr("Add Custom Rule"), self.tr("Write your rule here:"), QLineEdit.Normal) if filter == "": return from .AdBlockRule import AdBlockRule rule = AdBlockRule(filter, self.__subscription) offset = self.__subscription.addRule(rule) item = QTreeWidgetItem() item.setText(0, filter) item.setData(0, Qt.UserRole, offset) item.setFlags(item.flags() | Qt.ItemIsEditable) self.__itemChangingBlock = True self.__topItem.addChild(item) self.__itemChangingBlock = False self.__adjustItemFeatures(item, rule) def removeRule(self): """ Public slot to remove the current rule. """ item = self.currentItem() if item is None or \ not self.__subscription.canEditRules() or \ item == self.__topItem: return offset = item.data(0, Qt.UserRole) self.__subscription.removeRule(offset) self.deleteItem(item) def __contextMenuRequested(self, pos): """ Private slot to show the context menu. @param pos position for the menu (QPoint) """ if not self.__subscription.canEditRules(): return item = self.itemAt(pos) if item is None: return menu = QMenu() menu.addAction(self.tr("Add Rule"), self.addRule) menu.addSeparator() act = menu.addAction(self.tr("Remove Rule"), self.removeRule) if item.parent() is None: act.setDisabled(True) menu.exec_(self.viewport().mapToGlobal(pos)) def __itemChanged(self, itm): """ Private slot to handle the change of an item. @param itm changed item (QTreeWidgetItem) """ if itm is None or self.__itemChangingBlock: return self.__itemChangingBlock = True offset = itm.data(0, Qt.UserRole) oldRule = self.__subscription.rule(offset) if itm.checkState(0) == Qt.Unchecked and oldRule.isEnabled(): # Disable rule rule = self.__subscription.setRuleEnabled(offset, False) self.__adjustItemFeatures(itm, rule) elif itm.checkState(0) == Qt.Checked and not oldRule.isEnabled(): # Enable rule rule = self.__subscription.setRuleEnabled(offset, True) self.__adjustItemFeatures(itm, rule) elif self.__subscription.canEditRules(): from .AdBlockRule import AdBlockRule # Custom rule has been changed rule = self.__subscription.replaceRule( AdBlockRule(itm.text(0), self.__subscription), offset) self.__adjustItemFeatures(itm, rule) self.__itemChangingBlock = False def __copyFilter(self): """ Private slot to copy the current filter to the clipboard. """ item = self.currentItem() if item is not None: QApplication.clipboard().setText(item.text(0)) def __subscriptionChanged(self): """ Private slot handling a subscription change. """ self.refresh() self.__itemChangingBlock = True self.__topItem.setText( 0, self.tr("{0} (recently updated)").format( self.__subscription.title())) self.__itemChangingBlock = False def __adjustItemFeatures(self, itm, rule): """ Private method to adjust an item. @param itm item to be adjusted (QTreeWidgetItem) @param rule rule for the adjustment (AdBlockRule) """ if not rule.isEnabled(): font = QFont() font.setItalic(True) itm.setForeground(0, QColor(Qt.gray)) if not rule.isComment() and not rule.isHeader(): itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(0, Qt.Unchecked) itm.setFont(0, font) return itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable) itm.setCheckState(0, Qt.Checked) if rule.isCSSRule(): itm.setForeground(0, QColor(Qt.darkBlue)) itm.setFont(0, QFont()) elif rule.isException(): itm.setForeground(0, QColor(Qt.darkGreen)) itm.setFont(0, QFont()) else: itm.setForeground(0, QColor()) itm.setFont(0, QFont()) def keyPressEvent(self, evt): """ Protected method handling key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_C and \ evt.modifiers() & Qt.ControlModifier: self.__copyFilter() elif evt.key() == Qt.Key_Delete: self.removeRule() else: super(AdBlockTreeWidget, self).keyPressEvent(evt)
def genListItem(key, value, startColumn): newColumn = 2 newColumns = [] root = QTreeWidgetItem() root.setText(startColumn, '[] ' + key) index = 0 if value: v = value[0] if isinstance(v, str): child = QTreeWidgetItem() child.setText(startColumn + 1, '(str)') root.addChild(child) newColumn += 1 elif isinstance(v, bool): child = QTreeWidgetItem() child.setText(startColumn + 1, '(bool)') root.addChild(child) newColumn += 1 elif isinstance(v, float): child = QTreeWidgetItem() child.setText(startColumn + 1, '(float)') root.addChild(child) newColumn += 1 elif isinstance(v, int): child = QTreeWidgetItem() child.setText(startColumn + 1, '(int)') root.addChild(child) newColumn += 1 elif isinstance(v, list): child, listColumn = genListItem('[]') newColumn += listColumn root.addChild(child) elif isinstance(v, dict): child, dictColumn = genDictItem('item', v, startColumn + 1) newColumn += dictColumn root.addChild(child) else: root.addChild(QTreeWidgetItem().setText(startColumn, '(null)')) return root, newColumn
def update(self, *, network: Network, servers: dict, use_tor: bool): self.clear() # connected servers connected_servers_item = QTreeWidgetItem([_("Connected nodes"), '']) connected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL) chains = network.get_blockchains() n_chains = len(chains) for chain_id, interfaces in chains.items(): b = blockchain.blockchains.get(chain_id) if b is None: continue name = b.get_name() if n_chains > 1: x = QTreeWidgetItem( [name + '@%d' % b.get_max_forkpoint(), '%d' % b.height()]) x.setData(0, self.ITEMTYPE_ROLE, self.ItemType.CHAIN) x.setData(0, self.CHAIN_ID_ROLE, b.get_id()) else: x = connected_servers_item for i in interfaces: star = ' *' if i == network.interface else '' item = QTreeWidgetItem( [f"{i.server.net_addr_str()}" + star, '%d' % i.tip]) item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.CONNECTED_SERVER) item.setData(0, self.SERVER_ADDR_ROLE, i.server) item.setToolTip(0, str(i.server)) x.addChild(item) if n_chains > 1: connected_servers_item.addChild(x) # disconnected servers disconnected_servers_item = QTreeWidgetItem( [_("Other known servers"), ""]) disconnected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL) connected_hosts = set( [iface.host for ifaces in chains.values() for iface in ifaces]) protocol = PREFERRED_NETWORK_PROTOCOL for _host, d in sorted(servers.items()): if _host in connected_hosts: continue if _host.endswith('.onion') and not use_tor: continue port = d.get(protocol) if port: server = ServerAddr(_host, port, protocol=protocol) item = QTreeWidgetItem([server.net_addr_str(), ""]) item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.DISCONNECTED_SERVER) item.setData(0, self.SERVER_ADDR_ROLE, server) disconnected_servers_item.addChild(item) self.addTopLevelItem(connected_servers_item) self.addTopLevelItem(disconnected_servers_item) connected_servers_item.setExpanded(True) for i in range(connected_servers_item.childCount()): connected_servers_item.child(i).setExpanded(True) disconnected_servers_item.setExpanded(True) # headers h = self.header() h.setStretchLastSection(False) h.setSectionResizeMode(0, QHeaderView.Stretch) h.setSectionResizeMode(1, QHeaderView.ResizeToContents) super().update()
def __init__(self, parent, api_dict): super().__init__(parent) self.ui = Ui_ApiDialog() self.ui.setupUi(self) self.ui.closeButton.clicked.connect(self.close) # Load api into Tree node = self.ui.apiTree.invisibleRootItem() for key, val in api_dict.items(): tmp_args = {} api_func = QTreeWidgetItem() api_func.setText(0, str(key)) api_func.setExpanded(False) node.addChild(api_func) args_node = QTreeWidgetItem() api_func.addChild(args_node) args_node.setText(0, 'Args') args_node.setExpanded(False) if not val['args']: child = QTreeWidgetItem() args_node.addChild(child) child.setText(0, 'None') child.setExpanded(False) else: for index, arg in enumerate(val['args']): child = QTreeWidgetItem() args_node.addChild(child) child.setText(0, str(arg)) child.setExpanded(False) tmp_args[arg] = str(arg) sql_node = QTreeWidgetItem() api_func.addChild(sql_node) sql_node.setText(0, 'SQL') sql_node.setExpanded(False) sql_str = QTreeWidgetItem() sql_str.setText(0, val['sql']) sql_str.setExpanded(False) sql_node.addChild(sql_str) # added a route tree item that shows the exact route path and arguments route_node = QTreeWidgetItem() api_func.addChild(route_node) route_node.setText(0, 'Route') route_node.setExpanded(False) route_str = QTreeWidgetItem() route_list_str = 'http://0.0.0.0:8000/api/' + str(key) if tmp_args: route_list_str += '?' + urlencode(tmp_args) route_str.setText(0, route_list_str) route_str.setExpanded(False) route_node.addChild(route_str)
def add_file_items(files, parent_item: QTreeWidgetItem): for file in files: file_item = FileItem([file.file_name], file) file_item.setIcon(0, fip.icon(QFileInfo(file.file_name))) parent_item.addChild(file_item) file_item.setFirstColumnSpanned(True)
def load(filename, widget): """Loads snippets from a file, displaying them in a list. The user can then choose: - overwrite builtin snippets or not - overwrite own snippets with same title or not - select and view snippets contents. """ try: d = ET.parse(filename) elements = list(d.findall('snippet')) if not elements: raise ValueError(_("No snippets found.")) except Exception as e: QMessageBox.critical(widget, app.caption(_("Error")), _("Can't read from source:\n\n{url}\n\n{error}").format( url=filename, error=e)) return dlg = widgets.dialog.Dialog(widget) dlg.setWindowModality(Qt.WindowModal) dlg.setWindowTitle(app.caption(_("dialog title", "Import Snippets"))) tree = QTreeWidget(headerHidden=True, rootIsDecorated=False) dlg.setMainWidget(tree) userguide.addButton(dlg.buttonBox(), "snippet_import_export") allnames = frozenset(snippets.names()) builtins = frozenset(builtin.builtin_snippets) titles = dict((snippets.title(n), n) for n in allnames if n not in builtins) new = QTreeWidgetItem(tree, [_("New Snippets")]) updated = QTreeWidgetItem(tree, [_("Updated Snippets")]) unchanged = QTreeWidgetItem(tree, [_("Unchanged Snippets")]) new.setFlags(Qt.ItemIsEnabled) updated.setFlags(Qt.ItemIsEnabled) unchanged.setFlags(Qt.ItemIsEnabled) new.setExpanded(True) updated.setExpanded(True) items = [] for snip in elements: item = QTreeWidgetItem() item.body = snip.find('body').text item.title = snip.find('title').text item.shortcuts = list(e.text for e in snip.findall('shortcuts/shortcut')) title = item.title or snippets.maketitle(snippets.parse(item.body).text) item.setText(0, title) name = snip.get('id') name = name if name in builtins else None # determine if new, updated or unchanged if not name: name = titles.get(title) item.name = name if not name or name not in allnames: new.addChild(item) items.append(item) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) item.setCheckState(0, Qt.Checked) elif name: if (item.body != snippets.text(name) or title != snippets.title(name) or (item.shortcuts and item.shortcuts != [s.toString() for s in model.shortcuts(name) or ()])): updated.addChild(item) items.append(item) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) item.setCheckState(0, Qt.Checked) else: unchanged.addChild(item) item.setFlags(Qt.ItemIsEnabled) # count: for i in new, updated, unchanged: i.setText(0, i.text(0) + " ({0})".format(i.childCount())) for i in new, updated: if i.childCount(): i.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) i.setCheckState(0, Qt.Checked) def changed(item): if item in (new, updated): for i in range(item.childCount()): c = item.child(i) c.setCheckState(0, item.checkState(0)) tree.itemChanged.connect(changed) importShortcuts = QTreeWidgetItem([_("Import Keyboard Shortcuts")]) if items: tree.addTopLevelItem(importShortcuts) importShortcuts.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) importShortcuts.setCheckState(0, Qt.Checked) dlg.setMessage(_("Choose which snippets you want to import:")) else: dlg.setMessage(_("There are no new or updated snippets in the file.")) unchanged.setExpanded(True) tree.setWhatsThis(_( "<p>Here the snippets from {filename} are displayed.</p>\n" "<p>If there are new or updated snippets, you can select or deselect " "them one by one, or all at once, using the checkbox of the group. " "Then click OK to import all the selected snippets.</p>\n" "<p>Existing, unchanged snippets can't be imported.</p>\n" ).format(filename=os.path.basename(filename))) qutil.saveDialogSize(dlg, "snippettool/import/size", QSize(400, 300)) if not dlg.exec_() or not items: return ac = model.collection() m = model.model() with qutil.busyCursor(): for i in items: if i.checkState(0) == Qt.Checked: index = m.saveSnippet(i.name, i.body, i.title) if i.shortcuts and importShortcuts.checkState(0): shortcuts = list(map(QKeySequence.fromString, i.shortcuts)) ac.setShortcuts(m.name(index), shortcuts) widget.updateColumnSizes()
def PopulateQgisTools(self): self.ToolBars.clear() # Qgis tools. toolbars = self.iface.mainWindow().findChildren(QToolBar) topitem = QTreeWidgetItem(self.ToolBars) topitem.setText(0, "ToolBars") for toolbar in toolbars: pitems = QTreeWidgetItem(topitem) if toolbar.windowTitle() == '': pitems.setText(0, "No Name") else: pitems.setText(0, toolbar.windowTitle()) actions = toolbar.actions() for action in actions: if isinstance(action, QWidgetAction): a = action.defaultWidget().actions() for b in a: # Removed empty values, such as decorative bars in the toolbar,etc.. if b.text() == "": continue citems = QTreeWidgetItem(pitems) citems.setIcon(0, b.icon()) citems.setText(0, b.iconText()) citems.setToolTip(0, b.iconText()) else: if action.text() == "": continue citems = QTreeWidgetItem(pitems) citems.setIcon(0, action.icon()) citems.setText(0, action.iconText()) citems.setToolTip(0, action.iconText()) # Menus Actions menubar = self.iface.mainWindow().menuBar() topitem = QTreeWidgetItem(self.ToolBars) topitem.setText(0, "Menus") for action in menubar.actions(): self.addTreeItemMenu(parentItem=topitem, action=action) # Processing ToolBox. try: topitem = QTreeWidgetItem(self.ToolBars) topitem.setText(0, "Processing Algorithms") for p in QgsApplication.processingRegistry().providers(): if p.isActive(): providerItem = QTreeWidgetItem(topitem) providerItem.setText(0, p.name()) providerItem.setIcon(0, p.icon()) provider = QgsApplication.processingRegistry().providerById(p.id()) if provider is not None: for alg in provider.algorithms(): citems = QTreeWidgetItem() citems.setText(0, alg.displayName()) citems.setIcon(0, alg.icon()) citems.setToolTip(0, alg.displayName()) providerItem.addChild(citems) return except Exception: self.iface.messageBar().pushMessage("Error: ", "Error loading Processing Toolbox.", level=QGis.Critical, duration=3) None
class TaskViewer(QTreeWidget): """ Class implementing the task viewer. @signal displayFile(str, int) emitted to go to a file task """ displayFile = pyqtSignal(str, int) def __init__(self, parent, project): """ Constructor @param parent the parent (QWidget) @param project reference to the project object """ super(TaskViewer, self).__init__(parent) self.setSortingEnabled(True) self.setExpandsOnDoubleClick(False) self.__headerItem = QTreeWidgetItem( ["", "", self.tr("Summary"), self.tr("Filename"), self.tr("Line"), ""]) self.__headerItem.setIcon( 0, UI.PixmapCache.getIcon("taskCompleted.png")) self.__headerItem.setIcon( 1, UI.PixmapCache.getIcon("taskPriority.png")) self.setHeaderItem(self.__headerItem) self.header().setSortIndicator(2, Qt.AscendingOrder) self.__resizeColumns() self.tasks = [] self.copyTask = None self.projectOpen = False self.project = project self.projectTasksScanFilter = "" from .TaskFilter import TaskFilter self.taskFilter = TaskFilter() self.taskFilter.setActive(False) self.__projectTasksSaveTimer = AutoSaver(self, self.saveProjectTasks) self.__projectTasksMenu = QMenu( self.tr("P&roject Tasks"), self) self.__projectTasksMenu.addAction( self.tr("&Regenerate project tasks"), self.__regenerateProjectTasks) self.__projectTasksMenu.addSeparator() self.__projectTasksMenu.addAction( self.tr("&Configure scan options"), self.__configureProjectTasksScanOptions) self.__menu = QMenu(self) self.__menu.addAction(self.tr("&New Task..."), self.__newTask) self.subtaskItem = self.__menu.addAction( self.tr("New &Sub-Task..."), self.__newSubTask) self.__menu.addSeparator() self.projectTasksMenuItem = self.__menu.addMenu( self.__projectTasksMenu) self.__menu.addSeparator() self.gotoItem = self.__menu.addAction( self.tr("&Go To"), self.__goToTask) self.__menu.addSeparator() self.copyItem = self.__menu.addAction( self.tr("&Copy"), self.__copyTask) self.pasteItem = self.__menu.addAction( self.tr("&Paste"), self.__pasteTask) self.pasteMainItem = self.__menu.addAction( self.tr("Paste as &Main Task"), self.__pasteMainTask) self.deleteItem = self.__menu.addAction( self.tr("&Delete"), self.__deleteTask) self.__menu.addSeparator() self.markCompletedItem = self.__menu.addAction( self.tr("&Mark Completed"), self.__markCompleted) self.__menu.addAction( self.tr("Delete Completed &Tasks"), self.__deleteCompleted) self.__menu.addSeparator() self.__menu.addAction( self.tr("P&roperties..."), self.__editTaskProperties) self.__menu.addSeparator() self.__menuFilteredAct = self.__menu.addAction( self.tr("&Filtered display")) self.__menuFilteredAct.setCheckable(True) self.__menuFilteredAct.setChecked(False) self.__menuFilteredAct.triggered[bool].connect(self.__activateFilter) self.__menu.addAction( self.tr("Filter c&onfiguration..."), self.__configureFilter) self.__menu.addSeparator() self.__menu.addAction( self.tr("Resi&ze columns"), self.__resizeColumns) self.__menu.addSeparator() self.__menu.addAction(self.tr("Configure..."), self.__configure) self.__backMenu = QMenu(self) self.__backMenu.addAction(self.tr("&New Task..."), self.__newTask) self.__backMenu.addSeparator() self.backProjectTasksMenuItem = self.__backMenu.addMenu( self.__projectTasksMenu) self.__backMenu.addSeparator() self.backPasteItem = self.__backMenu.addAction( self.tr("&Paste"), self.__pasteTask) self.backPasteMainItem = self.__menu.addAction( self.tr("Paste as &Main Task"), self.__pasteMainTask) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Delete Completed &Tasks"), self.__deleteCompleted) self.__backMenu.addSeparator() self.__backMenuFilteredAct = self.__backMenu.addAction( self.tr("&Filtered display")) self.__backMenuFilteredAct.setCheckable(True) self.__backMenuFilteredAct.setChecked(False) self.__backMenuFilteredAct.triggered[bool].connect( self.__activateFilter) self.__backMenu.addAction( self.tr("Filter c&onfiguration..."), self.__configureFilter) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Resi&ze columns"), self.__resizeColumns) self.__backMenu.addSeparator() self.__backMenu.addAction( self.tr("Configure..."), self.__configure) self.__activating = False self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.__showContextMenu) self.itemActivated.connect(self.__taskItemActivated) self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__generateTopLevelItems() def __generateTopLevelItems(self): """ Private method to generate the 'Extracted Tasks' item. """ self.__extractedItem = QTreeWidgetItem(self, [self.tr("Extracted Tasks")]) self.__manualItem = QTreeWidgetItem(self, [self.tr("Manual Tasks")]) for itm in [self.__extractedItem, self.__manualItem]: itm.setFirstColumnSpanned(True) itm.setExpanded(True) itm.setHidden(True) font = itm.font(0) font.setUnderline(True) itm.setFont(0, font) def __checkTopLevelItems(self): """ Private slot to check the 'Extracted Tasks' item for children. """ for itm in [self.__extractedItem, self.__manualItem]: visibleCount = itm.childCount() for index in range(itm.childCount()): if itm.child(index).isHidden(): visibleCount -= 1 itm.setHidden(visibleCount == 0) def __resort(self): """ Private method to resort the tree. """ self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder()) def __resizeColumns(self): """ Private method to resize the list columns. """ self.header().resizeSections(QHeaderView.ResizeToContents) self.header().setStretchLastSection(True) def findParentTask(self, parentUid): """ Public method to find a parent task by its ID. @param parentUid uid of the parent task (string) @return reference to the task (Task) """ if not parentUid: return None parentTask = None for task in self.tasks: if task.getUuid() == parentUid: parentTask = task break return parentTask def __refreshDisplay(self): """ Private method to refresh the display. """ for task in self.tasks: task.setHidden(not self.taskFilter.showTask(task)) self.__checkTopLevelItems() self.__resort() self.__resizeColumns() def __taskItemActivated(self, itm, col): """ Private slot to handle the activation of an item. @param itm reference to the activated item (QTreeWidgetItem) @param col column the item was activated in (integer) """ if not self.__activating and \ itm is not self.__extractedItem and \ itm is not self.__manualItem: self.__activating = True fn = itm.getFilename() if fn: self.displayFile.emit(fn, itm.getLineno()) else: self.__editTaskProperties() self.__activating = False def __showContextMenu(self, coord): """ Private slot to show the context menu of the list. @param coord the position of the mouse pointer (QPoint) """ itm = self.itemAt(coord) coord = self.mapToGlobal(coord) if itm is None or \ itm is self.__extractedItem or \ itm is self.__manualItem: self.backProjectTasksMenuItem.setEnabled(self.projectOpen) if self.copyTask: self.backPasteItem.setEnabled(True) self.backPasteMainItem.setEnabled(True) else: self.backPasteItem.setEnabled(False) self.backPasteMainItem.setEnabled(False) self.__backMenu.popup(coord) else: self.projectTasksMenuItem.setEnabled(self.projectOpen) if itm.getFilename(): self.gotoItem.setEnabled(True) self.deleteItem.setEnabled(True) self.markCompletedItem.setEnabled(False) self.copyItem.setEnabled(False) self.subtaskItem.setEnabled(False) else: self.gotoItem.setEnabled(False) self.deleteItem.setEnabled(True) self.markCompletedItem.setEnabled(True) self.copyItem.setEnabled(True) self.subtaskItem.setEnabled(True) if self.copyTask: self.pasteItem.setEnabled(True) self.pasteMainItem.setEnabled(True) else: self.pasteItem.setEnabled(False) self.pasteMainItem.setEnabled(False) self.__menu.popup(coord) def setProjectOpen(self, o=False): """ Public slot to set the project status. @param o flag indicating the project status """ self.projectOpen = o def addTask(self, summary, priority=1, filename="", lineno=0, completed=False, _time=0, isProjectTask=False, taskType=Task.TypeTodo, description="", uid="", parentTask=None): """ Public slot to add a task. @param summary summary text of the task (string) @param priority priority of the task (0=high, 1=normal, 2=low) @param filename filename containing the task (string) @param lineno line number containing the task (integer) @param completed flag indicating completion status (boolean) @param _time creation time of the task (float, if 0 use current time) @param isProjectTask flag indicating a task related to the current project (boolean) @param taskType type of the task (one of Task.TypeFixme, Task.TypeTodo, Task.TypeWarning, Task.TypeNote) @param description explanatory text of the task (string) @param uid unique id of the task (string) @param parentTask reference to the parent task item (Task) @return reference to the task item (Task) """ if parentTask: parentUid = parentTask.getUuid() else: parentUid = "" task = Task(summary, priority, filename, lineno, completed, _time, isProjectTask, taskType, self.project, description, uid, parentUid) self.tasks.append(task) if parentTask: parentTask.addChild(task) parentTask.setExpanded(True) elif filename: self.__extractedItem.addChild(task) else: self.__manualItem.addChild(task) task.setHidden(not self.taskFilter.showTask(task)) self.__checkTopLevelItems() self.__resort() self.__resizeColumns() if isProjectTask: self.__projectTasksSaveTimer.changeOccurred() return task def addFileTask(self, summary, filename, lineno, taskType=Task.TypeTodo, description=""): """ Public slot to add a file related task. @param summary summary text of the task (string) @param filename filename containing the task (string) @param lineno line number containing the task (integer) @param taskType type of the task (one of Task.TypeFixme, Task.TypeTodo, Task.TypeWarning, Task.TypeNote) @param description explanatory text of the task (string) """ self.addTask(summary, filename=filename, lineno=lineno, isProjectTask=( self.project and self.project.isProjectSource(filename)), taskType=taskType, description=description) def getProjectTasks(self): """ Public method to retrieve all project related tasks. @return copy of tasks (list of Task) """ tasks = [task for task in self.tasks if task.isProjectTask()] return tasks[:] def getGlobalTasks(self): """ Public method to retrieve all non project related tasks. @return copy of tasks (list of Task) """ tasks = [task for task in self.tasks if not task.isProjectTask()] return tasks[:] def clearTasks(self): """ Public slot to clear all tasks from display. """ self.tasks = [] self.clear() self.__generateTopLevelItems() def clearProjectTasks(self, fileOnly=False): """ Public slot to clear project related tasks. @keyparam fileOnly flag indicating to clear only file related project tasks (boolean) """ for task in reversed(self.tasks[:]): if (fileOnly and task.isProjectFileTask()) or \ (not fileOnly and task.isProjectTask()): if self.copyTask == task: self.copyTask = None parent = task.parent() parent.removeChild(task) self.tasks.remove(task) del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() def clearFileTasks(self, filename, conditionally=False): """ Public slot to clear all tasks related to a file. @param filename name of the file (string) @param conditionally flag indicating to clear the tasks of the file checking some conditions (boolean) """ if conditionally: if self.project and self.project.isProjectSource(filename): # project related tasks will not be cleared return if not Preferences.getTasks("ClearOnFileClose"): return for task in self.tasks[:]: if task.getFilename() == filename: if self.copyTask == task: self.copyTask = None self.__extractedItem.removeChild(task) self.tasks.remove(task) if task.isProjectTask: self.__projectTasksSaveTimer.changeOccurred() del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() def __editTaskProperties(self): """ Private slot to handle the "Properties" context menu entry. """ from .TaskPropertiesDialog import TaskPropertiesDialog task = self.currentItem() dlg = TaskPropertiesDialog(task, self, self.projectOpen) ro = task.getFilename() != "" if ro: dlg.setReadOnly() if dlg.exec_() == QDialog.Accepted and not ro: summary, priority, completed, isProjectTask, description = \ dlg.getData() task.setSummary(summary) task.setPriority(priority) task.setCompleted(completed) task.setProjectTask(isProjectTask) task.setDescription(description) self.__projectTasksSaveTimer.changeOccurred() def __newTask(self): """ Private slot to handle the "New Task" context menu entry. """ from .TaskPropertiesDialog import TaskPropertiesDialog dlg = TaskPropertiesDialog(None, self, self.projectOpen) if dlg.exec_() == QDialog.Accepted: summary, priority, completed, isProjectTask, description = \ dlg.getData() self.addTask(summary, priority, completed=completed, isProjectTask=isProjectTask, description=description) def __newSubTask(self): """ Private slot to handle the "New Sub-Task" context menu entry. """ parentTask = self.currentItem() projectTask = parentTask.isProjectTask() from .TaskPropertiesDialog import TaskPropertiesDialog dlg = TaskPropertiesDialog(None, self, self.projectOpen) dlg.setSubTaskMode(projectTask) if dlg.exec_() == QDialog.Accepted: summary, priority, completed, isProjectTask, description = \ dlg.getData() self.addTask(summary, priority, completed=completed, isProjectTask=isProjectTask, description=description, parentTask=parentTask) def __markCompleted(self): """ Private slot to handle the "Mark Completed" context menu entry. """ task = self.currentItem() task.setCompleted(True) def __deleteCompleted(self): """ Private slot to handle the "Delete Completed Tasks" context menu entry. """ for task in reversed(self.tasks[:]): if task.isCompleted(): if self.copyTask == task: self.copyTask = None parent = task.parent() parent.removeChild(task) self.tasks.remove(task) if task.isProjectTask: self.__projectTasksSaveTimer.changeOccurred() del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() ci = self.currentItem() if ci: ind = self.indexFromItem(ci, self.currentColumn()) self.scrollTo(ind, QAbstractItemView.PositionAtCenter) def __copyTask(self): """ Private slot to handle the "Copy" context menu entry. """ task = self.currentItem() self.copyTask = task def __pasteTask(self): """ Private slot to handle the "Paste" context menu entry. """ if self.copyTask: parent = self.copyTask.parent() if not isinstance(parent, Task): parent = None self.addTask(self.copyTask.summary, priority=self.copyTask.priority, completed=self.copyTask.completed, description=self.copyTask.description, isProjectTask=self.copyTask._isProjectTask, parentTask=parent) def __pasteMainTask(self): """ Private slot to handle the "Paste as Main Task" context menu entry. """ if self.copyTask: self.addTask(self.copyTask.summary, priority=self.copyTask.priority, completed=self.copyTask.completed, description=self.copyTask.description, isProjectTask=self.copyTask._isProjectTask) def __deleteSubTasks(self, task): """ Private method to delete all sub-tasks. @param task task to delete sub-tasks of (Task) """ for subtask in task.takeChildren(): if self.copyTask == subtask: self.copyTask = None if subtask.childCount() > 0: self.__deleteSubTasks(subtask) self.tasks.remove(subtask) def __deleteTask(self): """ Private slot to handle the "Delete Task" context menu entry. """ task = self.currentItem() if self.copyTask == task: self.copyTask = None if task.childCount() > 0: self.__deleteSubTasks(task) parent = task.parent() parent.removeChild(task) self.tasks.remove(task) if task.isProjectTask: self.__projectTasksSaveTimer.changeOccurred() del task self.__checkTopLevelItems() self.__resort() self.__resizeColumns() ci = self.currentItem() if ci: ind = self.indexFromItem(ci, self.currentColumn()) self.scrollTo(ind, QAbstractItemView.PositionAtCenter) def __goToTask(self): """ Private slot to handle the "Go To" context menu entry. """ task = self.currentItem() self.displayFile.emit(task.getFilename(), task.getLineno()) def handlePreferencesChanged(self): """ Public slot to react to changes of the preferences. """ for task in self.tasks: task.colorizeTask() def __activateFilter(self, on): """ Private slot to handle the "Filtered display" context menu entry. @param on flag indicating the filter state (boolean) """ if on and not self.taskFilter.hasActiveFilter(): res = E5MessageBox.yesNo( self, self.tr("Activate task filter"), self.tr( """The task filter doesn't have any active filters.""" """ Do you want to configure the filter settings?"""), yesDefault=True) if not res: on = False else: self.__configureFilter() on = self.taskFilter.hasActiveFilter() self.taskFilter.setActive(on) self.__menuFilteredAct.setChecked(on) self.__backMenuFilteredAct.setChecked(on) self.__refreshDisplay() def __configureFilter(self): """ Private slot to handle the "Configure filter" context menu entry. """ from .TaskFilterConfigDialog import TaskFilterConfigDialog dlg = TaskFilterConfigDialog(self.taskFilter) if dlg.exec_() == QDialog.Accepted: dlg.configureTaskFilter(self.taskFilter) self.__refreshDisplay() def __configureProjectTasksScanOptions(self): """ Private slot to configure scan options for project tasks. """ filter, ok = QInputDialog.getText( self, self.tr("Scan Filter Patterns"), self.tr("Enter filename patterns of files" " to be excluded separated by a comma:"), QLineEdit.Normal, self.projectTasksScanFilter) if ok: self.projectTasksScanFilter = filter def __regenerateProjectTasks(self): """ Private slot to handle the "Regenerated project tasks" context menu entry. """ markers = { Task.TypeWarning: Preferences.getTasks("TasksWarningMarkers").split(), Task.TypeNote: Preferences.getTasks("TasksNoteMarkers").split(), Task.TypeTodo: Preferences.getTasks("TasksTodoMarkers").split(), Task.TypeFixme: Preferences.getTasks("TasksFixmeMarkers").split(), } files = self.project.pdata["SOURCES"] # apply file filter filterList = [f.strip() for f in self.projectTasksScanFilter.split(",") if f.strip()] if filterList: for filter in filterList: files = [f for f in files if not fnmatch.fnmatch(f, filter)] # remove all project tasks self.clearProjectTasks(fileOnly=True) # now process them progress = E5ProgressDialog( self.tr("Extracting project tasks..."), self.tr("Abort"), 0, len(files), self.tr("%v/%m Files")) progress.setMinimumDuration(0) progress.setWindowTitle(self.tr("Tasks")) count = 0 for file in files: progress.setLabelText( self.tr("Extracting project tasks...\n{0}").format(file)) progress.setValue(count) QApplication.processEvents() if progress.wasCanceled(): break fn = os.path.join(self.project.ppath, file) # read the file and split it into textlines try: text, encoding = Utilities.readEncodedFile(fn) lines = text.splitlines() except (UnicodeError, IOError): count += 1 progress.setValue(count) continue # now search tasks and record them lineIndex = 0 for line in lines: lineIndex += 1 shouldBreak = False for taskType, taskMarkers in markers.items(): for taskMarker in taskMarkers: index = line.find(taskMarker) if index > -1: task = line[index:] self.addFileTask(task, fn, lineIndex, taskType) shouldBreak = True break if shouldBreak: break count += 1 progress.setValue(len(files)) def __configure(self): """ Private method to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences("tasksPage") def saveProjectTasks(self): """ Public method to write the project tasks. """ if self.projectOpen and Preferences.getTasks("TasksProjectAutoSave"): self.project.writeTasks()
def on_update(self): selected_item = self.currentItem() current_token_id = selected_item.data(0, Qt.UserRole) if selected_item else None self.clear() tokens = self.parent.wallet.token_types.copy() for token_id, i in tokens.items(): name = i["name"] decimals = i["decimals"] calculated_balance= self.get_balance_from_token_id(token_id) if decimals != "?": balancestr = format_satoshis_nofloat(calculated_balance, decimal_point=decimals, num_zeros=decimals) balancestr += ' '*(9-decimals) else: balancestr = "double-click to add" typestr = "?" if i['class'] == "SLP1": typestr = "Type 1" elif i['class'] == "SLP65": typestr = "NFT1 Child" elif i['class'] == "SLP129": typestr = "NFT1 Parent" try: self.parent.wallet.get_slp_token_baton(token_id) item = QTreeWidgetItem([str(token_id),str(name),str(decimals),balancestr,"★", typestr]) except SlpNoMintingBatonFound: item = QTreeWidgetItem([str(token_id),str(name),str(decimals),balancestr,"", typestr]) squishyfont = QFont(MONOSPACE_FONT) squishyfont.setStretch(85) item.setFont(0, squishyfont) #item.setTextAlignment(2, Qt.AlignRight) item.setTextAlignment(3, Qt.AlignRight) item.setFont(3, QFont(MONOSPACE_FONT)) item.setData(0, Qt.UserRole, token_id) if decimals == "?": item.setForeground(0, QBrush(QColor("#BC1E1E"))) item.setForeground(1, QBrush(QColor("#BC1E1E"))) item.setForeground(2, QBrush(QColor("#BC1E1E"))) item.setForeground(3, QBrush(QColor("#BC1E1E"))) item.setForeground(4, QBrush(QColor("#BC1E1E"))) item.setForeground(5, QBrush(QColor("#BC1E1E"))) if i["class"] == "SLP129": for _token_id, _i in self.parent.wallet.token_types.items(): if _i["class"] == "SLP65" and _i.get("group_id", None) == token_id: name = _i["name"] decimals = _i["decimals"] calculated_balance= self.get_balance_from_token_id(_token_id) if decimals != "?": balancestr = format_satoshis_nofloat(calculated_balance, decimal_point=decimals, num_zeros=decimals) balancestr += ' '*(9-decimals) else: balancestr = "double-click to add" _nft_item = QTreeWidgetItem([str(_token_id),str(name),str(decimals),balancestr,"", "NFT1 Child"]) squishyfont = QFont(MONOSPACE_FONT) squishyfont.setStretch(85) _nft_item.setFont(0, squishyfont) #item.setTextAlignment(2, Qt.AlignRight) _nft_item.setTextAlignment(3, Qt.AlignRight) _nft_item.setFont(3, QFont(MONOSPACE_FONT)) _nft_item.setData(0, Qt.UserRole, _token_id) if decimals == "?": _nft_item.setForeground(0, QBrush(QColor("#BC1E1E"))) _nft_item.setForeground(1, QBrush(QColor("#BC1E1E"))) _nft_item.setForeground(2, QBrush(QColor("#BC1E1E"))) _nft_item.setForeground(3, QBrush(QColor("#BC1E1E"))) item.addChild(_nft_item) self.addTopLevelItem(item) elif i["class"] == "SLP65" and i.get("group_id", "?") == "?": self.addTopLevelItem(item) elif i["class"] == "SLP1": self.addTopLevelItem(item) if current_token_id == token_id: self.setCurrentItem(item) self.expandAll()
def update_song_properties(self): index = self.ui.tableView_Game.selectedIndexes() if len(index) > 0: assert isinstance(index[0], QModelIndex) row_id = index[0].sibling(index[0].row(), 0).data() song_query = QSqlQuery() song_query.prepare('SELECT t_song.id, t_song.name, t_anime.name, t_song_type.name ' 'FROM t_point ' 'INNER JOIN t_song ON t_point.id_song = t_song.id ' 'INNER JOIN t_anime ON t_anime.id = t_song.id_anime ' 'INNER JOIN t_song_type ON t_song_type.id = t_song.id_song_type ' 'WHERE t_point.id = ' + str(row_id)) song_query.setForwardOnly(1) song_query.exec_() song = QTreeWidgetItem() song.setText(0, "Song:") while song_query.next(): song_id = QTreeWidgetItem() song_name = QTreeWidgetItem() anime_name = QTreeWidgetItem() song_type = QTreeWidgetItem() song_id.setText(0, "ID: " + str(song_query.value(0))) song_name.setText(0, "Name: " + song_query.value(1)) anime_name.setText(0, "Anime: " + song_query.value(2)) song_type.setText(0, "Type: " + song_query.value(3)) artist_query = QSqlQuery() artist_query.prepare('SELECT t_artist.id, t_artist.name ' 'FROM t_song ' 'INNER JOIN t_song_artist ON t_song.id = t_song_artist.id_song ' 'INNER JOIN t_artist ON t_artist.id = t_song_artist.id_artist ' 'WHERE t_song.id = ' + str(song_query.value(0))) artist_query.setForwardOnly(1) artist_query.exec_() artists = QTreeWidgetItem() artists.setText(0, "Artists:") while artist_query.next(): artist = QTreeWidgetItem() artist.setText(0, str(artist_query.value(0)) + " - " + artist_query.value(1)) artists.addChild(artist) song.addChild(song_id) song.addChild(song_name) song.addChild(anime_name) song.addChild(song_type) song.addChild(artists) self.update_game_properties() self.ui.treeWidget_Game_Properties.addTopLevelItem(song) self.ui.treeWidget_Game_Properties.expandAll()
def on_update(self): def item_path( item ): # Recursively builds the path for an item eg 'parent_name/item_name' return item.text(0) if not item.parent() else item_path( item.parent()) + "/" + item.text(0) def remember_expanded_items(root): # Save the set of expanded items... so that address list updates don't annoyingly collapse # our tree list widget due to the update. This function recurses. Pass self.invisibleRootItem(). expanded_item_names = set() for i in range(0, root.childCount()): it = root.child(i) if it and it.childCount(): if it.isExpanded(): expanded_item_names.add(item_path(it)) expanded_item_names |= remember_expanded_items( it) # recurse return expanded_item_names def restore_expanded_items(root, expanded_item_names): # Recursively restore the expanded state saved previously. Pass self.invisibleRootItem(). for i in range(0, root.childCount()): it = root.child(i) if it and it.childCount(): restore_expanded_items( it, expanded_item_names) # recurse, do leaves first old = bool(it.isExpanded()) new = bool(item_path(it) in expanded_item_names) if old != new: it.setExpanded(new) self.wallet = self.parent.wallet had_item_count = self.topLevelItemCount() sels = self.selectedItems() addresses_to_re_select = {item.data(0, Qt.UserRole) for item in sels} expanded_item_names = remember_expanded_items(self.invisibleRootItem()) del sels # avoid keeping reference to about-to-be delete C++ objects self.clear() # Note we take a shallow list-copy because we want to avoid # race conditions with the wallet while iterating here. The wallet may # touch/grow the returned lists at any time if a history comes (it # basically returns a reference to its own internal lists). The wallet # may then, in another thread such as the Synchronizer thread, grow # the receiving or change addresses on Deterministic wallets. While # probably safe in a language like Python -- and especially since # the lists only grow at the end, we want to avoid bad habits. # The performance cost of the shallow copy below is negligible for 10k+ # addresses even on huge wallets because, I suspect, internally CPython # does this type of operation extremely cheaply (probably returning # some copy-on-write-semantics handle to the same list). receiving_addresses = list(self.wallet.get_receiving_addresses()) change_addresses = list(self.wallet.get_change_addresses()) if self.parent.fx and self.parent.fx.get_fiat_address_config(): fx = self.parent.fx else: fx = None account_item = self sequences = [0, 1] if change_addresses else [0] items_to_re_select = [] for is_change in sequences: if len(sequences) > 1: name = _("Receiving") if not is_change else _("Change") seq_item = QTreeWidgetItem([name, '', '', '', '', '']) account_item.addChild(seq_item) if not is_change and not had_item_count: # first time we create this widget, auto-expand the default address list seq_item.setExpanded(True) expanded_item_names.add(item_path(seq_item)) else: seq_item = account_item used_item = QTreeWidgetItem([_("Used"), '', '', '', '', '']) used_flag = False addr_list = change_addresses if is_change else receiving_addresses for n, address in enumerate(addr_list): num = len(self.wallet.get_address_history(address)) is_used = self.wallet.is_used(address) balance = sum(self.wallet.get_addr_balance(address)) address_text = address.to_ui_string() label = self.wallet.labels.get(address.to_storage_string(), '') balance_text = self.parent.format_amount(balance, whitespaces=True) columns = [address_text, str(n), label, balance_text, str(num)] if fx: rate = fx.exchange_rate() fiat_balance = fx.value_str(balance, rate) columns.insert(4, fiat_balance) address_item = SortableTreeWidgetItem(columns) address_item.setTextAlignment(3, Qt.AlignRight) address_item.setFont(3, QFont(MONOSPACE_FONT)) if fx: address_item.setTextAlignment(4, Qt.AlignRight) address_item.setFont(4, QFont(MONOSPACE_FONT)) address_item.setFont(0, QFont(MONOSPACE_FONT)) address_item.setData(0, Qt.UserRole, address) address_item.setData(0, Qt.UserRole + 1, True) # label can be edited if self.wallet.is_frozen(address): address_item.setBackground(0, QColor('lightblue')) if self.wallet.is_beyond_limit(address, is_change): address_item.setBackground(0, QColor('red')) if is_used: if not used_flag: seq_item.insertChild(0, used_item) used_flag = True used_item.addChild(address_item) else: seq_item.addChild(address_item) if address in addresses_to_re_select: items_to_re_select.append(address_item) for item in items_to_re_select: # NB: Need to select the item at the end becasue internally Qt does some index magic # to pick out the selected item and the above code mutates the TreeList, invalidating indices # and other craziness, which might produce UI glitches. See #1042 item.setSelected(True) # Now, at the very end, enforce previous UI state with respect to what was expanded or not. See #1042 restore_expanded_items(self.invisibleRootItem(), expanded_item_names)
def createTabWiget(self, index): wid = QWidget() layout = QHBoxLayout(wid) ################################################################### tree = QTreeWidget(self) # 2 tree.setColumnCount(1) tree.setHeaderLabels([' ', ' ']) #tree.header().setVisible(False) tree.header().setCascadingSectionResizes(True) #tree.itemClicked.connect(self.change_func) preview = QTreeWidgetItem(tree) # 3 preview.setText(0, self.tr('Preview')) # self.preview = QTreeWidgetItem() # self.preview.setText(0, 'Preview') # self.tree.addTopLevelItem(self.preview) qt5112 = QTreeWidgetItem() # 4 qt5112.setText(0, self.tr('Qt 5.11.2 snapshot')) qt5112.setCheckState(0, Qt.Unchecked) preview.addChild(qt5112) choice_list = [ 'macOS', 'Android x86', 'Android ARMv7', 'Sources', 'iOS' ] self.item_list = [] for i, c in enumerate(choice_list): # 5 item = QTreeWidgetItem(qt5112) item.setText(0, c) item.setCheckState(0, Qt.Unchecked) self.item_list.append(item) #test_item = QTreeWidgetItem(qt5112) # 6 #test_item.setText(0, 'test1') #test_item.setText(1, 'test2') tree.expandAll() # 7 ################################################################## treeLayout = QHBoxLayout() treeLayout.addWidget(tree) treeframe = QFrame() treeframe.setFrameStyle(QFrame.Box | QFrame.Raised) treeframe.setLayout(treeLayout) layout.addWidget(treeframe) '''''' #create settings eara layout funLayout = QHBoxLayout() hwFrame = QFrame() hwFrame.setFrameStyle(QFrame.Box | QFrame.Raised) recorderFrame = QFrame() recorderFrame.setFrameStyle(QFrame.Box | QFrame.Raised) playFrame = QFrame() playFrame.setFrameStyle(QFrame.Box | QFrame.Raised) buttonFrame = QFrame() buttonLayout = QVBoxLayout() buttonFrame.setLayout(buttonLayout) buttonNameList = [ self.tr("settings"), self.tr("start"), self.tr("covert") ] btn_settings = QPushButton(buttonNameList[0]) buttonLayout.addWidget(btn_settings) btn_start = QPushButton(buttonNameList[1]) buttonLayout.addWidget(btn_start) btn_covert = QPushButton(buttonNameList[2]) buttonLayout.addWidget(btn_covert) buttonLayout.addStretch(0) funLayout.addWidget(hwFrame) funLayout.addWidget(recorderFrame) funLayout.addWidget(playFrame) funLayout.addWidget(buttonFrame) funLayout.setStretch(0, 4) funLayout.setStretch(1, 4) funLayout.setStretch(2, 4) funLayout.setStretch(3, 1) rightframe = QFrame() rightframe.setFrameStyle(QFrame.Box | QFrame.Raised) rightframe.setLayout(funLayout) layout.addWidget(rightframe) wid.setLayout(layout) layout.setStretch(0, 2) layout.setStretch(1, 11) #settingsLayOutOnRightFrame = QHBoxLayout(rightframe) #twSetting = QTabWidget(settingsLayOutOnRightFrame) return wid
def __init__(self, dialog): super(FontsColors, self).__init__(dialog) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.scheme = SchemeSelector(self) layout.addWidget(self.scheme) self.printScheme = QCheckBox() layout.addWidget(self.printScheme) hbox = QHBoxLayout() self.tree = QTreeWidget(self) self.tree.setHeaderHidden(True) self.tree.setAnimated(True) self.stack = QStackedWidget(self) hbox.addWidget(self.tree) hbox.addWidget(self.stack) layout.addLayout(hbox) hbox = QHBoxLayout() self.fontLabel = QLabel() self.fontChooser = QFontComboBox() self.fontSize = QDoubleSpinBox() self.fontSize.setRange(6.0, 32.0) self.fontSize.setSingleStep(0.5) self.fontSize.setDecimals(1) hbox.addWidget(self.fontLabel) hbox.addWidget(self.fontChooser, 1) hbox.addWidget(self.fontSize) layout.addLayout(hbox) # add the items to our list self.baseColorsItem = i = QTreeWidgetItem() self.tree.addTopLevelItem(i) self.defaultStylesItem = i = QTreeWidgetItem() self.tree.addTopLevelItem(i) self.defaultStyles = {} for name in textformats.defaultStyles: self.defaultStyles[name] = i = QTreeWidgetItem() self.defaultStylesItem.addChild(i) i.name = name self.defaultStylesItem.setExpanded(True) self.allStyles = {} for group, styles in ly.colorize.default_mapping(): i = QTreeWidgetItem() children = {} self.allStyles[group] = (i, children) self.tree.addTopLevelItem(i) i.group = group for name, base, clss in styles: j = QTreeWidgetItem() j.name = name j.base = base i.addChild(j) children[name] = j self.baseColorsWidget = BaseColors(self) self.customAttributesWidget = CustomAttributes(self) self.emptyWidget = QWidget(self) self.stack.addWidget(self.baseColorsWidget) self.stack.addWidget(self.customAttributesWidget) self.stack.addWidget(self.emptyWidget) self.tree.currentItemChanged.connect(self.currentItemChanged) self.tree.setCurrentItem(self.baseColorsItem) self.scheme.currentChanged.connect(self.currentSchemeChanged) self.scheme.changed.connect(self.changed) self.baseColorsWidget.changed.connect(self.baseColorsChanged) self.customAttributesWidget.changed.connect(self.customAttributesChanged) self.fontChooser.currentFontChanged.connect(self.fontChanged) self.fontSize.valueChanged.connect(self.fontChanged) self.printScheme.clicked.connect(self.printSchemeChanged) app.translateUI(self)
class TreeLayerItem(QTreeWidgetItem): layerIcon = QIcon(os.path.join(os.path.dirname(__file__), "icons", "layer.png")) def __init__(self, iface, layer, tree, dlg): QTreeWidgetItem.__init__(self) self.iface = iface self.layer = layer self.setText(0, layer.name()) self.setIcon(0, self.layerIcon) project = QgsProject.instance() if project.layerTreeRoot().findLayer(layer.id()).isVisible(): self.setCheckState(0, Qt.Checked) else: self.setCheckState(0, Qt.Unchecked) self.visibleItem = QTreeWidgetItem(self) self.visibleCheck = QCheckBox() vis = layer.customProperty("qgis2web/Visible", True) if (vis == 0 or unicode(vis).lower() == "false"): self.visibleCheck.setChecked(False) else: self.visibleCheck.setChecked(True) self.visibleItem.setText(0, "Visible") self.addChild(self.visibleItem) tree.setItemWidget(self.visibleItem, 1, self.visibleCheck) if layer.type() == layer.VectorLayer: if layer.providerType() == 'WFS': self.jsonItem = QTreeWidgetItem(self) self.jsonCheck = QCheckBox() if layer.customProperty("qgis2web/Encode to JSON") == 2: self.jsonCheck.setChecked(True) self.jsonItem.setText(0, "Encode to JSON") self.jsonCheck.stateChanged.connect(self.changeJSON) self.addChild(self.jsonItem) tree.setItemWidget(self.jsonItem, 1, self.jsonCheck) if layer.geometryType() == QgsWkbTypes.PointGeometry: self.clusterItem = QTreeWidgetItem(self) self.clusterCheck = QCheckBox() if layer.customProperty("qgis2web/Cluster") == 2: self.clusterCheck.setChecked(True) self.clusterItem.setText(0, "Cluster") self.clusterCheck.stateChanged.connect(self.changeCluster) self.addChild(self.clusterItem) tree.setItemWidget(self.clusterItem, 1, self.clusterCheck) self.popupItem = QTreeWidgetItem(self) self.popupItem.setText(0, "Popup fields") options = [] fields = self.layer.fields() for f in fields: fieldIndex = fields.indexFromName(unicode(f.name())) editorWidget = layer.editorWidgetSetup(fieldIndex).type() if editorWidget == 'Hidden': continue options.append(f.name()) for option in options: self.attr = QTreeWidgetItem(self) self.attrWidget = QComboBox() self.attrWidget.addItem("no label") self.attrWidget.addItem("inline label") self.attrWidget.addItem("header label") custProp = layer.customProperty("qgis2web/popup/" + option) if (custProp != "" and custProp is not None): self.attrWidget.setCurrentIndex( self.attrWidget.findText( layer.customProperty("qgis2web/popup/" + option))) self.attr.setText(1, option) self.popupItem.addChild(self.attr) tree.setItemWidget(self.attr, 2, self.attrWidget) self.addChild(self.popupItem) else: if layer.providerType() == 'wms': self.getFeatureInfoItem = QTreeWidgetItem(self) self.getFeatureInfoCheck = QCheckBox() if layer.customProperty("qgis2web/GetFeatureInfo") == 2: self.getFeatureInfoCheck.setChecked(True) self.getFeatureInfoItem.setText(0, "Enable GetFeatureInfo?") self.getFeatureInfoCheck.stateChanged.connect( self.changeGetFeatureInfo) self.addChild(self.getFeatureInfoItem) tree.setItemWidget(self.getFeatureInfoItem, 1, self.getFeatureInfoCheck) @property def popup(self): popup = [] self.tree = self.treeWidget() for p in range(self.childCount()): item = self.child(p).text(1) if item != "": popupVal = self.tree.itemWidget(self.child(p), 2).currentText() pair = (item, popupVal) popup.append(pair) popup = OrderedDict(popup) return popup @property def visible(self): return self.visibleCheck.isChecked() @property def json(self): try: return self.jsonCheck.isChecked() except: return False @property def cluster(self): try: return self.clusterCheck.isChecked() except: return False @property def getFeatureInfo(self): try: return self.getFeatureInfoCheck.isChecked() except: return False def changeJSON(self, isJSON): self.layer.setCustomProperty("qgis2web/Encode to JSON", isJSON) def changeCluster(self, isCluster): self.layer.setCustomProperty("qgis2web/Cluster", isCluster) def changeGetFeatureInfo(self, isGetFeatureInfo): self.layer.setCustomProperty("qgis2web/GetFeatureInfo", isGetFeatureInfo)
def load_streams(self): while self.__download_manager.thread_count > 1: self.sig_step.emit(self.id, 'Waiting for threads to clear...') thread_name = QThread.currentThread().objectName() thread_id = int(QThread.currentThreadId()) self.sig_step.emit(self.id, f'{thread_id}: {thread_name} thread starting...') self.__download_manager.videos = [] self.__download_manager.streams = [] proxies = self.__download_manager.get_proxies() top_level_item_count = self.__download_manager.stream_tree.topLevelItemCount( ) for i in range(top_level_item_count): self.__download_manager.stream_tree.takeTopLevelItem(i) self.__download_manager.stream_tree.clear() self.__download_manager.streams_to_download = {} try: print('get video id') print(extract.video_id(self.__download_manager.url.text())) self.sig_step.emit(self.id, f'Loading video') loaded_url = YouTube(self.__download_manager.url.text(), proxies=proxies) self.sig_step.emit(self.id, f'Loaded video: {loaded_url.title}') self.sig_msg.emit(f'Found {loaded_url.title}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return self.__download_manager.videos.append(loaded_url) except RegexMatchError: print('playlist') if 'playlist' in self.__download_manager.url.text(): regex_search(r'(?:list=|\/)([0-9A-Za-z_-]{11}).*', self.__download_manager.url.text(), group=1) loaded_url = Playlist(self.__download_manager.url.text()) self.sig_msg.emit(f'Loaded playlist. Discovering videos...') loaded_url.populate_video_urls() i = 0 self.sig_progress_status.emit(0) for video_url in loaded_url.video_urls: self.sig_step.emit(self.id, f'Loading video {i}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return self.sig_progress_total.emit( int((i / (len(loaded_url.video_urls) * 2)) * 100)) vid = YouTube(video_url, proxies=proxies) self.sig_step.emit(self.id, f'Loaded video: {vid.title}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return self.sig_msg.emit(f'Found {vid.title}') self.__download_manager.videos.append(vid) self.sig_progress_status.emit( int((i / len(loaded_url.video_urls)) * 100)) i += 1 self.sig_progress_total.emit(50) else: self.sig_error.emit('Could not determine Video ' 'or Playlist ID from provided URL!\n' 'Please check input!') self.sig_done.emit(self.id) return except Exception as e: self.sig_error.emit(str(e)) self.sig_done.emit(self.id) return self.sig_msg.emit(f'Loading Streams..') print('loading streams') i = 0 for video in self.__download_manager.videos: self.sig_progress_status.emit(0) self.sig_step.emit(self.id, f'Loading streams for video {i}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return audio_streams = QTreeWidgetItem(['Audio Only']) tree_item = StreamTreeWidgetItem([video.title], f'video_{i}', self.__download_manager, video, None) self.__download_manager.streams = video.streams x = 0 for stream in self.__download_manager.streams: self.sig_step.emit(self.id, f'Loading stream {x}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return self.sig_msg.emit( f'Video {i + 1}/{len(self.__download_manager.videos)}: ' f'Loading Stream ITAG ID: {stream.itag}') if stream.video_codec is None: stream_item = StreamTreeWidgetItem([ f'Codec: {stream.audio_codec}, ' f'ABR: {stream.abr}, ' f'File Type: {stream.mime_type.split("/")[1]}, ' f'Size: {stream.filesize // 1024} KB' ], f'video_{i}_stream{x}', self.__download_manager, video, stream) self.sig_step.emit(self.id, f'Loaded stream {x}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return audio_streams.addChild(stream_item) else: stream_item = StreamTreeWidgetItem([ f'Res: {stream.resolution}, FPS: {stream.fps}, ' f' Video Codec: {stream.video_codec}, Audio Codec: {stream.audio_codec}, ' f'File Type: {stream.mime_type.split("/")[1]}, ' f'Size: {stream.filesize // 1024} KB' ], f'video_{i}_stream{x}', self.__download_manager, video, stream) self.sig_step.emit(self.id, f'Loaded stream {x}') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return tree_item.addChild(stream_item) stream_item.setCheckState(0, Qt.Unchecked) x += 1 self.sig_progress_status.emit( int((x / len(self.__download_manager.streams)) * 100)) tree_item.addChild(audio_streams) self.sig_step.emit(self.id, f'Adding video {i} to tree') if self.__abort: self.sig_progress_status.emit(f'Aborted!') self.sig_done.emit(self.id) return self.__download_manager.stream_tree.addTopLevelItem(tree_item) i += 1 self.sig_progress_status.emit(100) self.sig_progress_total.emit( int((i / (len(self.__download_manager.videos) * 2)) * 100) + 50) self.sig_msg.emit(f'Streams Loaded!') self.sig_done.emit(self.id)
class MenuItems(QTreeWidget): """Menu Items This class is responsible for creating, configuring and building the items in the items menu, located on the left side of the interface. """ def __init__(self, main_window): super().__init__() self.mainWindow = main_window self.project = main_window.getProject() # self._createIcons() # self._configItemSizes() self._createFonts() self._createColorsBrush() self._configTree() self._createItems() self._addItems() self._configItems() self._updateItems() def keyPressEvent(self, event): """This deals with key events that are directly linked with the menu.""" if event.key() == Qt.Key_F5: self.mainWindow.getInputWidget().runAnalysis() self._updateItems() def _createIcons(self): """Create Icons objects that are placed on the right side of the item. Currently isn't used. """ self.icon_child_set_material = QIcon() self.icon_child_set_material.addPixmap(QPixmap("data/icons/pulse.png"), QIcon.Active, QIcon.On) def _createFonts(self): """Create Font objects that configure the font of the items.""" self.font_top_Items = QFont() self.font_top_Items.setFamily("Segoe UI") self.font_top_Items.setPointSize(13) self.font_top_Items.setBold(True) self.font_top_Items.setItalic(False) self.font_top_Items.setWeight(75) self.font_child_Items = QFont() self.font_child_Items.setFamily("Segoe UI") self.font_child_Items.setPointSize(12) #self.font_child_Items.setBold(False) #self.font_child_Items.setItalic(True) self.font_child_Items.setWeight(60) def _createColorsBrush(self): """Create Color objects that define the color of the text and/or background of the items.""" self.QLinearGradient_upper = QLinearGradient(0, 0, 400, 0) self.QLinearGradient_upper.setColorAt(1, QColor(60, 60, 60, 150)) self.QLinearGradient_upper.setColorAt(0, QColor(220, 220, 220, 150)) self.QLinearGradient_lower = QLinearGradient(0, 0, 400, 0) self.QLinearGradient_lower.setColorAt(1, QColor(102, 204, 255, 100)) self.QLinearGradient_lower.setColorAt(0, QColor(240, 240, 240, 150)) self.brush_upper_items = QBrush(self.QLinearGradient_upper) self.brush_upper_items.setStyle(Qt.LinearGradientPattern) self.brush_lower_items = QBrush(self.QLinearGradient_lower) self.brush_lower_items.setStyle(Qt.LinearGradientPattern) def _configItemSizes(self): """Creates a control to the items height size.""" self.top_items_size = QSize() self.top_items_size.setHeight(35) self.child_items_size = QSize() self.child_items_size.setHeight(20) def _configTree(self): """Define the initial configuration of the TreeWidget.""" self.setHeaderHidden(True) self.setTabKeyNavigation(True) self.setRootIsDecorated(True) self.setFrameShape(1) # self.setFrameShadow(3) self.setLineWidth(2) # self.setStyleSheet("QTreeWidget{alternate-background-color: red; background: black;}") # self.setIndentation(20) # self.setColumnWidth(0, 50) self.itemClicked.connect(self.on_click_item) def _createItems(self): """Creates all TreeWidgetItems.""" self.list_top_items = [] self.list_child_items = [] self.item_top_generalSettings = QTreeWidgetItem(['General Settings']) self.item_child_setProjectAttributes = QTreeWidgetItem( ['Set Project Attributes']) self.item_child_setGeometryFile = QTreeWidgetItem( ['Set Geometry File']) self.item_child_setMeshProperties = QTreeWidgetItem( ['Set Mesh Properties']) self.item_child_set_material = QTreeWidgetItem(['Set Material']) self.item_child_set_fluid = QTreeWidgetItem(['Set Fluid']) self.item_child_set_crossSection = QTreeWidgetItem( ['Set Cross-Section']) # self.list_top_items.append(self.item_top_generalSettings) self.list_child_items.append(self.item_child_setProjectAttributes) self.list_child_items.append(self.item_child_setGeometryFile) self.list_child_items.append(self.item_child_setGeometryFile) self.list_child_items.append(self.item_child_setMeshProperties) self.list_child_items.append(self.item_child_set_material) self.list_child_items.append(self.item_child_set_fluid) self.list_child_items.append(self.item_child_set_crossSection) # self.item_top_structuralModelSetup = QTreeWidgetItem( ['Structural Model Setup']) self.item_child_setStructuralElementType = QTreeWidgetItem( ['Set Structural Element Type']) self.item_child_addFlanges = QTreeWidgetItem( ['Add Connecting Flanges']) self.item_child_setBeamXaxisRotation = QTreeWidgetItem( ['Set Beam X-axis Rotation']) self.item_child_setRotationDecoupling = QTreeWidgetItem( ['Set Rotation Decoupling']) self.item_child_setPrescribedDofs = QTreeWidgetItem( ['Set Prescribed DOFs']) self.item_child_setNodalLoads = QTreeWidgetItem(['Set Nodal Loads']) self.item_child_addMassSpringDamper = QTreeWidgetItem( ['Add: Mass / Spring / Damper']) self.item_child_add_elastic_nodal_links = QTreeWidgetItem( ['Add Elastic Nodal Links']) self.item_child_add_expansion_joint = QTreeWidgetItem( ['Add Expansion Joint']) self.item_child_add_valve = QTreeWidgetItem(['Add Valve']) self.item_child_setcappedEnd = QTreeWidgetItem(['Set Capped End']) self.item_child_set_stress_stiffening = QTreeWidgetItem( ['Set Stress Stiffening']) # self.list_top_items.append(self.item_top_structuralModelSetup) self.list_child_items.append(self.item_child_setStructuralElementType) self.list_child_items.append(self.item_child_addFlanges) self.list_child_items.append(self.item_child_setBeamXaxisRotation) self.list_child_items.append(self.item_child_setRotationDecoupling) self.list_child_items.append(self.item_child_setPrescribedDofs) self.list_child_items.append(self.item_child_setNodalLoads) self.list_child_items.append(self.item_child_addMassSpringDamper) self.list_child_items.append(self.item_child_add_elastic_nodal_links) self.list_child_items.append(self.item_child_add_expansion_joint) self.list_child_items.append(self.item_child_add_valve) self.list_child_items.append(self.item_child_setcappedEnd) self.list_child_items.append(self.item_child_set_stress_stiffening) # self.item_top_acousticModelSetup = QTreeWidgetItem( ['Acoustic Model Setup']) self.item_child_setAcousticElementType = QTreeWidgetItem( ['Set Acoustic Element Type']) self.item_child_setAcousticPressure = QTreeWidgetItem( ['Set Acoustic Pressure']) self.item_child_setVolumeVelocity = QTreeWidgetItem( ['Set Volume Velocity']) self.item_child_setSpecificImpedance = QTreeWidgetItem( ['Set Specific Impedance']) self.item_child_set_radiation_impedance = QTreeWidgetItem( ['Set Radiation Impedance']) self.item_child_add_perforated_plate = QTreeWidgetItem( ['Add Perforated Plate']) self.item_child_set_acoustic_element_length_correction = QTreeWidgetItem( ['Set Element Length Correction']) self.item_child_add_compressor_excitation = QTreeWidgetItem( ['Add Compressor Excitation']) # self.list_top_items.append(self.item_top_acousticModelSetup) self.list_child_items.append(self.item_child_setAcousticElementType) self.list_child_items.append(self.item_child_setAcousticPressure) self.list_child_items.append(self.item_child_setVolumeVelocity) self.list_child_items.append(self.item_child_setSpecificImpedance) self.list_child_items.append(self.item_child_set_radiation_impedance) self.list_child_items.append(self.item_child_add_perforated_plate) self.list_child_items.append( self.item_child_set_acoustic_element_length_correction) self.list_child_items.append(self.item_child_add_compressor_excitation) # self.item_top_analysis = QTreeWidgetItem(['Analysis']) self.item_child_selectAnalysisType = QTreeWidgetItem( ['Select Analysis Type']) self.item_child_analisysSetup = QTreeWidgetItem(['Analysis Setup']) self.item_child_runAnalysis = QTreeWidgetItem(['Run Analysis (F5)']) # self.list_top_items.append(self.item_top_analysis) self.list_child_items.append(self.item_child_selectAnalysisType) self.list_child_items.append(self.item_child_analisysSetup) self.list_child_items.append(self.item_child_runAnalysis) # self.item_top_resultsViewer_structural = QTreeWidgetItem( ['Results Viewer - Structural']) self.item_child_plotStructuralModeShapes = QTreeWidgetItem( ['Plot Structural Mode Shapes']) self.item_child_plotDisplacementField = QTreeWidgetItem( ['Plot Displacement Field']) self.item_child_plotStructuralFrequencyResponse = QTreeWidgetItem( ['Plot Structural Frequency Response']) self.item_child_plotReactionsFrequencyResponse = QTreeWidgetItem( ['Plot Reactions Frequency Response']) self.item_child_plotStressField = QTreeWidgetItem( ['Plot Stress Field']) self.item_child_plotStressFrequencyResponse = QTreeWidgetItem( ['Plot Stress Frequency Response']) # self.list_top_items.append(self.item_top_resultsViewer_structural) self.list_child_items.append(self.item_child_plotStructuralModeShapes) self.list_child_items.append(self.item_child_plotDisplacementField) self.list_child_items.append( self.item_child_plotStructuralFrequencyResponse) self.list_child_items.append( self.item_child_plotReactionsFrequencyResponse) self.list_child_items.append(self.item_child_plotStressField) self.list_child_items.append( self.item_child_plotStressFrequencyResponse) # self.item_top_resultsViewer_acoustic = QTreeWidgetItem( ['Results Viewer - Acoustic']) self.item_child_plotAcousticModeShapes = QTreeWidgetItem( ['Plot Acoustic Mode Shapes']) self.item_child_plotAcousticPressureField = QTreeWidgetItem( ['Plot Acoustic Pressure Field']) self.item_child_plotAcousticFrequencyResponse = QTreeWidgetItem( ['Plot Acoustic Frequency Response']) self.item_child_plot_TL_NR = QTreeWidgetItem( ['Plot Transmission Loss or Attenuation']) self.item_child_plot_perforated_plate_convergence_data = QTreeWidgetItem( ['Plot perforated plate convergence data']) # self.list_top_items.append(self.item_top_resultsViewer_acoustic) self.list_child_items.append(self.item_child_plotAcousticModeShapes) self.list_child_items.append(self.item_child_plotAcousticPressureField) self.list_child_items.append( self.item_child_plotAcousticFrequencyResponse) self.list_child_items.append(self.item_child_plot_TL_NR) self.list_child_items.append( self.item_child_plot_perforated_plate_convergence_data) # def _addItems(self): """Adds the Top Level Items and the Child Levels Items at the TreeWidget.""" self.addTopLevelItem(self.item_top_generalSettings) self.item_top_generalSettings.addChild( self.item_child_setProjectAttributes) self.item_top_generalSettings.addChild( self.item_child_setMeshProperties) self.item_top_generalSettings.addChild(self.item_child_setGeometryFile) self.item_top_generalSettings.addChild(self.item_child_set_material) self.item_top_generalSettings.addChild(self.item_child_set_fluid) self.item_top_generalSettings.addChild( self.item_child_set_crossSection) self.addTopLevelItem(self.item_top_structuralModelSetup) self.item_top_structuralModelSetup.addChild( self.item_child_setStructuralElementType) self.item_top_structuralModelSetup.addChild(self.item_child_addFlanges) self.item_top_structuralModelSetup.addChild( self.item_child_setBeamXaxisRotation) self.item_top_structuralModelSetup.addChild( self.item_child_setPrescribedDofs) self.item_top_structuralModelSetup.addChild( self.item_child_setRotationDecoupling) self.item_top_structuralModelSetup.addChild( self.item_child_setNodalLoads) self.item_top_structuralModelSetup.addChild( self.item_child_addMassSpringDamper) self.item_top_structuralModelSetup.addChild( self.item_child_add_elastic_nodal_links) self.item_top_structuralModelSetup.addChild( self.item_child_add_expansion_joint) self.item_top_structuralModelSetup.addChild(self.item_child_add_valve) self.item_top_structuralModelSetup.addChild( self.item_child_set_stress_stiffening) self.item_top_structuralModelSetup.addChild( self.item_child_setcappedEnd) self.addTopLevelItem(self.item_top_acousticModelSetup) self.item_top_acousticModelSetup.addChild( self.item_child_setAcousticElementType) self.item_top_acousticModelSetup.addChild( self.item_child_setAcousticPressure) self.item_top_acousticModelSetup.addChild( self.item_child_setVolumeVelocity) self.item_top_acousticModelSetup.addChild( self.item_child_setSpecificImpedance) self.item_top_acousticModelSetup.addChild( self.item_child_set_radiation_impedance) self.item_top_acousticModelSetup.addChild( self.item_child_add_perforated_plate) self.item_top_acousticModelSetup.addChild( self.item_child_set_acoustic_element_length_correction) self.item_top_acousticModelSetup.addChild( self.item_child_add_compressor_excitation) self.addTopLevelItem(self.item_top_analysis) self.item_top_analysis.addChild(self.item_child_selectAnalysisType) self.item_top_analysis.addChild(self.item_child_analisysSetup) self.item_top_analysis.addChild(self.item_child_runAnalysis) self.addTopLevelItem(self.item_top_resultsViewer_structural) self.item_top_resultsViewer_structural.addChild( self.item_child_plotStructuralModeShapes) self.item_top_resultsViewer_structural.addChild( self.item_child_plotDisplacementField) self.item_top_resultsViewer_structural.addChild( self.item_child_plotStructuralFrequencyResponse) self.item_top_resultsViewer_structural.addChild( self.item_child_plotReactionsFrequencyResponse) self.item_top_resultsViewer_structural.addChild( self.item_child_plotStressField) self.item_top_resultsViewer_structural.addChild( self.item_child_plotStressFrequencyResponse) self.addTopLevelItem(self.item_top_resultsViewer_acoustic) self.item_top_resultsViewer_acoustic.addChild( self.item_child_plotAcousticModeShapes) self.item_top_resultsViewer_acoustic.addChild( self.item_child_plotAcousticPressureField) self.item_top_resultsViewer_acoustic.addChild( self.item_child_plotAcousticFrequencyResponse) self.item_top_resultsViewer_acoustic.addChild( self.item_child_plot_TL_NR) self.item_top_resultsViewer_acoustic.addChild( self.item_child_plot_perforated_plate_convergence_data) def _configItems(self): """Configure all items.""" borderRole = Qt.UserRole + 1 borderPen = QPen(QColor(0, 0, 0)) borderPen.setWidth(1) textTopBrush = QBrush(QColor(0, 0, 0)) configTopBrush = self.brush_upper_items plotTopBrush = self.brush_lower_items configTopItems = [ self.item_top_generalSettings, self.item_top_structuralModelSetup, self.item_top_acousticModelSetup ] for top_item in self.list_top_items: top_item.setFlags(Qt.ItemIsDragEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) top_item.setFont(0, self.font_top_Items) top_item.setData(0, borderRole, borderPen) top_item.setTextAlignment(0, Qt.AlignHCenter | Qt.AlignVCenter) top_item.setForeground(0, textTopBrush) # top_item.setSizeHint(0, self.top_items_size) if top_item in configTopItems: top_item.setBackground(0, configTopBrush) self.expandItem(top_item) else: top_item.setBackground(0, plotTopBrush) delegate = BorderItemDelegate(self, borderRole) self.setItemDelegate(delegate) for child_item in self.list_child_items: child_item.setFont(0, self.font_child_Items) # child_item.setSizeHint(0, self.top_items_size) def update_plot_mesh(self): if not self.mainWindow.opv_widget.change_plot_to_mesh: self.mainWindow.plot_mesh() def update_plot_entities(self): if not (self.mainWindow.opv_widget.change_plot_to_entities or self.mainWindow.opv_widget. change_plot_to_entities_with_cross_section): self.mainWindow.plot_entities() def update_plot_entities_with_cross_section(self): if not self.mainWindow.opv_widget.change_plot_to_entities_with_cross_section: self.mainWindow.plot_entities_with_cross_section() # def create_plot_convergence_data(self): # self.item_top_resultsViewer_acoustic.addChild(self.item_child_plot_perforated_plate_convergence_data) def update_childItems_visibility(self, item): toggle = lambda x: x.setExpanded(not x.isExpanded()) if item in self.list_top_items: toggle(item) return True return False def on_click_item(self, item, column): """This event is raised every time an item is clicked on the menu.""" # self.mainWindow.getInputWidget().beforeInput() if self.update_childItems_visibility(item): return if self.project.none_project_action: self.empty_project_action_message() if item == self.item_child_setProjectAttributes: if not self.item_child_setProjectAttributes.isDisabled(): self.mainWindow.getInputWidget().set_project_attributes() elif item == self.item_child_setGeometryFile: if not self.item_child_setGeometryFile.isDisabled(): self.mainWindow.getInputWidget().set_geometry_file() elif item == self.item_child_setMeshProperties: if not self.item_child_setMeshProperties.isDisabled(): if self.mainWindow.getInputWidget().set_mesh_properties(): self._updateItems() elif item == self.item_child_set_material: if not self.item_child_set_material.isDisabled(): self.update_plot_entities() self.mainWindow.getInputWidget().set_material() self.mainWindow.plot_entities() elif item == self.item_child_set_fluid: if not self.item_child_set_fluid.isDisabled(): self.update_plot_entities() self.mainWindow.getInputWidget().set_fluid() self.mainWindow.plot_entities() elif item == self.item_child_set_crossSection: if not self.item_child_set_crossSection.isDisabled(): if self.mainWindow.getInputWidget().set_cross_section(): self.mainWindow.plot_entities_with_cross_section() elif item == self.item_child_addFlanges: if not self.item_child_addFlanges.isDisabled(): self.mainWindow.getInputWidget().add_flanges() elif item == self.item_child_setStructuralElementType: if not self.item_child_setStructuralElementType.isDisabled(): self.update_plot_entities() self.mainWindow.getInputWidget().setStructuralElementType() elif item == self.item_child_setBeamXaxisRotation: if not self.item_child_setBeamXaxisRotation.isDisabled(): self.update_plot_entities_with_cross_section() self.mainWindow.getInputWidget().set_beam_xaxis_rotation() elif item == self.item_child_setPrescribedDofs: if not self.item_child_setPrescribedDofs.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().setDOF() self.mainWindow.plot_mesh() elif item == self.item_child_setRotationDecoupling: if not self.item_child_setRotationDecoupling.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().setRotationDecoupling() self.mainWindow.plot_mesh() elif item == self.item_child_setNodalLoads: if not self.item_child_setNodalLoads.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().setNodalLoads() self.mainWindow.plot_mesh() elif item == self.item_child_addMassSpringDamper: if not self.item_child_addMassSpringDamper.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().addMassSpringDamper() self.mainWindow.plot_mesh() elif item == self.item_child_add_elastic_nodal_links: if not self.item_child_add_elastic_nodal_links.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().add_elastic_nodal_links() self.mainWindow.plot_mesh() elif item == self.item_child_add_expansion_joint: if not self.item_child_add_expansion_joint.isDisabled(): self.mainWindow.getInputWidget().add_expansion_joint() # self.mainWindow.plot_entities_with_cross_section() elif item == self.item_child_add_valve: if not self.item_child_add_valve.isDisabled(): read = self.mainWindow.getInputWidget().add_valve() if read.complete: self.mainWindow.plot_mesh() # self.mainWindow.plot_entities_with_cross_section() elif item == self.item_child_setcappedEnd: if not self.item_child_setcappedEnd.isDisabled(): self.mainWindow.getInputWidget().setcappedEnd() # self.mainWindow.plot_entities() elif item == self.item_child_set_stress_stiffening: if not self.item_child_set_stress_stiffening.isDisabled(): self.mainWindow.getInputWidget().set_stress_stress_stiffening() # self.mainWindow.plot_entities() elif item == self.item_child_setAcousticElementType: if not self.item_child_setAcousticElementType.isDisabled(): self.update_plot_entities() self.mainWindow.getInputWidget().set_acoustic_element_type() self.mainWindow.plot_entities() elif item == self.item_child_setAcousticPressure: if not self.item_child_setAcousticPressure.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().setAcousticPressure() self.mainWindow.plot_mesh() elif item == self.item_child_setVolumeVelocity: if not self.item_child_setVolumeVelocity.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().setVolumeVelocity() self.mainWindow.plot_mesh() elif item == self.item_child_setSpecificImpedance: if not self.item_child_setSpecificImpedance.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().setSpecificImpedance() self.mainWindow.plot_mesh() elif item == self.item_child_set_radiation_impedance: if not self.item_child_set_radiation_impedance.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().set_radiation_impedance() self.mainWindow.plot_mesh() elif item == self.item_child_add_perforated_plate: if not self.item_child_add_perforated_plate.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().add_perforated_plate() self.mainWindow.plot_mesh() elif item == self.item_child_set_acoustic_element_length_correction: if not self.item_child_set_acoustic_element_length_correction.isDisabled( ): self.update_plot_mesh() self.mainWindow.getInputWidget( ).set_acoustic_element_length_correction() self.mainWindow.plot_mesh() elif item == self.item_child_add_compressor_excitation: if not self.item_child_add_compressor_excitation.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().add_compressor_excitation() self.mainWindow.plot_mesh() elif item == self.item_child_selectAnalysisType: if not self.item_child_selectAnalysisType.isDisabled(): self.mainWindow.getInputWidget().analysisTypeInput() self._updateItems() elif item == self.item_child_analisysSetup: if not self.item_child_analisysSetup.isDisabled(): self.mainWindow.getInputWidget().analysisSetup() self._updateItems() elif item == self.item_child_runAnalysis: if not self.item_child_runAnalysis.isDisabled(): self.mainWindow.getInputWidget().runAnalysis() self._updateItems() elif item == self.item_child_plotStructuralModeShapes: if not self.item_child_plotStructuralModeShapes.isDisabled(): self.mainWindow.getInputWidget().plotStructuralModeShapes() elif item == self.item_child_plotDisplacementField: if not self.item_child_plotDisplacementField.isDisabled(): self.mainWindow.getInputWidget().plotDisplacementField() elif item == self.item_child_plotStructuralFrequencyResponse: if not self.item_child_plotStructuralFrequencyResponse.isDisabled( ): self.update_plot_mesh() self.mainWindow.getInputWidget( ).plotStructuralFrequencyResponse() elif item == self.item_child_plotReactionsFrequencyResponse: if not self.item_child_plotReactionsFrequencyResponse.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget( ).plotReactionsFrequencyResponse() elif item == self.item_child_plotStressField: if not self.item_child_plotStressField.isDisabled(): self.mainWindow.getInputWidget().plotStressField() elif item == self.item_child_plotStressFrequencyResponse: if not self.item_child_plotStressFrequencyResponse.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().plotStressFrequencyResponse() elif item == self.item_child_plotAcousticModeShapes: if not self.item_child_plotAcousticModeShapes.isDisabled(): self.mainWindow.getInputWidget().plotAcousticModeShapes() elif item == self.item_child_plotAcousticPressureField: if not self.item_child_plotAcousticPressureField.isDisabled(): self.mainWindow.getInputWidget().plotAcousticPressureField() elif item == self.item_child_plotAcousticFrequencyResponse: if not self.item_child_plotAcousticFrequencyResponse.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().plotAcousticFrequencyResponse( ) elif item == self.item_child_plot_TL_NR: if not self.item_child_plot_TL_NR.isDisabled(): self.update_plot_mesh() self.mainWindow.getInputWidget().plot_TL_NR() elif item == self.item_child_plot_perforated_plate_convergence_data: if not self.item_child_plot_perforated_plate_convergence_data.isDisabled( ): self.mainWindow.getInputWidget( ).plotPerforatedPlateConvergenceDataLog() def modify_model_setup_items_access(self, bool_key): # self.item_child_setProjectAttributes.setDisabled(bool_key) self.item_child_setGeometryFile.setDisabled(bool_key) self.item_child_setMeshProperties.setDisabled(bool_key) self.item_child_set_material.setDisabled(bool_key) self.item_child_set_fluid.setDisabled(bool_key) self.item_child_set_crossSection.setDisabled(bool_key) # self.item_child_setStructuralElementType.setDisabled(bool_key) self.item_child_addFlanges.setDisabled(bool_key) self.item_child_setBeamXaxisRotation.setDisabled(bool_key) self.item_child_setPrescribedDofs.setDisabled(bool_key) self.item_child_setRotationDecoupling.setDisabled(bool_key) self.item_child_setNodalLoads.setDisabled(bool_key) self.item_child_addMassSpringDamper.setDisabled(bool_key) self.item_child_setcappedEnd.setDisabled(bool_key) self.item_child_set_stress_stiffening.setDisabled(bool_key) self.item_child_add_elastic_nodal_links.setDisabled(bool_key) self.item_child_add_expansion_joint.setDisabled(bool_key) self.item_child_add_valve.setDisabled(bool_key) # self.item_child_setAcousticElementType.setDisabled(bool_key) self.item_child_setAcousticPressure.setDisabled(bool_key) self.item_child_setVolumeVelocity.setDisabled(bool_key) self.item_child_setSpecificImpedance.setDisabled(bool_key) self.item_child_set_radiation_impedance.setDisabled(bool_key) self.item_child_add_perforated_plate.setDisabled(bool_key) self.item_child_set_acoustic_element_length_correction.setDisabled( bool_key) self.item_child_add_compressor_excitation.setDisabled(bool_key) # self.item_child_selectAnalysisType.setDisabled(bool_key) def _updateItems(self): """Enables and disables the Child Items on the menu after the solution is done.""" if True: self.item_child_plotStructuralModeShapes.setDisabled(True) self.item_child_plotDisplacementField.setDisabled(True) self.item_child_plotStructuralFrequencyResponse.setDisabled(True) self.item_child_plotStressField.setDisabled(True) self.item_child_plotStressFrequencyResponse.setDisabled(True) self.item_child_plotAcousticModeShapes.setDisabled(True) self.item_child_plotAcousticFrequencyResponse.setDisabled(True) self.item_child_plotAcousticPressureField.setDisabled(True) self.item_child_plot_TL_NR.setDisabled(True) self.item_child_plot_perforated_plate_convergence_data.setDisabled( True) self.item_child_plotReactionsFrequencyResponse.setDisabled(True) self.item_child_analisysSetup.setDisabled(True) self.item_child_runAnalysis.setDisabled(True) if self.project.analysis_ID in [None, 2, 4]: self.item_child_analisysSetup.setDisabled(True) else: self.item_child_analisysSetup.setDisabled(False) if self.project.analysis_ID is not None and self.project.setup_analysis_complete: self.item_child_runAnalysis.setDisabled(False) if self.project.get_structural_solution( ) is not None or self.project.get_acoustic_solution() is not None: if self.project.analysis_ID == 0 or self.project.analysis_ID == 1: self.item_child_plotStructuralFrequencyResponse.setDisabled( False) self.item_child_plotDisplacementField.setDisabled(False) self.item_child_plotReactionsFrequencyResponse.setDisabled( False) self.item_child_plotStressField.setDisabled(False) self.item_child_plotStressFrequencyResponse.setDisabled(False) elif self.project.analysis_ID == 2: self.item_child_plotStructuralModeShapes.setDisabled(False) if self.project.get_acoustic_solution() is not None: self.item_child_plotAcousticModeShapes.setDisabled(False) elif self.project.analysis_ID == 4: self.item_child_plotAcousticModeShapes.setDisabled(False) if self.project.get_structural_solution() is not None: self.item_child_plotStructuralModeShapes.setDisabled(False) elif self.project.analysis_ID == 3: if self.project.perforated_plate_dataLog: self.item_child_plot_perforated_plate_convergence_data.setDisabled( False) self.item_child_plotAcousticFrequencyResponse.setDisabled( False) self.item_child_plotAcousticPressureField.setDisabled(False) self.item_child_plot_TL_NR.setDisabled(False) elif self.project.analysis_ID in [5, 6]: if self.project.perforated_plate_dataLog: self.item_child_plot_perforated_plate_convergence_data.setDisabled( False) self.item_child_plotStructuralFrequencyResponse.setDisabled( False) self.item_child_plotAcousticFrequencyResponse.setDisabled( False) self.item_child_plotStressField.setDisabled(False) self.item_child_plotStressFrequencyResponse.setDisabled(False) self.item_child_plotDisplacementField.setDisabled(False) self.item_child_plotAcousticPressureField.setDisabled(False) self.item_child_plot_TL_NR.setDisabled(False) self.item_child_plotReactionsFrequencyResponse.setDisabled( False) self.update_TreeVisibility_after_solution() def update_TreeVisibility_after_solution(self): """Expands and collapses the Top Level Items ont the menu after the solution is done.""" self.collapseItem(self.item_top_generalSettings) if self.project.analysis_ID in [0, 1, 2]: self.expandItem(self.item_top_resultsViewer_structural) self.expandItem(self.item_top_structuralModelSetup) self.collapseItem(self.item_top_resultsViewer_acoustic) self.collapseItem(self.item_top_acousticModelSetup) elif self.project.analysis_ID in [3, 4]: self.expandItem(self.item_top_resultsViewer_acoustic) self.expandItem(self.item_top_acousticModelSetup) self.collapseItem(self.item_top_resultsViewer_structural) self.collapseItem(self.item_top_structuralModelSetup) elif self.project.analysis_ID in [5, 6]: self.expandItem(self.item_top_resultsViewer_structural) self.expandItem(self.item_top_resultsViewer_acoustic) self.expandItem(self.item_top_structuralModelSetup) self.expandItem(self.item_top_acousticModelSetup) def empty_project_action_message(self): title = 'EMPTY PROJECT' message = 'Please, you should create a new project or load an already existing one before start to set up the model.' message += "\n\nIt is recommended to use the 'New Project' or the 'Import Project' \nbuttons to continue." window_title = 'ERROR' PrintMessageInput([title, message, window_title], opv=self.mainWindow.getOPVWidget())
class MainDialog(QDialog, Ui_MainDialog): """The main dialog of QGIS2Web plugin.""" items = {} def __init__(self, iface): QDialog.__init__(self) self.setupUi(self) self.iface = iface self.previewUrl = None self.layer_search_combo = None self.exporter_combo = None self.feedback = FeedbackDialog(self) self.feedback.setModal(True) stgs = QSettings() self.restoreGeometry( stgs.value("qgis2web/MainDialogGeometry", QByteArray(), type=QByteArray)) if stgs.value("qgis2web/previewOnStartup", Qt.Checked) == Qt.Checked: self.previewOnStartup.setCheckState(Qt.Checked) else: self.previewOnStartup.setCheckState(Qt.Unchecked) if (stgs.value("qgis2web/closeFeedbackOnSuccess", Qt.Checked) == Qt.Checked): self.closeFeedbackOnSuccess.setCheckState(Qt.Checked) else: self.closeFeedbackOnSuccess.setCheckState(Qt.Unchecked) self.previewFeatureLimit.setText( stgs.value("qgis2web/previewFeatureLimit", "1000")) self.paramsTreeOL.setSelectionMode(QAbstractItemView.SingleSelection) self.preview = None if webkit_available: widget = QWebView() self.preview = widget try: # if os.environ["TRAVIS"]: self.preview.setPage(WebPage()) except: print("Failed to set custom webpage") webview = self.preview.page() webview.setNetworkAccessManager(QgsNetworkAccessManager.instance()) self.preview.settings().setAttribute( QWebSettings.DeveloperExtrasEnabled, True) else: widget = QTextBrowser() widget.setText( self.tr('Preview is not available since QtWebKit ' 'dependency is missing on your system')) self.right_layout.insertWidget(0, widget) self.populateConfigParams(self) self.populate_layers_and_groups(self) self.populateLayerSearch() self.populateBasemaps() writer = WRITER_REGISTRY.createWriterFromProject() self.setStateToWriter(writer) self.exporter = EXPORTER_REGISTRY.createFromProject() self.exporter_combo.setCurrentIndex( self.exporter_combo.findText(self.exporter.name())) self.exporter_combo.currentIndexChanged.connect( self.exporterTypeChanged) self.toggleOptions() if webkit_available: if self.previewOnStartup.checkState() == Qt.Checked: self.autoUpdatePreview() self.buttonPreview.clicked.connect(self.previewMap) else: self.buttonPreview.setDisabled(True) self.layersTree.model().dataChanged.connect(self.populateLayerSearch) self.ol3.clicked.connect(self.changeFormat) self.leaflet.clicked.connect(self.changeFormat) self.buttonExport.clicked.connect(self.saveMap) readme = os.path.join(os.path.dirname(os.path.realpath(__file__)), "README.md") helpText = os.path.join(os.path.dirname(os.path.realpath(__file__)), "helpFile.md") lines = open(readme, 'r').readlines() with open(helpText, 'w') as helpFile: for ct, line in enumerate(lines): if ct > 4: helpFile.write(line) helpFile.close() self.helpField.setSource(QUrl.fromLocalFile(helpText)) if webkit_available: self.devConsole = QWebInspector(self.verticalLayoutWidget_2) self.devConsole.setFixedHeight(0) self.devConsole.setObjectName("devConsole") self.devConsole.setPage(self.preview.page()) self.right_layout.insertWidget(1, self.devConsole) self.filter = devToggleFilter() self.installEventFilter(self.filter) self.setModal(False) def changeFormat(self): self.autoUpdatePreview() self.toggleOptions() def exporterTypeChanged(self): new_exporter_name = self.exporter_combo.currentText() try: self.exporter = [ e for e in EXPORTER_REGISTRY.getExporters() if e.name() == new_exporter_name ][0]() except: pass def currentMapFormat(self): """ Returns the currently selected map writer type """ return self.getWriterFactory().type() def getWriterFactory(self): """ Returns a factory to create the currently selected map writer """ if self.mapFormat.checkedButton() == self.ol3: return OpenLayersWriter elif self.mapFormat.checkedButton() == self.leaflet: return LeafletWriter def createWriter(self): """ Creates a writer object reflecting the current settings in the dialog """ writer = self.getWriterFactory()() (writer.layers, writer.groups, writer.popup, writer.visible, writer.json, writer.cluster, writer.getFeatureInfo) = self.getLayersAndGroups() writer.params = self.getParameters() return writer def showErrorMessage(self, error): """ Shows an error message in the preview window """ html = "<html>" html += "<head></head>" html += "<style>body {font-family: sans-serif;}</style>" html += "<body><h1>Error</h1>" html += "<p>qgis2web produced an error:</p><code>" html += error html += "</code></body></html>" if self.preview: self.preview.setHtml(html) def showFeedbackMessage(self, title, message): """ Shows a feedback message in the preview window """ html = "<html>" html += "<head></head>" html += "<style>body {font-family: sans-serif;}</style>" html += "<body><h1>{}</h1>".format(title) html += "<p>{}</p>".format(message) html += "</body></html>" if self.preview: self.preview.setHtml(html) def toggleOptions(self): currentWriter = self.getWriterFactory() for param, value in specificParams.iteritems(): treeParam = self.paramsTreeOL.findItems( param, (Qt.MatchExactly | Qt.MatchRecursive))[0] if currentWriter == OpenLayersWriter: if value == "OL3": treeParam.setDisabled(False) else: treeParam.setDisabled(True) else: if value == "OL3": treeParam.setDisabled(True) else: treeParam.setDisabled(False) for option, value in specificOptions.iteritems(): treeOptions = self.layersTree.findItems( option, (Qt.MatchExactly | Qt.MatchRecursive)) for treeOption in treeOptions: if currentWriter == OpenLayersWriter: if value == "OL3": treeOption.setDisabled(False) else: treeOption.setDisabled(True) else: if value == "OL3": treeOption.setDisabled(True) else: treeOption.setDisabled(False) def createPreview(self): writer = self.createWriter() return writer.write(self.iface, dest_folder=utils.tempFolder()).index_file def shouldAutoPreview(self): """ Returns a tuple, with a bool for whether the preview should automatically be generated, and a string for explanations as to why the preview cannot be automatically generated """ writer = self.createWriter() total_features = 0 for layer in writer.layers: if isinstance(layer, QgsVectorLayer): total_features += layer.featureCount() if total_features > int(self.previewFeatureLimit.text()): # Too many features => too slow! return (False, self.tr('<p>A large number of features are ' 'present in the map. Generating the ' 'preview may take some time.</p>' '<p>Click Update Preview to generate the ' 'preview anyway.</p>')) return (True, None) def autoUpdatePreview(self): """ Triggered when a preview will be automatically generated, i.e. not as a result of the user manually clicking the Update Preview button. """ (auto_preview, message) = self.shouldAutoPreview() if not auto_preview: self.showFeedbackMessage(self.tr('Preview Map'), message) else: self.previewMap() def previewMap(self): try: preview_file = self.createPreview() self.loadPreviewFile(preview_file) except Exception as e: self.showErrorMessage(traceback.format_exc().replace( "\n", "<br />")) QgsMessageLog.logMessage(traceback.format_exc(), "qgis2web", level=QgsMessageLog.CRITICAL) def saveMap(self): writer = self.createWriter() write_folder = self.exporter.exportDirectory() if not write_folder: return self.feedback.reset() self.feedback.show() results = writer.write(self.iface, dest_folder=write_folder, feedback=self.feedback) self.feedback.showFeedback('Success') if self.closeFeedbackOnSuccess.checkState() == Qt.Checked: self.feedback.close() result = self.exporter.postProcess(results, feedback=self.feedback) if result and (not os.environ.get('CI') and not os.environ.get('TRAVIS')): webbrowser.open_new_tab(self.exporter.destinationUrl()) def populate_layers_and_groups(self, dlg): """Populate layers on QGIS into our layers and group tree view.""" root_node = QgsProject.instance().layerTreeRoot() tree_groups = [] tree_layers = root_node.findLayers() self.layers_item = QTreeWidgetItem() self.layers_item.setText(0, "Layers and Groups") self.layersTree.setColumnCount(3) for tree_layer in tree_layers: layer = tree_layer.layer() if (layer.type() != QgsMapLayer.PluginLayer and layer.customProperty("ol_layer_type") is None): try: if layer.type() == QgsMapLayer.VectorLayer: testDump = layer.rendererV2().dump() layer_parent = tree_layer.parent() if layer_parent.parent() is None: item = TreeLayerItem(self.iface, layer, self.layersTree, dlg) self.layers_item.addChild(item) else: if layer_parent not in tree_groups: tree_groups.append(layer_parent) except: QgsMessageLog.logMessage(traceback.format_exc(), "qgis2web", level=QgsMessageLog.CRITICAL) for tree_group in tree_groups: group_name = tree_group.name() group_layers = [ tree_layer.layer() for tree_layer in tree_group.findLayers() ] item = TreeGroupItem(group_name, group_layers, self.layersTree) self.layers_item.addChild(item) self.layersTree.addTopLevelItem(self.layers_item) self.layersTree.expandAll() self.layersTree.resizeColumnToContents(0) self.layersTree.resizeColumnToContents(1) for i in xrange(self.layers_item.childCount()): item = self.layers_item.child(i) if item.checkState(0) != Qt.Checked: item.setExpanded(False) def populateLayerSearch(self): self.layer_search_combo.clear() self.layer_search_combo.addItem("None") (layers, groups, popup, visible, json, cluster, getFeatureInfo) = self.getLayersAndGroups() for count, layer in enumerate(layers): if layer.type() == layer.VectorLayer: options = [] fields = layer.pendingFields() for f in fields: fieldIndex = fields.indexFromName(unicode(f.name())) formCnf = layer.editFormConfig() editorWidget = formCnf.widgetType(fieldIndex) if editorWidget == QgsVectorLayer.Hidden \ or editorWidget == 'Hidden': continue options.append(unicode(f.name())) for option in options: displayStr = unicode(layer.name() + ": " + option) self.layer_search_combo.insertItem(0, displayStr) sln = utils.safeName(layer.name()) self.layer_search_combo.setItemData( self.layer_search_combo.findText(displayStr), sln + "_" + unicode(count)) def configureExporter(self): self.exporter.configure() def populateConfigParams(self, dlg): """ Populates the dialog with option items and widgets """ self.items = defaultdict(dict) tree = dlg.paramsTreeOL configure_export_action = QAction('...', self) configure_export_action.triggered.connect(self.configureExporter) params = getParams(configure_exporter_action=configure_export_action) for group, settings in params.iteritems(): item = QTreeWidgetItem() item.setText(0, group) for param, value in settings.iteritems(): subitem = self.createOptionItem(tree_widget=tree, parent_item=item, parameter=param, default_value=value) item.addChild(subitem) self.items[group][param] = subitem self.paramsTreeOL.addTopLevelItem(item) item.sortChildren(0, Qt.AscendingOrder) self.paramsTreeOL.expandAll() self.paramsTreeOL.resizeColumnToContents(0) self.paramsTreeOL.resizeColumnToContents(1) self.layer_search_combo.removeItem(1) def createOptionItem(self, tree_widget, parent_item, parameter, default_value): """create the tree item corresponding to an option parameter""" action = None if isinstance(default_value, dict): action = default_value['action'] default_value = default_value['option'] subitem = TreeSettingItem(parent_item, tree_widget, parameter, default_value, action) if parameter == 'Layer search': self.layer_search_combo = subitem.combo elif parameter == 'Exporter': self.exporter_combo = subitem.combo return subitem def setStateToWriter(self, writer): """ Sets the dialog state to match the specified writer """ self.selectMapFormat(writer) self.setStateToParams(writer.params) self.setStateForBasemaps(writer.params["Appearance"]["Base layer"]) def setStateToParams(self, params): """ Sets the dialog state to match the specified parameters """ for group, settings in self.items.iteritems(): for param, item in settings.iteritems(): value = params[group][param] item.setValue(value) def setStateForBasemaps(self, basemaps): """ Sets the dialog state to match the specified basemaps """ for i in range(self.basemaps.count()): self.basemaps.item(i).setSelected(False) for basemap in basemaps: try: self.basemaps.findItems(basemap, (Qt.MatchExactly))[0].setSelected(True) except: pass def populateBasemaps(self): """ Adds entries for all known basemaps to the dialog """ multiSelect = QAbstractItemView.ExtendedSelection self.basemaps.setSelectionMode(multiSelect) attrFields = [] for i in range(len(baselayers)): for key in baselayers[i]: attrFields.append(key) self.basemaps.addItems(attrFields) def selectMapFormat(self, writer): """ Updates dialog state to match the specified writer format """ self.ol3.setChecked(isinstance(writer, OpenLayersWriter)) self.leaflet.setChecked(isinstance(writer, LeafletWriter)) def loadPreviewFile(self, file): """ Loads a web based preview from a local file path """ self.previewUrl = QUrl.fromLocalFile(file) if self.preview: self.preview.settings().clearMemoryCaches() self.preview.setUrl(self.previewUrl) def getParameters(self): parameters = defaultdict(dict) for group, settings in self.items.iteritems(): for param, item in settings.iteritems(): parameters[group][param] = item.value() if param == "Layer search": parameters["Appearance"]["Search layer"] = ( self.layer_search_combo.itemData( self.layer_search_combo.currentIndex())) basemaps = [i.text() for i in self.basemaps.selectedItems()] parameters["Appearance"]["Base layer"] = basemaps return parameters def saveParameters(self): """ Saves current dialog state to project """ WRITER_REGISTRY.saveWriterToProject(self.createWriter()) EXPORTER_REGISTRY.writeToProject(self.exporter) def getLayersAndGroups(self): layers = [] groups = {} popup = [] visible = [] json = [] cluster = [] getFeatureInfo = [] for i in xrange(self.layers_item.childCount()): item = self.layers_item.child(i) if isinstance(item, TreeLayerItem): if item.checkState(0) == Qt.Checked: layers.append(item.layer) popup.append(item.popup) visible.append(item.visible) json.append(item.json) cluster.append(item.cluster) getFeatureInfo.append(item.getFeatureInfo) else: group = item.name groupLayers = [] if item.checkState(0) != Qt.Checked: continue for layer in item.layers: groupLayers.append(layer) layers.append(layer) popup.append({}) if item.visible: visible.append(True) else: visible.append(False) if hasattr(item, "json") and item.json: json.append(True) else: json.append(False) if hasattr(item, "cluster") and item.cluster: cluster.append(True) else: cluster.append(False) if hasattr(item, "getFeatureInfo") and item.getFeatureInfo: getFeatureInfo.append(True) else: getFeatureInfo.append(False) groups[group] = groupLayers[::-1] return (layers[::-1], groups, popup[::-1], visible[::-1], json[::-1], cluster[::-1], getFeatureInfo[::-1]) def closeEvent(self, event): self.saveParameters() (layers, groups, popup, visible, json, cluster, getFeatureInfo) = self.getLayersAndGroups() for layer, pop, vis in zip(layers, popup, visible): attrDict = {} for attr in pop: attrDict['attr'] = pop[attr] layer.setCustomProperty("qgis2web/popup/" + attr, pop[attr]) layer.setCustomProperty("qgis2web/Visible", vis) QSettings().setValue("qgis2web/MainDialogGeometry", self.saveGeometry()) QSettings().setValue("qgis2web/previewOnStartup", self.previewOnStartup.checkState()) QSettings().setValue("qgis2web/closeFeedbackOnSuccess", self.closeFeedbackOnSuccess.checkState()) QSettings().setValue("qgis2web/previewFeatureLimit", self.previewFeatureLimit.text()) event.accept()
class SidebarWidget(QTreeWidget): TEXT_COLUMN = 4 def __init__(self, main_win, *args, **kwargs): self.main_window = main_win super().__init__(*args, **kwargs) # Get rid of the ugly focus rectangle and border self.setAttribute(Qt.WA_MacShowFocusRect, False) self.setStyleSheet('outline: 0; border: 0;') self.doc = None self.marker_items = {} self.setColumnCount(5) self.setHeaderHidden(True) # top level items self.recording_item = QTreeWidgetItem(('Recording', ), QTreeWidgetItem.Type) self.smp_item = QTreeWidgetItem(('SnowMicroPen', ), QTreeWidgetItem.Type) self.markers_item = QTreeWidgetItem(('Markers', ), QTreeWidgetItem.Type) self.drift_item = QTreeWidgetItem(('Drift, Offset, Noise', ), QTreeWidgetItem.Type) self.addTopLevelItem(self.recording_item) self.addTopLevelItem(self.smp_item) self.addTopLevelItem(self.markers_item) self.addTopLevelItem(self.drift_item) self.setFirstItemColumnSpanned(self.recording_item, True) self.setFirstItemColumnSpanned(self.smp_item, True) self.setFirstItemColumnSpanned(self.markers_item, True) self.setFirstItemColumnSpanned(self.drift_item, True) # recording items self.name_item = QTreeWidgetItem((None, None, 'Name', None, '')) self.timestamp_item = QTreeWidgetItem( (None, None, 'Timestamp', None, '')) self.rec_length_item = QTreeWidgetItem( (None, None, 'Length', None, '')) self.pnt_filename_item = QTreeWidgetItem( (None, None, 'Pnt File', None, '')) self.coordinates_item = QTreeWidgetItem( (None, None, 'Coordinates', None, '')) self.spatial_res_item = QTreeWidgetItem( (None, None, 'Spatial Resolution', None, '')) self.overload_item = QTreeWidgetItem( (None, None, 'Overload Force', None, '')) self.speed_item = QTreeWidgetItem((None, None, 'Speed', None, '')) self.recording_item.addChild(self.name_item) self.recording_item.addChild(self.pnt_filename_item) self.recording_item.addChild(self.timestamp_item) self.recording_item.addChild(self.coordinates_item) self.recording_item.addChild(self.rec_length_item) self.recording_item.addChild(self.spatial_res_item) self.recording_item.addChild(self.overload_item) self.recording_item.addChild(self.speed_item) # smp items self.smp_serial_item = QTreeWidgetItem( (None, None, 'Serial Number', None, '')) self.smp_firmware_item = QTreeWidgetItem( (None, None, 'Firmware Version', None, '')) self.smp_length_item = QTreeWidgetItem( (None, None, 'Max. Recording Length', None, '')) self.smp_tipdiameter_item = QTreeWidgetItem( (None, None, 'Tip Diameter', None, '')) self.smp_sensor_sensitivity_item = QTreeWidgetItem( (None, None, 'Sensor Sensitivity', None, '')) self.smp_sensor_serial_item = QTreeWidgetItem( (None, None, 'Sensor Serial Number', None, '')) self.smp_amp_item = QTreeWidgetItem( (None, None, 'Amplifier Serial Number', None, '')) self.smp_item.addChild(self.smp_serial_item) self.smp_item.addChild(self.smp_firmware_item) self.smp_item.addChild(self.smp_length_item) self.smp_item.addChild(self.smp_tipdiameter_item) self.smp_item.addChild(self.smp_sensor_sensitivity_item) self.smp_item.addChild(self.smp_sensor_serial_item) self.smp_item.addChild(self.smp_amp_item) # drift items self.drift_begin_item = QTreeWidgetItem( (None, None, 'Begin', None, '')) self.drift_end_item = QTreeWidgetItem((None, None, 'End', None, '')) self.drift_value_item = QTreeWidgetItem( (None, None, 'Drift', None, '')) self.offset_value_item = QTreeWidgetItem( (None, None, 'Offset', None, '')) self.noise_value_item = QTreeWidgetItem( (None, None, 'Noise', None, '')) self.drift_item.addChild(self.drift_begin_item) self.drift_item.addChild(self.drift_end_item) self.drift_item.addChild(self.drift_value_item) self.drift_item.addChild(self.offset_value_item) self.drift_item.addChild(self.noise_value_item) # Tight up the columns self.expandAll() self.setColumnWidth(0, 0) self.resizeColumnToContents(1) self.resizeColumnToContents(2) self.resizeColumnToContents(3) def set_document(self, doc): if doc is None: return p = doc.profile self.name_item.setText(self.TEXT_COLUMN, p.name) self.pnt_filename_item.setText(self.TEXT_COLUMN, str(p.pnt_file)) self.timestamp_item.setText(self.TEXT_COLUMN, str(p.timestamp)) self.rec_length_item.setText( self.TEXT_COLUMN, '{:.0f} mm ({:n} Samples)'.format(p.recording_length, len(p))) if p.coordinates: lat, long = ['{:.6f}'.format(c) for c in p.coordinates] url = '<a href="https://www.google.com/maps/search/?api=1&query={lat},{long}">{lat}, {long}</a>'.format( lat=lat, long=long) else: url = 'None' url_label = QLabel(url) url_label.setContentsMargins(5, 0, 0, 0) url_label.setOpenExternalLinks(True) self.setItemWidget(self.coordinates_item, 4, url_label) spatial_res = '{:.3f} µm'.format(p.spatial_resolution * 1000) self.spatial_res_item.setText(self.TEXT_COLUMN, spatial_res) overload = '{:.1f} N'.format(p.overload) self.overload_item.setText(self.TEXT_COLUMN, overload) speed = '{:.1f} mm/s'.format(p.speed) self.speed_item.setText(self.TEXT_COLUMN, speed) self.smp_serial_item.setText(self.TEXT_COLUMN, p.smp_serial) self.smp_firmware_item.setText(self.TEXT_COLUMN, p.smp_firmware) length = '{} mm'.format(p.smp_length) self.smp_length_item.setText(self.TEXT_COLUMN, length) tipdiameter = '{:.1f} mm'.format(p.smp_tipdiameter / 1000) self.smp_tipdiameter_item.setText(self.TEXT_COLUMN, tipdiameter) self.smp_sensor_serial_item.setText(self.TEXT_COLUMN, p.sensor_serial) self.smp_sensor_sensitivity_item.setText( self.TEXT_COLUMN, '{} pC/N'.format(p.sensor_sensitivity)) self.smp_amp_item.setText(self.TEXT_COLUMN, p.amplifier_serial) # Drop all existing markers for label, item in self.marker_items.items(): self.markers_item.removeChild(item) self.marker_items = {} for label, value in p.markers.items(): self.set_marker(label, value) def set_marker(self, label, value): if value is None: if label in self.marker_items: item = self.marker_items[label] self.markers_item.removeChild(item) del self.marker_items[label] return value = '{:.3f}'.format(value) if label not in self.marker_items: item = MarkerTreeItem(self.markers_item, label) # This is a bit tricky: We call the methods on main_window which # call this method again... def set_marker(): self.main_window.set_marker(label, item.lineedit.text()) item.lineedit.editingFinished.connect(set_marker) def delete_marker(checked): self.main_window.set_marker(label, None) item.delete_button.clicked.connect(delete_marker) self.marker_items[label] = item self.markers_item.addChild(item) item = self.marker_items[label] item.lineedit.setText(value) def set_drift(self, begin_label, end_label, drift, offset, noise): self.drift_begin_item.setText(self.TEXT_COLUMN, begin_label) self.drift_end_item.setText(self.TEXT_COLUMN, end_label) self.drift_value_item.setText( self.TEXT_COLUMN, '{:.2g} mN/m'.format(drift * 1000 * 1000)) self.offset_value_item.setText(self.TEXT_COLUMN, '{:.2f} mN'.format(offset * 1000)) self.noise_value_item.setText(self.TEXT_COLUMN, '{:.2f} mN'.format(noise * 1000))
class TreeLayerItem(QTreeWidgetItem): layerIcon = QIcon( os.path.join(os.path.dirname(__file__), "icons", "layer.png")) def __init__(self, iface, layer, tree, dlg): QTreeWidgetItem.__init__(self) self.iface = iface self.layer = layer self.setText(0, layer.name()) self.setIcon(0, self.layerIcon) project = QgsProject.instance() if project.layerTreeRoot().findLayer(layer.id()).isVisible(): self.setCheckState(0, Qt.Checked) else: self.setCheckState(0, Qt.Unchecked) self.visibleItem = QTreeWidgetItem(self) self.visibleCheck = QCheckBox() vis = layer.customProperty("qgis2web/Visible", True) if (vis == 0 or unicode(vis).lower() == "false"): self.visibleCheck.setChecked(False) else: self.visibleCheck.setChecked(True) self.visibleItem.setText(0, "Visible") self.addChild(self.visibleItem) tree.setItemWidget(self.visibleItem, 1, self.visibleCheck) if layer.type() == layer.VectorLayer: if layer.providerType() == 'WFS': self.jsonItem = QTreeWidgetItem(self) self.jsonCheck = QCheckBox() if layer.customProperty("qgis2web/Encode to JSON") == 2: self.jsonCheck.setChecked(True) self.jsonItem.setText(0, "Encode to JSON") self.jsonCheck.stateChanged.connect(self.changeJSON) self.addChild(self.jsonItem) tree.setItemWidget(self.jsonItem, 1, self.jsonCheck) if layer.geometryType() == QGis.Point: self.clusterItem = QTreeWidgetItem(self) self.clusterCheck = QCheckBox() if layer.customProperty("qgis2web/Cluster") == 2: self.clusterCheck.setChecked(True) self.clusterItem.setText(0, "Cluster") self.clusterCheck.stateChanged.connect(self.changeCluster) self.addChild(self.clusterItem) tree.setItemWidget(self.clusterItem, 1, self.clusterCheck) self.popupItem = QTreeWidgetItem(self) self.popupItem.setText(0, "Popup fields") options = [] fields = self.layer.pendingFields() for f in fields: fieldIndex = fields.indexFromName(unicode(f.name())) formCnf = layer.editFormConfig() editorWidget = formCnf.widgetType(fieldIndex) if editorWidget == QgsVectorLayer.Hidden or \ editorWidget == 'Hidden': continue options.append(f.name()) for option in options: self.attr = QTreeWidgetItem(self) self.attrWidget = QComboBox() self.attrWidget.addItem("no label") self.attrWidget.addItem("inline label") self.attrWidget.addItem("header label") custProp = layer.customProperty("qgis2web/popup/" + option) if (custProp != "" and custProp is not None): self.attrWidget.setCurrentIndex( self.attrWidget.findText( layer.customProperty("qgis2web/popup/" + option))) self.attr.setText(1, option) self.popupItem.addChild(self.attr) tree.setItemWidget(self.attr, 2, self.attrWidget) self.addChild(self.popupItem) else: if layer.providerType() == 'wms': self.getFeatureInfoItem = QTreeWidgetItem(self) self.getFeatureInfoCheck = QCheckBox() if layer.customProperty("qgis2web/GetFeatureInfo") == 2: self.getFeatureInfoCheck.setChecked(True) self.getFeatureInfoItem.setText(0, "Enable GetFeatureInfo?") self.getFeatureInfoCheck.stateChanged.connect( self.changeGetFeatureInfo) self.addChild(self.getFeatureInfoItem) tree.setItemWidget(self.getFeatureInfoItem, 1, self.getFeatureInfoCheck) @property def popup(self): popup = [] self.tree = self.treeWidget() for p in xrange(self.childCount()): item = self.child(p).text(1) if item != "": popupVal = self.tree.itemWidget(self.child(p), 2).currentText() pair = (item, popupVal) popup.append(pair) popup = OrderedDict(popup) return popup @property def visible(self): return self.visibleCheck.isChecked() @property def json(self): try: return self.jsonCheck.isChecked() except: return False @property def cluster(self): try: return self.clusterCheck.isChecked() except: return False @property def getFeatureInfo(self): try: return self.getFeatureInfoCheck.isChecked() except: return False def changeJSON(self, isJSON): self.layer.setCustomProperty("qgis2web/Encode to JSON", isJSON) def changeCluster(self, isCluster): self.layer.setCustomProperty("qgis2web/Cluster", isCluster) def changeGetFeatureInfo(self, isGetFeatureInfo): self.layer.setCustomProperty("qgis2web/GetFeatureInfo", isGetFeatureInfo)
def loadCulturas(self): # Carregar culturas self.culturas = [] self.cursor.execute(''' SELECT * FROM cultura''') for linha in self.cursor.fetchall(): self.culturas.append({'nome': linha[0], 'id': linha[1]}) # Carregar informacoes regionais for cultura in self.culturas: cultura['configuracoes'] = [] self.cursor.execute(''' SELECT * FROM configuracaoRegional WHERE culturaID = ?''', (cultura['id'],)) for linha in self.cursor.fetchall(): cultura['configuracoes'].append({'id': linha[0], 'nome': linha[2], 'estados': pickle.loads(linha[3]), 'tipo_vrad': linha[4], 'solo': pickle.loads(linha[6]) # 'vrad': linha, }) # Carregar grupos for cultura in self.culturas: for configuracao in cultura['configuracoes']: configuracao['grupos'] = [] self.cursor.execute(''' SELECT * FROM grupo WHERE culturaRegiao = ?''', (configuracao['id'],)) for linha in self.cursor.fetchall(): configuracao['grupos'].append({'id': linha[0], 'nome': linha[1], 'ciclo': linha[3], 'tipoKc': linha[4], 'kc': pickle.loads(linha[5]), 'fases': pickle.loads(linha[6])}) # Exibir informacoes for cultura in self.culturas: itemCultura = QTreeWidgetItem() itemCultura.setText(0, cultura['nome']) itemCultura.setFlags(Qt.ItemIsEditable|Qt.ItemIsEnabled|Qt.ItemIsSelectable) self.treeWidget.addTopLevelItem(itemCultura) cultura['item'] = itemCultura for configuracao in cultura['configuracoes']: itemConf = QTreeWidgetItem() itemConf.setText(0, configuracao['nome']) itemConf.setText(1, ', '.join(configuracao['estados'])) itemConf.setFlags(Qt.ItemIsEditable|Qt.ItemIsEnabled|Qt.ItemIsSelectable) itemCultura.addChild(itemConf) configuracao['item'] = itemConf for grupo in configuracao['grupos']: itemGrupo = QTreeWidgetItem() itemGrupo.setText(0, grupo['nome']) itemGrupo.setText(1, str(grupo['ciclo']) + ' dias') itemGrupo.setFlags(Qt.ItemIsEditable|Qt.ItemIsEnabled|Qt.ItemIsSelectable) itemConf.addChild(itemGrupo) grupo['item'] = itemGrupo self.treeWidget.resizeColumnToContents(0)
def on_update(self): def item_path(item): # Recursively builds the path for an item eg 'parent_name/item_name' return item.text(0) if not item.parent() else item_path(item.parent()) + "/" + item.text(0) def remember_expanded_items(root): # Save the set of expanded items... so that address list updates don't annoyingly collapse # our tree list widget due to the update. This function recurses. Pass self.invisibleRootItem(). expanded_item_names = set() for i in range(0, root.childCount()): it = root.child(i) if it and it.childCount(): if it.isExpanded(): expanded_item_names.add(item_path(it)) expanded_item_names |= remember_expanded_items(it) # recurse return expanded_item_names def restore_expanded_items(root, expanded_item_names): # Recursively restore the expanded state saved previously. Pass self.invisibleRootItem(). for i in range(0, root.childCount()): it = root.child(i) if it and it.childCount(): restore_expanded_items(it, expanded_item_names) # recurse, do leaves first old = bool(it.isExpanded()) new = bool(item_path(it) in expanded_item_names) if old != new: it.setExpanded(new) self.wallet = self.parent.wallet had_item_count = self.topLevelItemCount() item = self.currentItem() current_address = item.data(0, Qt.UserRole) if item else None expanded_item_names = remember_expanded_items(self.invisibleRootItem()) self.clear() receiving_addresses = self.wallet.get_receiving_addresses() change_addresses = self.wallet.get_change_addresses() if self.parent.fx and self.parent.fx.get_fiat_address_config(): fx = self.parent.fx else: fx = None account_item = self sequences = [0,1] if change_addresses else [0] items_to_re_select = [] for is_change in sequences: if len(sequences) > 1: name = _("Receiving") if not is_change else _("Change") seq_item = QTreeWidgetItem( [ name, '', '', '', '', ''] ) account_item.addChild(seq_item) if not is_change and not had_item_count: # first time we create this widget, auto-expand the default address list seq_item.setExpanded(True) expanded_item_names.add(item_path(seq_item)) else: seq_item = account_item used_item = QTreeWidgetItem( [ _("Used"), '', '', '', '', ''] ) used_flag = False addr_list = change_addresses if is_change else receiving_addresses for n, address in enumerate(addr_list): num = len(self.wallet.get_address_history(address)) is_used = self.wallet.is_used(address) balance = sum(self.wallet.get_addr_balance(address)) address_text = address.to_ui_string() label = self.wallet.labels.get(address.to_storage_string(), '') balance_text = self.parent.format_amount(balance, whitespaces=True) columns = [address_text, str(n), label, balance_text, str(num)] if fx: rate = fx.exchange_rate() fiat_balance = fx.value_str(balance, rate) columns.insert(4, fiat_balance) address_item = SortableTreeWidgetItem(columns) address_item.setTextAlignment(3, Qt.AlignRight) address_item.setFont(3, QFont(MONOSPACE_FONT)) if fx: address_item.setTextAlignment(4, Qt.AlignRight) address_item.setFont(4, QFont(MONOSPACE_FONT)) address_item.setFont(0, QFont(MONOSPACE_FONT)) address_item.setData(0, Qt.UserRole, address) address_item.setData(0, Qt.UserRole+1, True) # label can be edited if self.wallet.is_frozen(address): address_item.setBackground(0, QColor('lightblue')) if self.wallet.is_beyond_limit(address, is_change): address_item.setBackground(0, QColor('red')) if is_used: if not used_flag: seq_item.insertChild(0, used_item) used_flag = True used_item.addChild(address_item) else: seq_item.addChild(address_item) if address == current_address: items_to_re_select.append(address_item) if items_to_re_select: # NB: Need to select the item at the end becasue internally Qt does some index magic # to pick out the selected item and the above code mutates the TreeList, invalidating indices # and other craziness, which might produce UI glitches. See #1042 self.setCurrentItem(items_to_re_select[-1]) # Now, at the very end, enforce previous UI state with respect to what was expanded or not. See #1042 restore_expanded_items(self.invisibleRootItem(), expanded_item_names)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Set up dragging. #tree.setAcceptDrops(True) self.setDragEnabled(True) # Clear the treeWidget_Plugins list and redraw it, according to # the type filter. # TODO: is this needed? forget why it was put here. self.clear() # Loop over the plugin subpackages. for subpackage in [Analyses, Transforms, Utilities]: plugin_type = subpackage.__name__.split('.')[-1] # Make a new leaf item. package_item = QTreeWidgetItem() # Set the name in column 0. package_item.setText(0, plugin_type) # Attach the widget item to the parent tree. self.addTopLevelItem(package_item) # Loop over defined plugins in it. category_plugin_dict = defaultdict(list) for item_name in dir(subpackage): item = getattr(subpackage, item_name) # Can check for the _plugin_type attribute, attached # by the decorator. if not getattr(item, '_plugin_type', None): continue # Skip if the file name starts with an underscore, indicating # an experimental function. if item.__name__[0] == '_': continue # Record this function for the category. category_plugin_dict[item._category].append(item) # TODO: nested categories. # For now, just a flat list. for category, plugin_list in category_plugin_dict.items(): for plugin in plugin_list: # Create a nested tree node. subitem = QTreeWidgetItem() # Assign the name as text to column 0. subitem.setText(0, plugin.__name__) # Attach the widget item to the parent tree. package_item.addChild(subitem) # Annotate the item with the plugin, for easy # referencing. # TODO: record better customized doc text which # includes the function call signature. subitem.plugin = plugin self.expandAll() self.currentItemChanged.connect(self.Handle_currentItemChanged) return
def __init__(self, dialog): super(Shortcuts, self).__init__(dialog) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.scheme = SchemeSelector(self) layout.addWidget(self.scheme) self.searchEntry = LineEdit() self.searchEntry.setPlaceholderText(_("Search...")) layout.addWidget(self.searchEntry) self.tree = QTreeWidget(self) self.tree.setHeaderLabels([_("Command"), _("Shortcut")]) self.tree.setRootIsDecorated(False) self.tree.setColumnCount(2) self.tree.setAllColumnsShowFocus(True) self.tree.setAnimated(True) layout.addWidget(self.tree) self.edit = QPushButton(icons.get("preferences-desktop-keyboard-shortcuts"), '') layout.addWidget(self.edit) # signals self.searchEntry.textChanged.connect(self.updateFilter) self.scheme.currentChanged.connect(self.slotSchemeChanged) self.scheme.changed.connect(self.changed) self.tree.currentItemChanged.connect(self.slotCurrentItemChanged) self.tree.itemDoubleClicked.connect(self.editCurrentItem) self.edit.clicked.connect(self.editCurrentItem) # make a dict of all actions with the actions as key and the names as # value, with the collection prepended (for loading/saving) win = dialog.parent() allactions = {} for collection in actioncollectionmanager.manager(win).actionCollections(): for name, action in collection.actions().items(): allactions[action] = (collection, name) # keep a list of actions not in the menu structure left = list(allactions.keys()) def add_actions(menuitem, actions): """Add actions to a QTreeWidgetItem.""" for a in actions: if a.menu(): item = build_menu_item(a) if item.childCount(): menuitem.addChild(item) elif a in left: left.remove(a) menuitem.addChild(ShortcutItem(a, *allactions[a])) menuitem.setFlags(Qt.ItemIsEnabled) # disable selection def build_menu_item(action): """Return a QTreeWidgetItem with children for all the actions in the submenu.""" menuitem = QTreeWidgetItem() text = qutil.removeAccelerator(action.text()) menuitem.setText(0, _("Menu {name}").format(name=text)) add_actions(menuitem, action.menu().actions()) return menuitem # present the actions nicely ordered as in the menus for a in win.menuBar().actions(): menuitem = build_menu_item(a) if menuitem.childCount(): self.tree.addTopLevelItem(menuitem) # sort leftover actions left.sort(key=lambda i: i.text()) # show actions that are left, grouped by collection titlegroups = {} for a in left[:]: # copy collection, name = allactions[a] if collection.title(): titlegroups.setdefault(collection.title(), []).append(a) left.remove(a) for title in sorted(titlegroups): item = QTreeWidgetItem(["{0}:".format(title)]) for a in titlegroups[title]: item.addChild(ShortcutItem(a, *allactions[a])) self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection # show other actions that were not in the menus item = QTreeWidgetItem([_("Other commands:")]) for a in left: if a.text() and not a.menu(): item.addChild(ShortcutItem(a, *allactions[a])) if item.childCount(): self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection self.tree.expandAll() item = self.tree.topLevelItem(0).child(0) if _lastaction: # find the previously selected item for i in self.items(): if i.name == _lastaction: item = i break self.tree.setCurrentItem(item) self.tree.resizeColumnToContents(0)
def populate_available_terms(self): """ Runs when annotations tab is viewed and when volume is changed. Populates the avaible annotation terms. """ self.ui.treeWidgetAvailableTerms.clear() vol = self.controller.current_annotation_volume() if not vol or None in (vol.annotations.stage, vol.annotations.center): # info_dialog(self, 'Chose centre and stage', 'You must choose a centre and stage from the options tab') return self.ui.lineEditCentre.setText(vol.annotations.center) self.ui.lineEditStage.setText(vol.annotations.stage.name) self.ui.lineEditModality.setText(vol.annotations.modality.value) def setup_option_box_signal(box_: QComboBox, child_: QTreeWidgetItem): """ Connect the Qcombobox to a slot """ box_.activated.connect( partial(self.update_annotation, child_, box_)) # Setup signal so when combobox is only opened, it sets the selection to that column box_.highlighted.connect(partial(self.on_box_highlight, child)) header_labels = QTreeWidgetItem( ['', 'term', 'name', 'option', 'done?']) self.ui.treeWidgetAvailableTerms.setHeaderItem(header_labels) parent = QTreeWidgetItem(self.ui.treeWidgetAvailableTerms) parent.setText(0, '') parent.setFlags(parent.flags()) parent.setExpanded(True) header = self.ui.treeWidgetAvailableTerms.header() # Set root column to invisible self.ui.treeWidgetAvailableTerms.setColumnWidth(0, 0) header.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeToContents) # For each annotation set an info row in the annotations table for i, ann in enumerate( sorted(vol.annotations, key=lambda an_: an_.order)): child = QTreeWidgetItem(parent) child.setText(1, ann.term) child.setText(3, ann.name) option = ann.selected_option # color = OPTION_COLOR_MAP[option] parent.addChild(child) # Set up the parameter option combobox and highlight the currently selected one options_box = QComboBox() options_box.setSizeAdjustPolicy(QComboBox.AdjustToContents) for opt in ann.options: options_box.addItem(opt) options_box.setCurrentIndex(options_box.findText( option)) # 060818 Louise's bug option is a bool not a str # Setup combobox selection signal setup_option_box_signal(options_box, child) self.ui.treeWidgetAvailableTerms.setItemWidget( child, 2, options_box) done_checkbox = QtWidgets.QCheckBox() done_checkbox.setChecked(ann.looked_at) done_checkbox.stateChanged.connect( partial(self.parameter_done_signal, child, done_checkbox)) self.ui.treeWidgetAvailableTerms.setItemWidget( child, 4, done_checkbox) # Set the roi coords to None self.roi_highlight_off_signal.emit()
def addOverlaysToTreeWidget(self, overlayDict, forbiddenOverlays, preSelectedOverlays, singleOverlaySelection): self.singleOverlaySelection = singleOverlaySelection testItem = QTreeWidgetItem("a") for keys in list(overlayDict.keys()): if overlayDict[keys] in forbiddenOverlays: continue else: boolStat = False split = keys.split("/") for i in range(len(split)): if len(split) == 1: newItemsChild = OverlayTreeWidgetItem(overlayDict[keys], keys) self.addTopLevelItem(newItemsChild) boolStat = False if overlayDict[keys] in preSelectedOverlays: newItemsChild.setCheckState(0, Qt.Checked) else: newItemsChild.setCheckState(0, Qt.Unchecked) elif i+1 == len(split) and len(split) > 1: newItemsChild = OverlayTreeWidgetItem(overlayDict[keys], keys) testItem.addChild(newItemsChild) if overlayDict[keys] in preSelectedOverlays: newItemsChild.setCheckState(0, Qt.Checked) else: newItemsChild.setCheckState(0, Qt.Unchecked) elif self.topLevelItemCount() == 0 and i+1 < len(split): newItem = QTreeWidgetItem([split[i]]) self.addTopLevelItem(newItem) testItem = newItem boolStat = True elif self.topLevelItemCount() != 0 and i+1 < len(split): if boolStat == False: for n in range(self.topLevelItemCount()): if self.topLevelItem(n).text(0) == split[i]: testItem = self.topLevelItem(n) boolStat = True break elif n+1 == self.topLevelItemCount(): newItem = QTreeWidgetItem([split[i]]) self.addTopLevelItem(newItem) testItem = newItem boolStat = True elif testItem.childCount() == 0: newItem = QTreeWidgetItem([split[i]]) testItem.addChild(newItem) testItem = newItem boolStat = True else: for x in range(testItem.childCount()): if testItem.child(x).text(0) == split[i]: testItem = testItem.child(x) boolStat = True break elif x+1 == testItem.childCount(): newItem = QTreeWidgetItem([split[i]]) testItem.addChild(newItem) testItem = newItem boolStat = True