Python Qt GUI设计:QTableView、QListView、QListWidet、QTableWidget、QTreeWidget和QTreeWidgetltem表格和树类(提升篇—1)

表格与树解决的问题是如何在一个控件中有规律地呈现更多的数据。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, QMessageBox

from 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 sys

from 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 sys

from 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 sys

from 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_())

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容