Python Qt GUI设计:表格和树类(提升篇—1)

共 8237字,需浏览 17分钟

 ·

2021-12-16 22:04

点击上方蓝色字体,关注我们


表格与树解决的问题是如何在一个控件中有规律地呈现更多的数据。PyQt提供了两种控件类用于解决该问题,其中一种是表格结构的控件类,另一种是树形结构的控件类。



1


QTableView类



在通常情况下,一个应用需要和一批数据(比如数组、列表)进行交互,然后以表格的形式输出这些信息,这时就要用到QTableView类了。在QtableView中可以使用自定义的数据模型来显示内容,通过setModel来绑定数据源。


QTableWidget继承自QTableView,主要区别是QTableView可以使用自定义的数据模型来显示内容(先要通过setModel来绑定数据源),而QTableWidget只能使用标准的数据模型,并且其单元格数据是通过QTableWidgetltem对象来实现的。通常使用QTableWidget就能够满足我们的要求。


QTableView控件可以绑定一个模型数据用来更新控件上的内容,可用的模式如下表所示:



通过示例了解QTableView类的使用方法,效果如下所示:



实现代码如下所示:


from PyQt5.QtWidgets import *from PyQt5.QtGui import *from PyQt5.QtCore import *import sys
class Table(QWidget):
def __init__(self, arg=None): super(Table, self).__init__(arg) self.setWindowTitle("QTableView表格视图控件的例子") self.resize(500,300); self.model=QStandardItemModel(4,4); self.model.setHorizontalHeaderLabels(['标题1','标题2','标题3','标题4'])
for row in range(4): for column in range(4): item = QStandardItem("row %s, column %s"%(row,column)) self.model.setItem(row, column, item)
self.tableView=QTableView() self.tableView.setModel(self.model) #下面代码让表格100填满窗口 #self.tableView.horizontalHeader().setStretchLastSection(True) #self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) dlgLayout=QVBoxLayout(); dlgLayout.addWidget(self.tableView) self.setLayout(dlgLayout)
if __name__ == '__main__': app = QApplication(sys.argv) table = Table() table.show() sys.exit(app.exec_())



2


QListView类



QListView类用于展示数据,它的子类是QListWidget类。QListView是基于模型(Model)的,需要程序来建立模型,然后再保存数据。


QListWidget是一个升级版本的QListView,它已经建立了一个数据存储模(QListWidgetltem),直接调用addltem()函数,就可以添加条目(ltem)。


QListView类中的常用方法如下表所示:



QListView类中的常用信号如下表所示: 



通过示例了解QListView类的使用方法,效果如下所示:



示例中,将QListView控件的clicked信号与自定义对象的clicked()槽函数进行绑定,当单击QListView控件里Model中的一项时会弹出消息框(提示选择的是哪─项)。


实现代码如下所示:


from PyQt5.QtWidgets import QApplication, QWidget , QVBoxLayout , QListView, QMessageBoxfrom PyQt5.QtCore import QStringListModel  import sys  
class ListViewDemo(QWidget): def __init__(self, parent=None): super(ListViewDemo, self).__init__(parent) self.setWindowTitle("QListView 例子") self.resize(300, 270) layout = QVBoxLayout()
listView = QListView() slm = QStringListModel(); self.qList = ['Pyhon语言','C语言','C++语言','Java语言' ] slm.setStringList(self.qList) listView.setModel(slm ) listView.clicked.connect(self.clicked) layout.addWidget( listView ) self.setLayout(layout)
def clicked(self, qModelIndex): QMessageBox.information(self, "QListView", "你选择了: "+ self.qList[qModelIndex.row()])
if __name__ == "__main__": app = QApplication(sys.argv) win = ListViewDemo() win.show() sys.exit(app.exec_())



3


QListWidet类



QListWidet类是一个基于条目的接口,用于从列表中添加或删除条目。列表中的每个条目都是一个QListWidgetltem对象。QListWidget可以设置为多重选择。


QListWidget类中的常用方法如下表所示:



QListWidget类中的常用信号如下表所示:



通过示例了解QListWidget类的使用方法,效果如下所示:



示例中, 将QListWidget控件的itemClicked信号与自定义对象的Clicked()槽函数进行绑定,当单击QListWidget列表中的一个条目时会弹出消息框,提示选择的是哪个条目。


实现代码如下所示:


import sysfrom PyQt5.QtCore import *from PyQt5.QtGui import *from PyQt5.QtWidgets import *
class ListWidget(QListWidget): def clicked(self,item): QMessageBox.information(self, "ListWidget", "你选择了: "+item.text())
if __name__ == '__main__': app = QApplication(sys.argv) listWidget = ListWidget() listWidget.resize(300,120) listWidget.addItem("Pyhon语言"); listWidget.addItem("C语言"); listWidget.addItem("C++语言"); listWidget.addItem("Java语言"); listWidget.setWindowTitle('QListwidget 例子') listWidget.itemClicked.connect(listWidget.clicked) listWidget.show() sys.exit(app.exec_())



4


QTableWidget类



QTableWidget是Qt程序中常用的显示数据表格的空间,类似于C#中的DataGrid。QTableWidget是QTableView的子类,它使用标准的数据模型,并且其单元格数据是通过QTableWidgetltem 对象来实现的。使用QTableWidget时就需要QTableWidgetltem,用来表示表格中的一个单元格,整个表格就是用各单元格构建起来的。


QTableWidget类中的常用方法如下表所示:



编辑规则的枚举值类型如下表所示:



表格的选择行为的枚举值类型如下表所示:



单元格文本的水平对齐方式如下表所示:



单元格文本的垂直对齐方式如下表所示:



如果要设置水平和垂直对齐方式,比如在表格空间内上、下、左、右居中对齐,那么只要使用Qt.AlignHCenter和Qt.AlignVCenter 即可。


通过示例了解QTableWidget类的使用方法,效果如下所示:



示例中, 构造了一个QTableWidget对象,并且设置表格为4行3列。生成了一个QTableWidgetltem对象,名称为“不脱发的程序猿”。


实现代码如下所示:


import sysfrom PyQt5.QtWidgets import (QWidget, QTableWidget, QHBoxLayout, QApplication, QTableWidgetItem, QAbstractItemView  )
class Table(QWidget): def __init__(self): super().__init__() self.initUI()
def initUI(self): self.setWindowTitle("QTableWidget 例子") self.resize(430,230); conLayout = QHBoxLayout() tableWidget = QTableWidget() tableWidget.setRowCount(4) tableWidget.setColumnCount(3) conLayout.addWidget(tableWidget )
tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)'])
newItem = QTableWidgetItem("不脱发的程序猿") tableWidget.setItem(0, 0, newItem)
newItem = QTableWidgetItem("男") tableWidget.setItem(0, 1, newItem)
newItem = QTableWidgetItem("65") tableWidget.setItem(0, 2, newItem)
# 将表格变为禁止编辑 #tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
# 设置表格为整行选择 #tableWidget.setSelectionBehavior( QAbstractItemView.SelectRows)
# 将行和列的大小设为与内容相匹配 #tableWidget.resizeColumnsToContents() #tableWidget.resizeRowsToContents()
#表格表头的显示与隐藏 #tableWidget.verticalHeader().setVisible(False) #tableWidget.horizontalHeader().setVisible(False)
# 不显示表格单元格的分割线 #tableWidget.setShowGrid(False) # 不显示垂直表头 tableWidget.verticalHeader().setVisible(False)
self.setLayout(conLayout)
if __name__ == '__main__': app = QApplication(sys.argv) example = Table() example.show() sys.exit(app.exec_())



5


QTreeWidget和QTreeWidgetltem类



QTreeWidget类实现了树形结构,效果如下图所示:



QTreeWidget类中的常用方法如下表所示:



QTreeWidgetltem类中的常用方法如下表所示:



通过示例了解QTreeWidget和QTreeWidgetltem类的使用方法,效果如下所示:



示例中,实现树形结构节点的添加、修改和删除, 实现代码如下所示:


import sysfrom PyQt5.QtWidgets import *#from PyQt5.QtGui import QIcon ,  QBrush , QColor#from PyQt5.QtCore import Qt 
class TreeWidgetDemo(QWidget): def __init__(self,parent=None): super(TreeWidgetDemo,self).__init__(parent) self.setWindowTitle('TreeWidget 例子')
operatorLayout = QHBoxLayout() addBtn = QPushButton("添加节点") updateBtn = QPushButton("修改节点") delBtn = QPushButton("删除节点") operatorLayout.addWidget(addBtn) operatorLayout.addWidget(updateBtn) operatorLayout.addWidget(delBtn) # 按钮的信号槽连接 addBtn.clicked.connect(self.addTreeNodeBtn ) updateBtn.clicked.connect(self.updateTreeNodeBtn ) delBtn.clicked.connect(self.delTreeNodeBtn )
self.tree = QTreeWidget(self) # 设置列数 self.tree.setColumnCount(2) # 设置头的标题 self.tree.setHeaderLabels(['Key','Value']) root= QTreeWidgetItem(self.tree) root.setText(0,'root') root.setText(1,'0')
child1 = QTreeWidgetItem(root) child1.setText(0,'child1') child1.setText(1,'1')
child2 = QTreeWidgetItem(root) child2.setText(0,'child2') child2.setText(1,'2')
child3 = QTreeWidgetItem(root) child3.setText(0,'child3') child3.setText(1,'3')
child4 = QTreeWidgetItem(child3) child4.setText(0,'child4') child4.setText(1,'4')
child5 = QTreeWidgetItem(child3) child5.setText(0,'child5') child5.setText(1,'5')
self.tree.addTopLevelItem(root) self.tree.clicked.connect( self.onTreeClicked )
mainLayout = QVBoxLayout(self); mainLayout.addLayout(operatorLayout); mainLayout.addWidget(self.tree); self.setLayout(mainLayout)
def onTreeClicked(self, qmodelindex): item = self.tree.currentItem() print("key=%s ,value=%s" % (item.text(0), item.text(1)))
def addTreeNodeBtn(self): print('--- addTreeNodeBtn ---') item = self.tree.currentItem() node = QTreeWidgetItem(item) node.setText(0,'newNode') node.setText(1,'10')

def updateTreeNodeBtn(self): print('--- updateTreeNodeBtn ---') item = self.tree.currentItem() item.setText(0,'updateNode') item.setText(1,'20')

def delTreeNodeBtn(self): print('--- delTreeNodeBtn ---') item = self.tree.currentItem() root = self.tree.invisibleRootItem() for item in self.tree.selectedItems(): (item.parent() or root).removeChild(item)
if __name__ == '__main__': app = QApplication(sys.argv) tree = TreeWidgetDemo() tree.show() sys.exit(app.exec_())


往期推荐



点击阅读原文,更精彩~
浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报