六、表格控件的使用

(七)表格控件的使用

      表格控件可以以行和列的形式表示数据,比如在需要显示车票信息、薪资收入、进销存报表、学生成绩等类似的数据时,通常都采用表格来显示,例如,在12306网站中显示火车票信息时就使用表格来显示。
      表格是界面中显示数据最常采用的一种方式,在PyQt5中使用TableWidget表示表格控件。接下来讲解如何使用表格控件显示数据库中的数据,对表格进行各种操作设置,包括内容自动填充、禁止编辑单元格、设置颜色、排序、在表格中显示图片、合并单元格等。

1. TableWidget表格控件

      PyQt5提供了两种表格控件,分别是TableWidget和TableView,其中,TableView是基于模型的,它是TableWidget的父类,使用TableView时,首先需要建立模型,然后再保存数据;而TableWidget是TableView的升级版本,它已经内置了一个数据存储模型QTableWidgetItem,我们在使用时,不必自己建立模型,而直接使用setItem()方法即可添加数据。所以在实际开发时,推荐使用TableWidget控件作为表格。
在这里插入图片描述
      由于QTableWidget类继承自QTableView,因此,它具有QTableView的所有公共方法,另外,它还提供了一些自身特有的方法。

TableWidget类的常用方法及说明

方法说明
setRowCount()设置表格的行数。
setColumnCount()设置表格的列数。
setHorizontalHeaderLabels()设置表格中的水平标题名称。
setVerticalHeaderLabels()设置单元格中的垂直标题名称。
setItem()设置每个单元格中的内容。
setCellWidget()设置单元格的内容为QWIDget控件。
resizeColumnsToContents()使表格的列的宽度跟随内容改变。
resizeRowsToContents()使表格的行的高度跟随内容改变。
setEditTriggers()
  • 设置表格是否可以编辑,取值如下:
  • QAbstractItemView.NoEditTriggers0No:不能编辑表格内容;
  • QAbstractItemView.CurrentChanged1Editing:允许对单元格进行编辑;
  • QAbstractItemView.DoubleClicked2Editing:双击时可以编辑单元格;
  • QAbstractItemView.SelectedClicked4Editing:单击时可以编辑单元格;
  • QAbstractItemView.EditKeyPressed8Editing:按修改键时可以编辑单元格;
  • QAbstractItemView.AngKeyPressed16Editing:按任意键都可以编辑单元格。
setSpan()
  • 合并单元格,该方法的4个参数如下:
  • row:要改变的单元格的行索引;
  • column:要改变的单元格的列索引;
  • rowSpanCount:需要合并的行数;
  • columnSpanCount:需要合并的列数。
setShowGrid()设置是否显示网格线,默认不显示。
setSelectionBehavior()
  • 设置表格的选择行为,取值如下:
  • QAbstractItemView.SelectItems0Selecting:选中当前单元格;
  • QAbstractItemView.SelectRows1Selecting:选中整行;
  • QAbstractItemView.DoubleClicked2Editing:选中整列。
setTextAlignment()
  • 设置单元格内文字的对齐方式,取值如下:
  • Qt.AlignLeft:与单元格左边缘对齐;
  • Qt.AlignRight:与单元格右边缘对齐;
  • Qt.AlignHCenter:单元格内水平居中对齐;
  • Qt.AlignJustify:单元格内两端对齐;
  • Qt.AlignTop:与单元格顶部边缘对齐;
  • Qt.AlignBottom:与单元格底部边缘对齐;
  • Qt.AlignVCenter:单元格内垂直居中对齐。
setAlternatingRowColors()设置表格颜色交错显示。
setColumnWidth()设置单元格的宽度。
setRowHeight()设置单元格的高度。
sortItems()
  • 设置单元格内容的排序方式,取值如下:
  • Qt.DescendingOrder:降序;
  • Qt.AscendingOrder:升序。
rowCount()获取表格中的行数;
columnCount()获取表格中的列数。
verticalHeader()获取表格的垂直标题头。
horizotalHeader()获取表格的水平标题头。

      QTableWidgetItem类表示QTableWidget中的单元格,一个表格就是由多个单元格组成的。

QTableWidgetItem类的常用方法及说明

方法说明
setText()设置单元格的文本。
setCheckSate()
  • 设置指定单元格的选中状态,取值如下:
  • Qt.Checked:单元格选中;
  • Qt.Unchecked:单元格未选中。
setIcon()为单元格设置图标。
setBackground()设置单元格的背景色。
setForeground()设置单元格内文本的颜色。
setFont()设置单元格内文本的字体。
text()获取单元格的文本。

2. 在表格中显示数据库数据

      使用TableWidget控件显示数据主要用到QTableWidgetItem类,使用该类创建表格中的单元格,并指定要显示的文本或者图标后,即可使用TableWidget对象的setItem()方法将其添加到表格中。

示例:使用表格显示MySQL数据

      创建一个.py文件,导入PyQt5中的相应模块,在该程序中,主要是用PyMySQL模块从数据库中查询数据,并将查到的数据显示在TableWidget表格中。

完整代码如下:

from PyQt5.QtWidgets import *


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(400, 180)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行程序,效果显示如下:
在这里插入图片描述

3. 隐藏垂直标题

      表格在显示数据时,默认会以编号的形式自动形成一列垂直标题,如果需要隐藏,可以使用verticalHeader()获取垂直标题,然后使用setVisible()方法将其隐藏。

示例:用setVisible()方法隐藏垂直标题

关键代码如下:

table.verticalHeader().setVisible(False)     # 隐藏垂直标题

完整代码如下:

from PyQt5.QtWidgets import *


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(520, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

在这里插入图片描述
      如果需要隐藏表格的水平标题,可以使用如下代码:

table.horizontalHeader().setVisible(False)    # 隐藏水平标题

4. 设置最后一列自动填充容器

      表格中的列默认会以默认宽度显示,但如果遇到窗口伸缩的情况,在放大窗口时,由于表格是固定的,就会造成窗口中可能会出现大面积的空白区域,影响整体的美观。在PyQt5中可以使用setstret-chlastSection()方法将表格的最后一列设置为自动伸缩列,这样就可以自动填充整个容器。

示例:设置最后一列的列宽随窗口缩放而变化

关键代码如下:

table. horizontalHeader().setStretchLastSection(True)     # 设置最后一列自动填充容器

完整代码如下:

from PyQt5.QtWidgets import *


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(520, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # 设置最后一列自动填充容器
        table.horizontalHeader().setStretchLastSection(True)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

效果如下图所示:
在这里插入图片描述

示例:设置表格所有列按比例随窗口自动缩放

      上面的代码将最后一列设置为了自动伸缩列,除此之外,还可以将整个表格设置为自动伸缩模式,这样,在放大或缩小窗口时,整个表格的所有列都会按比例自动缩放。
关键代码如下:

table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(520, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行效果如下图:
在这里插入图片描述

5. 禁止编辑单元格

示例:设置禁止编辑单元格中的内容

      当双击表格中的某个单元格时,表格中的数据默认情况下是可以编辑的,但如果只需要查看数据,则可以使用表格对象的setEditTriggers()方法将表格的单元格设置为禁止编辑状态。
关键代码如下:

table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)    # 禁止编辑单元格

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(520, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

在这里插入图片描述

6. 设置单元格的文本颜色

      使用QTableWidgetItem对象的setForeground()方法可以设置单元格内文本的颜色,其参数为一个QBrush对象,在该对象中可以使用颜色名或者RGB值来对颜色进行设置。

示例:用setForeground()方法将单元格内的文字设置为绿色

关键代码:

data.setForeground(QtGui.QBrush(QtGui.QColor("green")))     # 设置单元格文本颜色

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtGui
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(520, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
                # 设置单元格文本颜色
                data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行效果如下:
在这里插入图片描述

示例:用setBackground()方法设置单元格的背景颜色

      如果需要设置单元格的背景颜色,可以使用setBackground()方法
关键代码:

data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))    # 设置单元格背景颜色

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtGui
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(950, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
                # # 设置单元格文本颜色
                # data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
                # 设置单元格背景颜色
                data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行效果如下:
在这里插入图片描述

7. 设置指定列的排序方式

      使用QTableWidget对象的sortItems()方法,可以设置表格中指定列的排序方式。语法如下:

sortItems(column, order)

sortItems()方法的参数说明

参数说明
column一个整数数字,表示要进行排序的列索引。
order一个枚举值,指定排序方式,其中,Qt.DescendingOrder表示降序,Qt.AscendingOrder表示升序。

示例:按照“出版时间”降序(从大到小)排列表格

      将上一示例的表格内的“出版时间”一列按照降序排列,由于“出版时间”列的索引是4(索引从0开始),关键代码如下:

table.sortItems(4, QtCore.Qt.DescendingOrder)    # 设置降序排序
from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(950, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
                # # 设置单元格文本颜色
                # data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
                # 设置单元格背景颜色
                data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))
        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        # 设置降序排序
        table.sortItems(4, QtCore.Qt.DescendingOrder)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行效果于原来的对比如下:
在这里插入图片描述

8. 在指定列中显示图片

      表格除了可以显示文字,还可以显示图片,显示图片可以在创建QTableWidgetItem对象时传入QIcon图标对象实现。

示例:在“出版时间”列旁显示日历图片

      在上一示例表格中的第4列“出版时间”旁边显示一个日历图片,关键代码如下:

                if j == 4:    # 如果是第4列,则显示图片
                    data = QTableWidgetItem(QtGui.QIcon("./image/date.png"), str(result[i][j]))   # 插入图片和文字
                else:
                    data = QTableWidgetItem(str(result[i][j]))  # 直接插入文字

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(950, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                # 设置插入日历图片
                if j == 4:    # 如果是第4列,则显示图片
                    data = QTableWidgetItem(QtGui.QIcon("./image/date.png"), str(result[i][j]))   # 插入图片和文字
                else:
                    data = QTableWidgetItem(str(result[i][j]))  # 直接插入文字
                # data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                table.setItem(i, j, data)
                # # # 设置单元格文本颜色
                # # data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
                # # 设置单元格背景颜色
                # data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))

        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        # # 设置降序排序
        # table.sortItems(4, QtCore.Qt.DescendingOrder)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行效果如下:
在这里插入图片描述

9. 向指定列中添加PyQt5标准控件

      TableWidget表格不仅可以显示文字、图片,还可显示PyQt5的标准控件,实现该功能需要使用setCellWidget()方法,语法如下:

setCellWidget(row, column, QWidget)

setCellWidget()方法的参数说明

参数说明
row一个整数数字,表示要添加控件的单元格的行索引
column一个整数数字,表示要添加控件的单元格的列索引
QWidgetPyqt5标准控件

示例:将“图书分类”显示为标准控件ComboBox下拉列表

      将上面示例表格中的第2列“图书分类”显示为ComboBox下拉列表,允许用户从中选择数据。
关键代码如下:

                # 将下标第2列设置为ComboBox下拉列表
                if j == 2:       # 判断是否为第2列
                    combobox = QComboBox()      # 创建一个下拉列表对象
                    # 为下拉列表设置数据源
                    combobox.addItems(["Python", "Java", "C语言", ".NET"])
                    combobox.setCurrentIndex(0)    # 设置默认选中第一项
                    table.setCellWidget(i, 2, combobox)     # 将创建的下拉列表显示在表格中
                else:
                    data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                    table.setItem(i, j, data)

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(950, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                # 在下标第4列设置插入日历图片
                if j == 4:    # 如果是第4列,则显示图片
                    data = QTableWidgetItem(QtGui.QIcon("./image/date.png"), str(result[i][j]))   # 插入图片和文字
                else:
                    data = QTableWidgetItem(str(result[i][j]))  # 直接插入文字
                # data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格

                # 将下标第2列设置为ComboBox下拉列表
                if j == 2:       # 判断是否为第2列
                    combobox = QComboBox()      # 创建一个下拉列表对象
                    # 为下拉列表设置数据源
                    combobox.addItems(["Python", "Java", "C语言", ".NET"])
                    combobox.setCurrentIndex(0)    # 设置默认选中第一项
                    table.setCellWidget(i, 2, combobox)     # 将创建的下拉列表显示在表格中
                else:
                    data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                    table.setItem(i, j, data)
                # table.setItem(i, j, data)

                # # # 设置单元格文本颜色
                # # data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
                # # 设置单元格背景颜色
                # data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))

        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        # # 设置降序排序
        # table.sortItems(4, QtCore.Qt.DescendingOrder)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

运行效果如下:
在这里插入图片描述
      通过使用setCellWidget()方法可以向表格中添加任何PyQt5标准控件,例如,在实际项目开发中常见的“查看详情”“编辑”“删除”按钮、指示某行是否选中的复选框等。

10. 合并指定单元格

      在实际项目开发中,经常遇到合并单元格的情况。在上面示例中,有部分图书额价格相同、有的出版时间相同、也有的图书分类相同,遇到类似的情况,就可将显示相同数据的单元格进行合并。
      在PyQt5中合并表格的单元格,需要使用setSpan()方法,该方法的语法如下:

setSpan(row, column, rowSpanCount, columnSpanCount)

setSpan()方法的参数说明

参数说明
row一个整数数字,表示要改变的单元格的行索引
column一个整数数字,表示要改变的单元格的列索引
rowSpanCount一个整数数字,表示需要合并的行数。
columSpanCount一个整数数字,表示需要合并的列数。

示例:将相同数据的单元格进行合并

关键代码如下:

        # 合并相同数据单元格
        # 合并第3列的第1-5行
        # (0表示第1行,2表示第3列,5表示跨越5行<1、2、3、4、5行>,1表示跨越1列)
        table.setSpan(0, 2, 5, 1)
        # (2表示第2行,3表示第4列,3表示跨越3行<3、4、5行>,1表示跨越1列)
        table.setSpan(2, 3, 3, 1)
        # (2表示第3行,4表示第5列,3表示跨越3行<3、4、5行>,1表示跨越1列)
        table.setSpan(2, 4, 3, 1)

完整代码如下:

from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore
from PyQt5 import QtWidgets


class Demo(QWidget):
    def __init__(self, parent=None):
        super(Demo, self).__init__(parent)
        self.initUi()        # 初始化窗口

    def initUi(self):
        self.setWindowTitle("使用表格显示数据库中的数据")
        self.resize(950, 320)    # 设置窗口大小
        vhayout = QHBoxLayout()     # 创建水平布局
        table = QTableWidget()   # 创建表格

        import pymysql
        # 打开数据库连接
        db = pymysql.connect(host="localhost", user="root", password="123456", database="mrsoft", charset="utf8")
        cursor = db.cursor()     # 使用cursor()方法获取操作游标
        cursor.execute("select * from books")    # 执行SQL语句
        result = cursor.fetchall()    # 获取所有记录
        row = cursor.rowcount      # 取得记录个数,用于设置表格的行数
        vol = len(result[0])    # 取得字段个数,用于设置表格的列数
        cursor.close()      # 关闭游标
        db.close()     # 关闭连接

        table.setRowCount(row)     # 设置表格行数
        table.setColumnCount(vol)    # 设置表格列数
        table.setHorizontalHeaderLabels(["ID", "图书名称", "图书分类", "图书价格", "出版时间"])    # 设置表格的标题名称
        for i in range(row):     # 遍历行
            for j in range(vol):    # 遍历列
                # 在下标第4列设置插入日历图片
                if j == 4:    # 如果是第4列,则显示图片
                    data = QTableWidgetItem(QtGui.QIcon("./image/date.png"), str(result[i][j]))   # 插入图片和文字
                else:
                    data = QTableWidgetItem(str(result[i][j]))  # 直接插入文字
                # data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格

                # # 将下标第2列设置为ComboBox下拉列表
                # if j == 2:       # 判断是否为第2列
                #     combobox = QComboBox()      # 创建一个下拉列表对象
                #     # 为下拉列表设置数据源
                #     combobox.addItems(["Python", "Java", "C语言", ".NET"])
                #     combobox.setCurrentIndex(0)    # 设置默认选中第一项
                #     table.setCellWidget(i, 2, combobox)     # 将创建的下拉列表显示在表格中
                # else:
                #     data = QTableWidgetItem(str(result[i][j]))     # 转换后可插入表格
                #     table.setItem(i, j, data)
                table.setItem(i, j, data)

                # # # 设置单元格文本颜色
                # # data.setForeground(QtGui.QBrush(QtGui.QColor("green")))
                # # 设置单元格背景颜色
                # data.setBackground(QtGui.QBrush(QtGui.QColor("yellow")))

        table.resizeColumnsToContents()    # 使列宽跟随内容改变
        table.resizeRowsToContents()    # 使行高跟随内容改变
        table.setAlternatingRowColors(True)     # 使表格颜色交错显示
        vhayout.addWidget(table)     # 将表格添加倒水平布局中
        self.setLayout(vhayout)     # 设置当前窗口的布局方式

        # 隐藏垂直标题
        table.verticalHeader().setVisible(False)
        # # 设置最后一列自动填充容器
        # table.horizontalHeader().setStretchLastSection(True)

        table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        # 禁止编辑单元格
        table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        # # 设置降序排序
        # table.sortItems(4, QtCore.Qt.DescendingOrder)
        # 合并相同数据单元格
        # 合并第3列的第1-5行
        # (0表示第1行,2表示第3列,5表示跨越5行<1、2、3、4、5行>,1表示跨越1列)
        table.setSpan(0, 2, 5, 1)
        # (2表示第2行,3表示第4列,3表示跨越3行<3、4、5行>,1表示跨越1列)
        table.setSpan(2, 3, 3, 1)
        # (2表示第3行,4表示第5列,3表示跨越3行<3、4、5行>,1表示跨越1列)
        table.setSpan(2, 4, 3, 1)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)     # 创建窗口程序
    demo = Demo()      # 创建窗口类对象
    demo.show()
    sys.exit(app.exec_())

合并后的效果如下图:
在这里插入图片描述

原本的效果如下图:
在这里插入图片描述

表格控件总览:   在VB开发环境中,表格控件在界面开发元素中占有重要的地位。它不仅有外观整洁、表达形式规范的优点,而且更重要的是它较高的信息表现率(就是相对于其他控件来说能够表达更多的信息),随着信息时代的到来,它的应用将更加的广泛。    那么在VB平台下,如何操作这一功能强大的控件元素呢?事实上我们知道,VB平台下面的表格控件是相当丰富的,总结下来提供了4种类型:Microsoft Data Bound grid Control、Microsoft Datagrid Control、Microsoft Flexgrid Control、Microsoft Hierarchial Flexgrid Control. 这四种表格各有其特点,下面我们一一讨论。   1. Microsoft Data Bound grid Control   此控件主要用于数据绑定(可以不绑定,但是因为不提供对单个cell的控制支持,所以实际上这样做是不经济的)。具体说来,就是数据源比较固定的情况下可以使用这种控件。   具体使用方法是设定此控件的datasource属性,就可以不用编写任何代码就可以显示该数据源所指向的记录数据。比如可以将datasource设置为一个data控件,而data控件又指向数据库"成绩"的 一个"语文"表,那么当程序运行时,它就自动显示此"语文"表的数据。 基本步骤如下: 1、向工程上添加Microsoft Data Bound Grid Control控件,即DBGrid控件。 2、在窗体上添加DBGrid控件DBGrid1和Data控件Data1。 3、设置Data1的DatabaseName属性为你要看的数据库的名字。 4、设置Data1的RecordSource属性为表的名字或合法的SQL Select语句。 5、设置DBGrid1的DataSource属性为Data1。   从上面的分析看得出来,这个控件虽然操作方便,但是它也有局限性,就是不能对显示的数据进行灵活的控制操作,比如有些数据允许用户修改,有些数据却不允许用户修改,而此控件却只能提供全部数据源的原子操作:即要么全部允许修改,要么就全部不允许。还有另外此控件也不提供对单个单元格(cell)进行操作,所以提供不了更为个性化的界面风格。   2. Microsoft Datagrid Control   此控件跟前面介绍的Data Bound grid Control控件很相似,也是主要进行绑定操作,而缺点和Data Bound grid Control完全一样。但是它跟Data Bound grid Control不一样的是其数据源的驱动引擎只能是OLEDB形式的,不能是DAO,比如就可以使用ADO数据控件,不能使用DATA控件。而Data Bound grid Control却刚好和它相反,这一点在开发中一定要注意。   3. Microsoft Flexgrid Control与Microsoft Hierarchial Flexgrid Control.   这里重点介绍这两种控件,因为在实际开发中,这两种控件应用的场合更多一些,它不仅能够反映数据,而且也能把数据的修改信息反映到数据库中去,所以弥补了上述两种控件的不足。   如果数据不需要修改,那么可以进行绑定操作,其方法跟前面介绍的完全一样,就是通过设置DataSource属性来完成数据的显示工作。但是实际开发中,需要对整个表格控件更为灵活的显示控制。   在给出例程之前,有必要对这一控件进行比较详尽的认识:这种控件允许将文本或者图象放置于每个单元格之中,控件的Row与Col属性允许用户在代码中指定当前行和列,当然也可通过操作鼠标和键盘来改变这两个属性,而text属性指明当前单元格的文本。如果单元格的文本太长而不能完全显示出来的话,可以通过将WordWrap属性设置为true来达到显示的目的。下面将比较重要的属性小结如下:   DataSource---------用来指定需要绑定的数据源,比如data控件。   Cellpicture----------用来设定当前单元格的图象,便于显示该图象。此属性不能在设计时使用。   Col,Row---------------设定当前列和当前行,注意它们均是从0开始的,如果同时设定它们,可以指定当前的单元格。设计时也不能使用。   Cols,Rows---------------设置表格控件总的列数和行数。   Hwnd---------------表格句柄,可以结合Windows API对表格控件进行更高级的控制。   Text---------------指定当前的单元格的文本内容。   TextMatrix(i,j)-------此属性比较重要,它用来指定第I行和第j列所确定的单元格的文本内容。它等价于下面的代码: MSHFlexGrid1.Rows =i MSHFlexGrid1.Cols =j MSHFlexGrid1.Text =指定的字符串   WordWrap-------为ture时可以在当前单元格换行显示,否则如果要显示的字符的长度超过列宽,那么就不能显示完全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值