def UpdateFileList(self, baseFolder: Path, fileList: QtWidgets.QTreeWidget): assert (fileList) assert (baseFolder) asset_path = baseFolder / re_project._RE_DCC_APP fileList.clear() for pattern in self.sceneDCCExtensions: filelist_gen = asset_path.glob(pattern) file_list = list(filelist_gen) for file_path in file_list: rel_path: Path = file_path.relative_to(asset_path) #print(rel_path.as_posix()) file_stats: os.stat_result = file_path.stat() mtime = file_stats.st_mtime timestamp_str = datetime.datetime.fromtimestamp( mtime).strftime('%Y-%m-%d-%H:%M') fileList.addTopLevelItem( QtWidgets.QTreeWidgetItem([ rel_path.as_posix(), timestamp_str, ProjectManagerUI.convert_file_size(file_stats.st_size) ])) fileList.resizeColumnToContents(0) fileList.resizeColumnToContents(2)
def update_hint_locations(game: RandovaniaGame, hint_tree_widget: QtWidgets.QTreeWidget): game_description = default_database.game_description_for(game) number_for_hint_type = { hint_type: i + 1 for i, hint_type in enumerate(LoreType) } used_hint_types = set() hint_tree_widget.clear() hint_tree_widget.setSortingEnabled(False) # TODO: This ignores the Dark World names. But there's currently no logbook nodes in Dark World. for world in game_description.world_list.worlds: world_item = QtWidgets.QTreeWidgetItem(hint_tree_widget) world_item.setText(0, world.name) world_item.setExpanded(True) for area in world.areas: hint_types = {} for node in area.nodes: if isinstance(node, LogbookNode): if node.required_translator is not None: hint_types[ node. lore_type] = node.required_translator.short_name else: hint_types[node.lore_type] = "✓" if hint_types: area_item = QtWidgets.QTreeWidgetItem(world_item) area_item.setText(0, area.name) for hint_type, text in hint_types.items(): area_item.setText(number_for_hint_type[hint_type], text) used_hint_types.add(hint_type) hint_tree_widget.resizeColumnToContents(0) hint_tree_widget.setSortingEnabled(True) hint_tree_widget.sortByColumn(0, QtCore.Qt.AscendingOrder) for hint_type in used_hint_types: hint_tree_widget.headerItem().setText(number_for_hint_type[hint_type], hint_type.long_name)
def reset_model(self, index): """Setup model according to current relationship_class selected in combobox. """ self.class_name, self.object_class_name_list = self.relationship_class_keys[ index] object_class_name_list = self.object_class_name_list.split(",") self.model.set_horizontal_header_labels(object_class_name_list) self.existing_items_model.set_horizontal_header_labels( object_class_name_list) self.new_items_model.set_horizontal_header_labels( object_class_name_list) self.relationship_ids.clear() for db_map in self.db_maps: relationship_classes = self.db_map_rel_cls_lookup[db_map] rel_cls = relationship_classes.get( (self.class_name, self.object_class_name_list), None) if rel_cls is None: continue for relationship in self.db_mngr.get_items_by_field( db_map, "relationship", "class_id", rel_cls["id"]): key = tuple(relationship["object_name_list"].split(",")) self.relationship_ids[key] = relationship["id"] existing_items = list(self.relationship_ids) self.existing_items_model.reset_model(existing_items) self.model.refresh() self.model.modelReset.emit() for wg in self.splitter_widgets(): wg.deleteLater() for name in object_class_name_list: tree_widget = QTreeWidget(self) tree_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) tree_widget.setColumnCount(1) tree_widget.setIndentation(0) header_item = QTreeWidgetItem([name]) header_item.setTextAlignment(0, Qt.AlignHCenter) tree_widget.setHeaderItem(header_item) objects = self.db_mngr.get_items_by_field(self.db_map, "object", "class_name", name) items = [QTreeWidgetItem([obj["name"]]) for obj in objects] tree_widget.addTopLevelItems(items) tree_widget.resizeColumnToContents(0) self.splitter.addWidget(tree_widget) sizes = [wg.columnWidth(0) for wg in self.splitter_widgets()] self.splitter.setSizes(sizes) for widget in self.hidable_widgets: widget.show()
def _initUI(self): def _init_tool_buttons(): # First logic buttons logic_buttons_layout = QHBoxLayout() logic_buttons = [('NO', QPushButton('NO')), ('AND', QPushButton('AND')), ('OR', QPushButton('OR')), ('implies', QPushButton('→')), ('equivalence', QPushButton('↔')), ('forall', QPushButton('∀')), ('exists', QPushButton('∃'))] for name, button in logic_buttons: if name in self.tool_buttons: logic_buttons_layout.addWidget(button) # Then proof buttons proof_buttons_layout = QHBoxLayout() proof_buttons = [\ ('p_contraposition', QPushButton('Proof by contraposition')), ('p_absurd', QPushButton('Proof by contradicton')), ('p_cases', QPushButton('Cases disjunction')), ('p_induction', QPushButton('Proof by induction'))] for name, button in proof_buttons: if name in self.tool_buttons: proof_buttons_layout.addWidget(button) # Put it all together buttons_layout = QVBoxLayout() buttons_layout.addLayout(logic_buttons_layout) buttons_layout.addLayout(proof_buttons_layout) return buttons_layout # Create widgets objects = PropobjList() objects.addItem('X : ensemble') objects.addItem('Y : ensemble') objects.addItem('f : X → Y') objects.addItem('x ∈ X') objects.addItem('A : partie de X') icon_item = QListWidgetItem('B partie de X') icon_item.setIcon(QIcon('icon_blue.png')) objects.addItem(icon_item) properties = PropobjList() properties.addItem('f est une fonction de remplissage') properties.addItem("transitivité de l'union") statements = QTreeWidget() statements.setAlternatingRowColors(True) statements.setHeaderLabels(['Énoncé', 'Identifiant']) anneaux_ideaux = StatementNode(statements, 'Anneaux et idéaux') Statement(anneaux_ideaux, ['Définition anneau', 'Définition 1.1']) Statement(anneaux_ideaux, ['Définition idéal', 'Définition 1.7']) Statement(anneaux_ideaux, ["Existence d'un idéal maximal", 'Théorème']) noetherianite = StatementNode(statements, 'Noetherianité') Statement(noetherianite, ['Transfert de Noethérianité', '']) Statement(noetherianite, ['Principal implique noethérien', 'Proposition 2.3']) statements.resizeColumnToContents(0) goal = Goal(GOAL) # Create layouts goal_layout = QHBoxLayout() logic_buttons = _init_tool_buttons() # already contains buttons main_layout = QVBoxLayout() workspace_layout = QHBoxLayout() propobj_layout = QVBoxLayout() tools_layout = QVBoxLayout() # Create QGroupBox to have titles propobj_gb = QGroupBox('Properties and objects') tools_gb = QGroupBox('Tools (affect goal, prop. and obj.)') # Put widgets in layouts and group boxes goal_layout.addStretch() goal_layout.addWidget(goal) goal_layout.addStretch() # Add space below goal goal_layout.setContentsMargins(0, 10, 0, 30) #LTRB propobj_layout.addWidget(objects) propobj_layout.addWidget(properties) tools_layout.addLayout(logic_buttons) tools_layout.addWidget(statements) propobj_gb.setLayout(propobj_layout) tools_gb.setLayout(tools_layout) workspace_layout.addWidget(propobj_gb) workspace_layout.addWidget(tools_gb) # Don't forget me main_layout.addLayout(goal_layout) main_layout.addLayout(workspace_layout) self.setWindowTitle("L'union des images réciproque est l'image "\ "réciproque de l'union — d∃∀duction") self.setLayout(main_layout) self.show()
class CourseTreeWidget(QWidget, ABookCore): def __init__(self, path, settings, session): QWidget.__init__(self) ABookCore.__init__(self, path, settings, session) self.signal = CourseTreeWidgetSignals() self.selectedList = [] self.treeWidget = QTreeWidget() self.treeWidget.setHeaderLabels(['Name', "Course ID", "Chapter ID"]) self.treeWidget.itemChanged.connect(self.checkbox_toggled) self.treeWidget.clicked.connect(self.loadResourceList) self.addDownloadTaskButton = QPushButton("Add to Downloader") self.addDownloadTaskButton.clicked.connect(self.addDownloadTask) self.importCourseButton = QPushButton("Import Courses") self.importCourseButton.clicked.connect(self.startImportCourseWidget) main_layout = QGridLayout() main_layout.addWidget(self.treeWidget, 0, 0, 1, 2) main_layout.addWidget(self.importCourseButton, 1, 0) main_layout.addWidget(self.addDownloadTaskButton, 1, 1) main_layout.setMargin(0) self.setLayout(main_layout) if settings['first_launch'] is True: settings['first_launch'] = False self.importCourseButton.click() else: self.createTreeRoot() def createTreeRoot(self): courseList = self.getCourseList() for course in courseList: courseId = course['courseInfoId'] currentChapterList = self.getChapterList(courseId) self.createTree(self.treeWidget, 'course', course, currentChapterList, courseId) def createTree(self, parentItem, itemType, itemData, chapterList, courseId): if itemType == 'course': courseName = itemData['courseTitle'] courseId = itemData['courseInfoId'] courseItem = self.createCourseTreeItem(courseName, courseId, 'None', True) parentItem.addTopLevelItem(courseItem) childChapterList = self.getChildChapterList(chapterList, {'id': 0}) self.createTree(courseItem, 'chapter', childChapterList, chapterList, courseId) elif itemType == 'chapter': for chapter in itemData: childChapterList = self.getChildChapterList( chapterList, chapter) chapterName = chapter['name'] chapterId = chapter['id'] hasChild = len(childChapterList) > 0 chapterItem = self.createCourseTreeItem( chapterName, courseId, chapterId, hasChild) parentItem.addChild(chapterItem) if hasChild: self.createTree(chapterItem, 'chapter', childChapterList, chapterList, courseId) else: raise KeyError('Wrong TODO') def checkbox_toggled(self, node: QTreeWidgetItem, column: int): if node.checkState(column) == Qt.Checked: self.selectedList.append( [node.text(0), node.text(1), node.text(2)]) elif node.checkState(column) == Qt.Unchecked: if len(self.selectedList) > 1: self.selectedList.remove( [node.text(0), node.text(1), node.text(2)]) else: self.selectedList = [] def createCourseTreeItem(self, name: str, courseId: str, chapterId: str, hasChild: bool): item = QTreeWidgetItem() item.setText(0, str(name)) item.setText(1, str(courseId)) item.setText(2, str(chapterId)) if hasChild is True: item.setFlags(item.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) else: item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(0, Qt.Unchecked) return item def addDownloadTask(self): for item in self.selectedList: if item[1] != "None" and item[2] != "None": courseId = item[1] chapterId = item[2] downloadList = self.getResourceList(courseId, chapterId) if downloadList is not None: for resource in downloadList: fileDir, filePath, fileName, coursePath = self.getResourcePath( courseId, chapterId, resource["resourceInfoId"]) self.signal.addDownloadTask.emit( fileName, filePath, "http://abook.hep.com.cn/ICourseFiles/" + resource["resFileUrl"]) def startImportCourseWidget(self): wizard = ImportCourseWizard(self) wizard.show() def loadResourceList(self): # When triggered on click, first adjust the width of the column self.treeWidget.resizeColumnToContents(0) self.treeWidget.resizeColumnToContents(1) self.treeWidget.resizeColumnToContents(2) # Get the course_id and chapter_id courseId = self.sender().currentItem().text(1) chapterId = self.sender().currentItem().text(2) # Ignore the root nodes if courseId != "None" and chapterId != "None": # Get the resource list # resource_list = self.get_resource_info(courseId, chapterId) resourceList = self.getResourceList(courseId, chapterId) # Clear the FileListWidget self.signal.clearFileListWidget.emit() # If resource list is not empty if isinstance(resourceList, list): # Each resource item is a QStandardItem # data role -1 stores the url of the resource # data role -2 stores the url of the preview image of the resource # data role Qt.TooltipRole stores the url of the resource # data role Qt.DecorationRole stores the preview image of the resource # We need to lazy load and cache the preview image so that the main thread will not be blocked # 1. create items without the Qt.DecorationRole and add it to resourceItemList # 2. pass the resource_item_list to LoadPicWorker to cache and load resourceItemList = [] for resource in resourceList: resName = resource["resTitle"] urlBase = "http://abook.hep.com.cn/ICourseFiles/" resFileUrl = urlBase + resource["resFileUrl"] resourceItem = QStandardItem(resName) resourceItem.setData(resFileUrl, Qt.ToolTipRole) resourceItem.setData(resFileUrl, -1) resourceItem.setData(resource['picUrl'], -2) self.signal.appendRowFileListWidget.emit(resourceItem) resourceItemList.append(resourceItem) loadPicWorker = LoadPicWorker(resourceItemList, self) loadPicWorker.start()