前言
首先为上周的博文鸽掉而毫无诚意地道个歉,汪汪。上周的文章先记在账上,之后慢慢补。
因为工作和生活的变动,移居到了另一个城市,各种辛苦就不说了,目前总算是告一段落,也算是个新的开始,加油。
今天继续来说一下PyQt的常用控件之QTreeWidget和QTreeView,两者的区别与QList相同就不赘述了,直接到使用环节。
QTree控件有可以有多层嵌套,经常会用在有层级或者父子关系的数据展示中,例如文件路径、部门层级、省市地区等等。
QTreeWidget
QTreeWidget的使用很简单,代码如下:
from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "QTreeWidget.ui"), self) self.initUI() self.bindEvent() def initUI(self): self.treeWidget.setColumnCount(2) self.treeWidget.setColumnWidth(0,400) self.treeWidget.setHeaderLabels(["name", "msg"]) def bindEvent(self): self.pushButton_1.clicked.connect(self.add) self.pushButton_2.clicked.connect(self.remove) self.treeWidget.clicked.connect(self.click) # add Item def add(self): root = QtWidgets.QTreeWidgetItem() root.setText(0, "zhangsan") root.setIcon(0, QtGui.QIcon("./logo.png")) root.setCheckState(0, QtCore.Qt.Checked) child1 = QtWidgets.QTreeWidgetItem() child1.setText(0, "zhangsan1") child1.setIcon(0, QtGui.QIcon("./logo.png")) child1.setCheckState(0, QtCore.Qt.Checked) root.addChild(child1) child2 = QtWidgets.QTreeWidgetItem() child2.setText(0, "zhangsan2") child2.setText(1, "法外狂徒") child2.setIcon(0, QtGui.QIcon("./logo.png")) child2.setCheckState(0, QtCore.Qt.Checked) child1.addChild(child2) self.treeWidget.addTopLevelItem(root) # remove item def remove(self): item = self.treeWidget.currentItem() parent = item.parent() if not parent: rootIndex = self.treeWidget.indexOfTopLevelItem(item) self.treeWidget.takeTopLevelItem(rootIndex) else: parent.removeChild(item) # Item Clicked def click(self): item = self.treeWidget.currentItem() self.label.setText("key=%s,value=%s"%(item.text(0),item.text(1))) app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
效果如下:

如上图,层级之间为包含关系,有复选框及图标,可以方便地添加和删除以及获取数据。
常用的样式表如下:
QTreeWidget {background-color:#2b2b2b;} QTreeWidget::item:selected,QTreeWidget::item:hover {background-color:#fa8c16;border: none;} QHeaderView::section {background-color: #5d5d5d;} QTreeWidget::branch {color: #bbbbbb; }
QTreeView
接下来就要说一说前文中提到的QDirModel,不过实际使用中更多的会用到QFileSystemModel,相比起来,后者的优点是异步处理,在处理大量数据时不会造成UI阻塞。
示例代码如下:
from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "QTreeView.ui"), self) self.initUI() self.bindEvent() def initUI(self): self.model = QtWidgets.QFileSystemModel() # QtWidgets.QDirModel dirpath = "C:/Anaconda3" self.model.setRootPath(dirpath) self.model.setNameFilters(["*.py"]) self.model.setNameFilterDisables(False) self.treeView.setModel(self.model) self.treeView.setRootIndex(self.model.index(dirpath)) self.treeView.setColumnWidth(0, 400) def bindEvent(self): self.treeView.clicked.connect(self.click) # Item Clicked def click(self,QModelIndex): self.label.setText("path=%s,name=%s,size=%s"%(self.model.filePath(QModelIndex),self.model.fileName(QModelIndex),self.model.fileInfo(QModelIndex).size())) app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
效果如下:

这就是一个常用的文件浏览器的界面。
QTreeView的常用样式如下:
QTreeView {background-color:#2b2b2b;} QTreeView::item:selected,QTreeView::item:hover {background-color:#fa8c16;border: none;} QHeaderView::section {background-color: #5d5d5d;} QTreeView::branch {color: #bbbbbb; }
如果要用QTreeView实现上面QTreeWidget呢,当然也可以通过QStandardItemModel轻松地实现,代码如下:
from Qt import QtCore, QtWidgets, QtGui from Qt.QtCompat import load_ui, QFileDialog class testPanel(QtWidgets.QWidget): def __init__(self): super(testPanel, self).__init__() DIR, file_name = os.path.split(os.path.abspath(__file__)) load_ui(os.path.join(DIR, "QTreeView.ui"), self) self.initUI() self.bindEvent() def initUI(self): self.model = QtGui.QStandardItemModel() self.treeView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) self.treeView.setModel(self.model) self.model.setHorizontalHeaderLabels(["name", "msg"]) self.model.setColumnCount(2) self.treeView.setAutoScroll(True) self.treeView.setColumnWidth(0, 400) def bindEvent(self): self.pushButton_1.clicked.connect(self.add) self.pushButton_2.clicked.connect(self.remove) self.treeView.selectionModel().selectionChanged.connect(self.selectionChanged) # add Item def add(self): icon = QtGui.QIcon('./logo.png') item1 = QtGui.QStandardItem(icon, "zhangsan1") item1.setCheckState(QtCore.Qt.Checked) self.model.appendRow([item1]) item2 = QtGui.QStandardItem(icon, "zhangsan2") item2.setCheckState(QtCore.Qt.Checked) item1.appendRow([item2]) item3 = QtGui.QStandardItem(icon, "zhangsan3") item3.setCheckState(QtCore.Qt.Checked) item3_1 = QtGui.QStandardItem("法外狂徒") item2.appendRow([item3,item3_1]) self.model.sort(0) # remove item def remove(self): index = self.treeView.currentIndex() if index: self.model.removeRow(index.row(), index.parent()) # Item Change def selectionChanged(self,QModelIndex): indexs = self.treeView.selectedIndexes() if indexs: item = self.model.itemFromIndex(indexs[0]) self.label.setText("name=%s,msg=%s"%(item.text(),indexs[0].sibling(indexs[0].row(), 1).data())) app = QtWidgets.QApplication(sys.argv) mt = testPanel() mt.show() app.exec_()
效果如下:

这些都是比较基础的用法,但长时间不用总是难免生疏,查找资料也比较费劲,故整理出来,留作笔记。
没有被听见,
不是沉默的理由。
《悲惨世界》
——维克多·雨果


评论
417634 208178It is really a nice and beneficial piece of information. Im glad that you just shared this valuable info with us. Please keep us informed like this. Thanks for sharing. 735640
535838 879754Spot lets start work on this write-up, I truly believe this remarkable website requirements additional consideration. Ill a lot more likely be once once again you just read additional, thank you that data. 986893
507765 440094Basically a smiling visitant here to share the really like (:, btw outstanding pattern . 110247