def _on_update_rules(self, new_rules): active_rule = self._model.active_rule item_to_select = None self._rules_list.clear() self._rules_list.blockSignals(True) try: for rule in new_rules: item = QTreeWidgetItem(self._rules_list, [rule.name]) item.rule = rule self._rules_list.addTopLevelItem(item) self._rules_list.setCurrentItem(item) if active_rule and active_rule == rule.name: item_to_select = item self._rules_list.setItemSelected(item, False) if item_to_select: self._rules_list.setItemSelected(item_to_select, True) except Exception as exc: LOGGER.error('{} | {}'.format(exc, traceback.format_exc())) finally: self._rules_list.blockSignals(False) self._on_update_active_rule(active_rule=self._model.active_rule)
def buildtree(parent, it): # Check for children try: for child in parent.children: itchild = QTreeWidgetItem(it, [child.label]) itchild.source = child buildtree(child, itchild) # Add child's children it.addChild(itchild) except AttributeError: # Probably no children return
def __init__(self, guide=None): super(TreeWidget, self).__init__() self.setColumnCount(1) self.setSelectionMode(self.ExtendedSelection) self.setDragDropMode(self.DragDrop) self.setDefaultDropAction(Qt.MoveAction) self.setHeaderHidden(True) for i in range(3): item = QTreeWidgetItem(self, ["LAYER LAYER {}".format(i)]) for i in range(3): QTreeWidgetItem(self, ["SYSTEM SYSTEM {}".format(i)]) self.itemSelectionChanged.connect(self.allowDragNDrop)
def textAlignment(self, column): """ Overrides base LibraryItem textAlignment function :param column: int """ return QTreeWidgetItem.textAlignment(self, column)
def add_conf_group(self, conf_group_widget): row = conf_group_widget.childCount() conformer_item = QTreeWidgetItem(conf_group_widget) conf_group_widget.insertChild(row, conformer_item) nrg_combobox = FilereaderComboBox(self.session, otherItems=['energy']) nrg_combobox.currentIndexChanged.connect( lambda *args: self.changes.emit()) freq_combobox = FilereaderComboBox(self.session, otherItems=['frequency']) freq_combobox.currentIndexChanged.connect( lambda *args: self.changes.emit()) trash_button = QPushButton() trash_button.setFlat(True) trash_button.clicked.connect( lambda *args, combobox=nrg_combobox: combobox.deleteLater()) trash_button.clicked.connect( lambda *args, combobox=freq_combobox: combobox.deleteLater()) trash_button.clicked.connect(lambda *args, child=conformer_item: conf_group_widget.removeChild(child)) trash_button.clicked.connect(lambda *args: self.changes.emit()) trash_button.setIcon( QIcon(self.style().standardIcon(QStyle.SP_DialogCancelButton))) self.tree.setItemWidget(conformer_item, 0, nrg_combobox) self.tree.setItemWidget(conformer_item, 1, freq_combobox) self.tree.setItemWidget(conformer_item, 2, trash_button) self.changes.emit()
def _add_row(self, item): values = [getattr(item, c) for c in self._columns] values = [str(v) if v not in (None, 0) else '' for v in values] new_item = QTreeWidgetItem(values) new_item.setFlags(new_item.flags() | Qt.ItemIsEditable) new_item.setData(0, Qt.UserRole, item) self._tree.addTopLevelItem(new_item)
def textAlignment(self, column): """ Returns the text alinment for the label in the given column :param column: int :return: QAlignmentFlag """ if self.viewer().is_icon_view(): return Qt.AlignCenter else: return QTreeWidgetItem.textAlignment(self, column)
def addSource(self, source): self.sources.append(source) it = QTreeWidgetItem(self.main.treeView, [source.label]) it.setIcon(0, self.groupIcon) it.source = source self.main.treeView.addTopLevelItem(it) def buildtree(parent, it): # Check for children try: for child in parent.children: itchild = QTreeWidgetItem(it, [child.label]) itchild.source = child buildtree(child, itchild) # Add child's children it.addChild(itchild) except AttributeError: # Probably no children return buildtree(source, it)
def font(self, column): """ Returns the font for the given column :param column: int :return: QFont """ default = QTreeWidgetItem.font(self, column) font = self._fonts.get(column, default) font.setPixelSize(self.font_size() * self.dpi()) return font
def _load_data(self): self._tree_hierarchy.clear() if not self._file_path or not os.path.isfile(self._file_path): return with open(self._file_path, 'r') as fh: skeleton_data = json.load(fh) if not skeleton_data: return created_nodes = dict() for node_data in skeleton_data: node_index = node_data.get('index', 0) node_parent_index = node_data.get('parent_index', -1) node_name = node_data.get('name', 'new_node') new_node = QTreeWidgetItem() new_node.setText(0, node_name) created_nodes[node_index] = { 'node': new_node, 'parent_index': node_parent_index } sorted(created_nodes.items(), key=lambda x: int(x[0])) for node_index, node_data in created_nodes.items(): node_data = created_nodes.get(node_index, None) if not node_data: continue node_item = node_data.get('node') parent_index = node_data['parent_index'] if parent_index <= -1: self._tree_hierarchy.addTopLevelItem(node_item) continue parent_node_data = created_nodes.get(parent_index, None) if not parent_node_data: continue parent_node_item = parent_node_data.get('node') parent_node_item.addChild(node_item) self._tree_hierarchy.expandAll()
def icon(self, column): """ Overrides base QTreeWidgetItem icon function Overrides icon to add support for thumbnail icon :param column: int :return: QIcon """ item_icon = QTreeWidgetItem.icon(self, column) if not item_icon and column == self.DEFAULT_THUMBNAIL_COLUMN: item_icon = self.thumbnail_icon() return item_icon
def __init__(self, name, session, nrg_fr, thermo_co, size, *args, **kwargs): super().__init__(*args, **kwargs) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.session = session self.nrg_fr = nrg_fr self.thermo_co = thermo_co layout = QGridLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setRowStretch(0, 1) frame = QGroupBox(name) frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) frame_layout = QGridLayout(frame) frame_layout.setContentsMargins(0, 0, 0, 0) frame_layout.setRowStretch(0, 1) self.tree = QTreeWidget() self.tree.setColumnCount(3) self.tree.setHeaderLabels(["energy", "frequencies", "remove"]) self.tree.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.tree.setColumnWidth(0, size[0]) self.tree.setColumnWidth(1, size[1]) self.tree.resizeColumnToContents(2) root_item = self.tree.invisibleRootItem() plus = QTreeWidgetItem(root_item) plus_button = QPushButton("add molecule") plus_button.setFlat(True) plus_button.clicked.connect(self.add_mol_group) plus_button2 = QPushButton("") plus_button2.setFlat(True) plus_button2.clicked.connect(self.add_mol_group) self.tree.setItemWidget(plus, 0, plus_button) self.tree.setItemWidget(plus, 1, plus_button2) self.tree.insertTopLevelItem(1, plus) self.add_mol_group() frame_layout.addWidget(self.tree) layout.addWidget(frame)
def get_tree_item_name(self, tree_item): """ Returns a list with all the column names of the given QTreeWidgetItem :param tree_item: QTreeWidgetItem, item we want to retrive name of :return: list<str> """ try: # When selecting an item in the tree and refreshing a C++ wrapped will raise count = QTreeWidgetItem.columnCount(tree_item) except Exception: count = 0 name = list() for i in range(count): name.append(str(tree_item.text(i))) return name
def add_mol_group(self, *args): row = self.tree.topLevelItemCount() root_item = self.tree.invisibleRootItem() mol_group = QTreeWidgetItem(root_item) self.tree.insertTopLevelItem(row, mol_group) trash_button = QPushButton() trash_button.setFlat(True) trash_button.clicked.connect( lambda *args, parent=mol_group: self.remove_mol_group(parent)) trash_button.setIcon( QIcon(self.style().standardIcon(QStyle.SP_DialogDiscardButton))) add_conf_button = QPushButton("add conformer") add_conf_button.setFlat(True) add_conf_button.clicked.connect( lambda *args, conf_group_widget=mol_group: self.add_conf_group( conf_group_widget)) add_conf_button2 = QPushButton("") add_conf_button2.setFlat(True) add_conf_button2.clicked.connect( lambda *args, conf_group_widget=mol_group: self.add_conf_group( conf_group_widget)) add_conf_child = QTreeWidgetItem(mol_group) self.tree.setItemWidget(add_conf_child, 0, add_conf_button) self.tree.setItemWidget(add_conf_child, 1, add_conf_button2) self.tree.setItemWidget(mol_group, 2, trash_button) mol_group.setText(0, "group %i" % row) mol_group.addChild(add_conf_child) self.add_conf_group(mol_group) self.tree.expandItem(mol_group) self.changes.emit()
def _update_names_list(self, nodes): """ Internal function that updates names list with given node names :param nodes: list(str) """ nodes_to_discard = self._get_nodes_to_discard() or list() nodes = list(set(nodes)) for obj in nodes: if obj in nodes_to_discard: continue node_type = dcc.node_type(obj) if node_type not in self._get_node_types( ) and not self._others_btn.isChecked(): is_valid = False for node_type in self._get_node_types(): is_valid = dcc.check_object_type(obj, node_type, check_sub_types=True) if is_valid: break if not is_valid: continue node_name = dcc.node_short_name(obj) item = QTreeWidgetItem(self._names_list, [node_name]) item.obj = node_name item.preview_name = '' item.full_name = obj if dcc.is_maya(): sel = api.SelectionList() sel.add(obj) item.handle = maya.OpenMaya.MObjectHandle( sel.get_depend_node(0)) self._names_list.addTopLevelItem(item)
def update_versions_from_commits_data(self, commits_data, current_commit_data=None): self.clear() if not commits_data: return # https://stackoverflow.com/questions/42896141/how-to-lazily-iterate-on-reverse-order-of-keys-in-ordereddict/42896182#42896182 for i, (commit, commit_data) in enumerate( ((commit, commits_data[commit]) for commit in reversed(commits_data))): item = QTreeWidgetItem() item.setText(0, str(i + 1)) item.setText(1, commit_data.get('message', '')) item.setText(2, commit_data.get('author', '')) item.setText(3, commit_data.get('date', '')) item.setText(4, commit) self.addTopLevelItem(item) if current_commit_data: for current_commit in list(current_commit_data.keys()): if current_commit == commit: item.setBackgroundColor(0, Qt.green)
def _add_item(self, version_data): version, comment, user, file_size, file_date, version_file = version_data version_str = str(version).zfill(self._padding) item = QTreeWidgetItem() item.setText(0, version_str) item.setText(1, comment) item.setText(2, str(file_size)) item.setText(3, user) item.setText(4, file_date) self.addTopLevelItem(item) item.file_path = version_file
def fill_tree(self, trigger_name=None, trigger_job=None): item_stack = [self.tree.invisibleRootItem()] self.tree.clear() jobs = self.session.seqcrow_job_manager.jobs for job in jobs: name = job.name parent = item_stack[0] item = QTreeWidgetItem(parent) item_stack.append(item) item.setData(self.NAME_COL, Qt.DisplayRole, job) item.setText(self.NAME_COL, name) if isinstance(job, LocalJob): if job.killed: item.setText(self.STATUS_COL, "killed") del_job_widget = QWidget() del_job_layout = QGridLayout(del_job_widget) del_job = QPushButton() del_job.clicked.connect( lambda *args, job=job: self.remove_job(job)) del_job.setIcon( QIcon(del_job_widget.style().standardIcon( QStyle.SP_DialogDiscardButton))) del_job.setFlat(True) del_job_layout.addWidget(del_job, 0, 0, 1, 1, Qt.AlignHCenter) del_job_layout.setColumnStretch(0, 1) del_job_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.DEL_COL, del_job_widget) elif job.isRunning(): if job in self.session.seqcrow_job_manager.unknown_status_jobs: unk_widget = QWidget() unk_layout = QGridLayout(unk_widget) unk = QPushButton() unk.setIcon( QIcon(unk_widget.style().standardIcon( QStyle.SP_MessageBoxQuestion))) unk.setFlat(True) unk.clicked.connect(lambda *args, job=job: self. show_ask_if_running(job)) unk_layout.addWidget(unk, 0, 0, 1, 1, Qt.AlignHCenter) unk_layout.setColumnStretch(0, 1) unk_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.STATUS_COL, unk_widget) else: item.setText(self.STATUS_COL, "running") kill_widget = QWidget() kill_layout = QGridLayout(kill_widget) kill = QPushButton() kill.setIcon( QIcon(kill_widget.style().standardIcon( QStyle.SP_DialogCancelButton))) kill.setFlat(True) kill.clicked.connect(lambda *args, job=job: job.kill()) kill.clicked.connect( lambda *args, session=self.session: session. seqcrow_job_manager.triggers.activate_trigger( JOB_QUEUED, "resume")) kill_layout.addWidget(kill, 0, 0, 1, 1, Qt.AlignLeft) kill_layout.setColumnStretch(0, 0) kill_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.KILL_COL, kill_widget) elif job.isFinished(): if not job.error: item.setText(self.STATUS_COL, "finished") else: error_widget = QWidget() error_layout = QGridLayout(error_widget) error = QPushButton() error.setIcon( QIcon(error_widget.style().standardIcon( QStyle.SP_MessageBoxWarning))) error.setFlat(True) error.setToolTip( "job did not finish without errors or output file cannot be found" ) error_layout.addWidget(error, 0, 0, 1, 1, Qt.AlignHCenter) error_layout.setColumnStretch(0, 1) error_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.STATUS_COL, error_widget) del_job_widget = QWidget() del_job_layout = QGridLayout(del_job_widget) del_job = QPushButton() del_job.clicked.connect( lambda *args, job=job: self.remove_job(job)) del_job.setIcon( QIcon(del_job_widget.style().standardIcon( QStyle.SP_DialogDiscardButton))) del_job.setFlat(True) del_job_layout.addWidget(del_job, 0, 0, 1, 1, Qt.AlignHCenter) del_job_layout.setColumnStretch(0, 1) del_job_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.DEL_COL, del_job_widget) else: item.setText(self.STATUS_COL, "queued") priority_widget = QWidget() priority_layout = QGridLayout(priority_widget) inc_priority = QPushButton() inc_priority.setIcon( QIcon(priority_widget.style().standardIcon( QStyle.SP_ArrowUp))) inc_priority.setFlat(True) inc_priority.clicked.connect( lambda *args, job=job: self.session.seqcrow_job_manager .increase_priotity(job)) priority_layout.addWidget(inc_priority, 0, 0, 1, 1, Qt.AlignRight) dec_priority = QPushButton() dec_priority.setIcon( QIcon(priority_widget.style().standardIcon( QStyle.SP_ArrowDown))) dec_priority.setFlat(True) dec_priority.clicked.connect( lambda *args, job=job: self.session.seqcrow_job_manager .decrease_priotity(job)) priority_layout.addWidget(dec_priority, 0, 1, 1, 1, Qt.AlignLeft) priority_layout.setColumnStretch(0, 1) priority_layout.setColumnStretch(1, 1) priority_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.CHANGE_PRIORITY, priority_widget) kill_widget = QWidget() kill_layout = QGridLayout(kill_widget) kill = QPushButton() kill.setIcon( QIcon(kill_widget.style().standardIcon( QStyle.SP_DialogCancelButton))) kill.setFlat(True) kill.clicked.connect(lambda *args, job=job: job.kill()) kill.clicked.connect( lambda *args, session=self.session: session. seqcrow_job_manager.triggers.activate_trigger( JOB_QUEUED, "resume")) kill_layout.addWidget(kill, 0, 0, 1, 1, Qt.AlignLeft) kill_layout.setColumnStretch(0, 0) kill_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.KILL_COL, kill_widget) item.setText(self.SERVER_COL, "local") if job.scratch_dir and os.path.exists(job.scratch_dir): browse_widget = QWidget() browse_layout = QGridLayout(browse_widget) browse = QPushButton() browse.clicked.connect( lambda *args, job=job: self.browse_local(job)) browse.setIcon( QIcon(browse_widget.style().standardIcon( QStyle.SP_DirOpenIcon))) browse.setFlat(True) browse_layout.addWidget(browse, 0, 0, 1, 1, Qt.AlignLeft) browse_layout.setColumnStretch(0, 1) browse_layout.setContentsMargins(0, 0, 0, 0) self.tree.setItemWidget(item, self.BROWSE_COL, browse_widget) self.tree.expandItem(item) self.tree.resizeColumnToContents(self.STATUS_COL) self.tree.resizeColumnToContents(self.SERVER_COL) self.tree.resizeColumnToContents(self.CHANGE_PRIORITY) self.tree.resizeColumnToContents(self.KILL_COL) self.tree.resizeColumnToContents(self.DEL_COL) self.tree.resizeColumnToContents(self.BROWSE_COL)
def insertNode(self, nodeCategoryPath, name, doc=None, libName=None): nodePath = nodeCategoryPath.split('|') categoryPath = '' # walk from tree top to bottom, creating folders if needed # also writing all paths in dict to avoid duplications for folderId in range(0, len(nodePath)): folderName = nodePath[folderId] if folderId == 0: categoryPath = folderName if categoryPath not in self.categoryPaths: rootFolderItem = QTreeWidgetItem(self) rootFolderItem.bCategory = True rootFolderItem.setFlags(QtCore.Qt.ItemIsEnabled) rootFolderItem.setText(0, folderName) rootFolderItem.setBackground(folderId, QtGui.QColor(80, 85, 80)) self.categoryPaths[categoryPath] = rootFolderItem else: parentCategoryPath = categoryPath categoryPath += '|{}'.format(folderName) if categoryPath not in self.categoryPaths: childCategoryItem = QTreeWidgetItem( self.categoryPaths[parentCategoryPath]) childCategoryItem.setFlags(QtCore.Qt.ItemIsEnabled) childCategoryItem.bCategory = True childCategoryItem.setText(0, folderName) childCategoryItem.setBackground(0, QtGui.QColor(80, 85, 80)) self.categoryPaths[categoryPath] = childCategoryItem # create node under constructed folder nodeItem = QTreeWidgetItem(self.categoryPaths[categoryPath]) nodeItem.bCategory = False nodeItem.setText(0, name) nodeItem.libName = libName if doc: nodeItem.setToolTip(0, doc)
def fill_tree(self, *args): item_stack = [self.tree.invisibleRootItem()] self.tree.clear() self._items = [] fr_dict = self.session.filereader_manager.filereader_dict for model in fr_dict.keys(): id = model.id if id is None: continue name = model.name parent = item_stack[0] item = QTreeWidgetItem(parent) item._model = model item_stack.append(item) self._items.append(item) item.setData(self.NAME_COL, Qt.DisplayRole, model) item.setText(self.NAME_COL, name) item.setText(self.ID_COL, ".".join([str(x) for x in id])) if any(x.all_geom is not None and len(x.all_geom) > 1 for x in fr_dict[model]): item.setText(self.COORDSETS_COL, "yes") else: item.setText(self.COORDSETS_COL, "no") if any("energy" in x.other for x in fr_dict[model]): item.setText(self.NRG_COL, "yes") else: item.setText(self.NRG_COL, "no") if any("frequency" in x.other for x in fr_dict[model]): item.setText(self.FREQ_COL, "yes") else: item.setText(self.FREQ_COL, "no") for fr in fr_dict[model]: child = QTreeWidgetItem(item) child.setData(self.NAME_COL, Qt.DisplayRole, fr) child.setText(self.NAME_COL, fr.name) if fr.all_geom is not None and len(fr.all_geom) > 1: child.setText(self.COORDSETS_COL, "yes") else: child.setText(self.COORDSETS_COL, "no") if "energy" in fr.other: child.setText(self.NRG_COL, "%.6f" % fr.other["energy"]) else: child.setText(self.NRG_COL, "") if "frequency" in fr.other: child.setText(self.FREQ_COL, "yes") else: child.setText(self.FREQ_COL, "no") #self.tree.expandItem(item) for i in [self.ID_COL, self.COORDSETS_COL, self.NRG_COL, self.FREQ_COL]: self.tree.resizeColumnToContents(i)
def _add_item(self, file_name, parent=None): """ Function that adds given file into the tree :param file_name: str, name of the file new item will store :param parent: QTreeWidgetItem, parent item to append new item into :return: QTreeWidet, new item added """ try: self.blockSignals(True) self.clearSelection() finally: self.blockSignals(False) path_name = file_name found = False # Check if item exists if parent: parent_path = self.get_tree_item_path_string(parent) path_name = '{}/{}'.format(parent_path, file_name) for i in range(parent.childCount()): item = parent.child(i) if item.text(0) == file_name: found = item else: for i in range(self.topLevelItemCount()): item = self.topLevelItem(i) if item.text(0) == file_name: found = item # Check if the item should be excluded or not from the tree exclude = self.EXCLUDE_EXTENSIONS if exclude: split_name = file_name.split('.') extension = split_name[-1] if extension in exclude: return if found: item = found else: item = self.create_item_widget(file_name) # Constrain item size if necessary size = self.ITEM_WIDGET_SIZE if size: size = QSize(*size) item.setSizeHint(self._title_text_index, size) # Set item text item_path = path.join_path(self._directory, path_name) sub_files = folder.get_files_and_folders(item_path) item.setText(self._title_text_index, file_name) # Retrieve file properties if self.header().count() > 1: if path.is_file(item_path): size = fileio.get_file_size(item_path) date = fileio.get_last_modified_date(item_path) item.setText(self._title_text_index + 1, str(size)) item.setText(self._title_text_index + 2, str(date)) # Update valid sub files # NOTE: Sub files are added dynamically when the user expands an item if sub_files: self._delete_children(item) exclude_extensions = self.EXCLUDE_EXTENSIONS exclude_count = 0 if exclude_extensions: for f in sub_files: for exclude in exclude_extensions: if f.endswith(exclude): exclude_count += 1 break if exclude_count != len(sub_files): QTreeWidgetItem(item) # Add item to tree hierarchy if parent: parent.addChild(item) try: self.blockSignals(True) self.setCurrentItem(item) finally: self.blockSignals(False) else: self.addTopLevelItem(item) return item