高级组件不是说这个组件有多”高级”的意思,而是表示功能强大的意思。如要实现一个功能完整的表格功能,可能需要花上好几天,编写好多代码才能实现,而直接调用wx.Grid组件,三两下就搞定了,所以说这个组件很高级。

PyQt5常用的高级组件有表格视图控件QTableView和QTableWidget、列表视图QList

View和QListWidget,树状结构QTreeWidget和标签视图QTabWidget。

表格视图控件QTableView需要和数据模型配套使用。表格的数据模型,需要填上每一行每一列的数据,就像execl表格一样。

QTableView是基于MVC模式设计的,M(Model)是数据模型,V(view)是指QTableView视图,用来显示数据模型,C(controllor)是控制器,与View合并到一起了。通过setModel()方法绑定数据源。它常用方法如下表所示:

方法

描述

setSpan(int, int, int, int)

合并行列,4个参数分别是起始行、起始列、合并行数和列表;

clearSpans()

清除所有合并的单元格(取消合并);

setSelectionBehavior()

值为
QAbstractItemView.SelectRows时,将按行选中,而不是默认的可选中所有行;

setSelectionModel()

值为
QAbstractItemView.SingleSelection时,将按单元格选中,而不是默认的可选中所有行;

setEditTriggers()

值为QTableView.NoEditTriggers时,将单元格置为不可编辑;

hideColumn(int column)

隐藏指定的列;

showColumn(int column)

显示指定的列;

hideRow(int row)

隐藏指定的行;

showRow(int row)

显示指定的行;

horizontalHeader()

返回水平表头对象,调用setSectionResizeMode(QHeaderView.Stretch)时,所有列平均分配;调用setStretchLastSection(True)时,最后一列自动拉伸。

isColumnHidden(int column)

返回bool值,表示列是否处于隐藏状态;

isRowHidden(int row)

返回bool值,表示行是否处于隐藏状态;

resizeColumnToContents(int column)

根据内容调整指定列的列宽,column为列的下标,从0开始;

resizeColumnsToContents()

根据内容调整所有列的列宽;

resizeRowToContents(int row)

根据内容调整指定行的行高,row为行的下标,从0开始;

resizeRowsToContents()

根据内容调整所有行的行高;

sortByColumn(int column,

SortOrder order)

对column进行排序,排序方式由order指定, Qt.DescendingOrder降序,Qt.AscendingOrder升序;

setModel(QAbstractItemModel)

绑定模型数据。

表格视图控件QTableView可以绑定的模型数据如下表所示:

模型名称

描述

QStringListModel

储存一组字符串;

QStandardItemModel

存储任意层次结构的数据;

QDirModel

对文件系统进行封装;

QSqlQueryModel

对SQL的查询结果集进行封装;

QSqlTableModel

对SQL中的表格进行封装;

QSqlRelationalTableModel

对带有foreign key的SQL表格进行封装。

模型的常用方法如下表所示:

方法

描述

setHorizontalHeaderLabels([str] labels)

用于一次性顺序设置水平表头多个节显示的文本,该方法无返回值。设置了标签的节自动会创建该节对应的项;

setVerticalHeaderLabels([str] labels)

用于一次性顺序设置垂直表头多个节显示的文本,该方法无返回值。设置了标签的节自动会创建该节对应的项;

setItem()

向模板里添加item;

appendRow()

添加QStandItem数据;

findItems(str,Qt.MatchExactly,

int column)

在指定列里查找数据,返回List;

removeRows(int row)

删除指定行的数据;

data(QModelIndex index)

获取单元格的值;

columnCount()

获取总列数;

程序清单:table.py

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget,
  QHBoxLayout, QTableView, QAbstractItemView
from PyQt5.QtGui import QStandardItemModel, QStandardItem, 
  QBrush, QColor
from PyQt5.QtCore import Qt


# 继承QWidget
class TableViewWidget(QWidget):
    customer_list = [("张三", "男", "1981-06-02", "13888888888",
                      "南极路企鹅临舍傍9号999路"),
                     ("李四", "男", "1988-08-08", "13999999999",
                      "北极熊店的下坡路中6号666路"),
                     ("李清照", "女", "1986-06-06", "13666666666",
                      "秦岭古诗庙湾道8号888路")]
    itemModel = None

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 设置布局
        layout = QHBoxLayout()
        table_view = QTableView(self)
        # 数据层次结构,10行5列
        self.itemModel = QStandardItemModel(10, 5)
        # 表头
        self.itemModel.setHorizontalHeaderLabels(["姓名", "性别", "生日", 
                                                  "手机号", "地址"])
        # 输入内容
        for (row, customer) in enumerate(self.customer_list):
            for column in range(len(customer)):
                self.itemModel.setItem(row, column, 
                                       QStandardItem(customer[column]))
        # 绑定数据源
        table_view.setModel(self.itemModel)
        # 最后一列自动拉伸
        table_view.horizontalHeader().setStretchLastSection(True)
        items = self.itemModel.findItems("13666666666", 
                                         Qt.MatchExactly, 3)
        # 设置单元格的背脊颜色为红
        if len(items) > 0:
            items[0].setForeground(QBrush(QColor(255, 0, 0)))
        layout.addWidget(table_view)
        # 合并行列
        table_view.setSpan(0, 1, 2, 1)
        # 单元格不可编辑
        table_view.setEditTriggers(QTableView.NoEditTriggers)
        # 选择单行
        table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        # 单击事件
        table_view.clicked.connect(self.table_click)
        # 双击事件
        table_view.doubleClicked.connect(self.double_click)
        self.setLayout(layout)
        # 调整窗口大小
        self.resize(900, 500)
        # 窗口居中
        self.center()
        # 窗口标题
        self.setWindowTitle("表格应用")
        # 显示窗口
        self.show()
        # 获取文件夹路径

    def table_click(self, model_index):
        # 选中行和列的下标
        row = model_index.row()
        column = model_index.column()
        item = self.itemModel.index(row, column).data()
        print("选中单元格的值:%s" % item)
        # 选中单元格的值
        column_data = self.itemModel.data(model_index)
        print("选中单元格的值:%s" % column_data)
        # 总列数
        column_count = self.itemModel.columnCount()
        for i in range(column_count):
            # 根据行列获取单元格里的值
            item = self.itemModel.index(row, i).data()
            print(item, end=" ")

    def double_click(self, model_index):
        # 选中单元格的值
        column_data = self.itemModel.data(model_index)
        print(column_data)

    # 实现居中
    def center(self):
        f = self.frameGeometry()
        c = QDesktopWidget().availableGeometry().center()
        f.moveCenter(c)
        self.move(f.topLeft())


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = TableViewWidget()
    sys.exit(app.exec_())

运行程序之后,弹出的窗口如下:

python QWidget 绘制图片 python qtableview_跨平台

好了,QTableView的内容就说到这了,关注我,下一节更精彩。