前言
首先为上周的博文鸽掉而毫无诚意地道个歉,汪汪。上周的文章先记在账上,之后慢慢补。
因为工作和生活的变动,移居到了另一个城市,各种辛苦就不说了,目前总算是告一段落,也算是个新的开始,加油。
今天继续来说一下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_()
效果如下:
这些都是比较基础的用法,但长时间不用总是难免生疏,查找资料也比较费劲,故整理出来,留作笔记。
没有被听见,
不是沉默的理由。
《悲惨世界》
——维克多·雨果
评论
638553 614524I notice there is undoubtedly lots of spam on this blog. Do you require aid cleaning them up? I may well aid between courses! 107736
818603 844527magnificent points altogether, you simply gained a emblem new reader. 647018
707290 963744Outstanding blog here! Moreover your internet internet site rather a lot up quickly! What host are you making use of? Can I get your affiliate hyperlink for your host? I wish my site loaded up as fast as yours lol. 361618
388070 303364hello I was very impressed with the setup you used with this web site. I use blogs my self so good job. definatly adding to bookmarks. 219553
819153 947450I discovered your blog internet site website on google and appearance some of your early posts. Preserve up the excellent operate. I just extra increase Feed to my MSN News Reader. Seeking for toward reading far much more by you later on! 899026