Six, the use of form controls

(7) Use of form controls

      Table controls can represent data in the form of rows and columns. For example, when it is necessary to display ticket information, salary income, invoicing reports, student grades and other similar data, tables are usually used to display them. For example, trains are displayed on the 12306 website Use a table to display the ticket information.
      Tables are the most common way to display data in the interface. In PyQt5, TableWidget is used to represent table controls. Next, I will explain how to use the table control to display the data in the database, and perform various operation settings on the table, including automatic content filling, prohibiting cell editing, setting colors, sorting, displaying pictures in the table, merging cells, etc.

1. TableWidget form control

      PyQt5 provides two table controls, namely TableWidget and TableView. Among them, TableView is based on the model, which is the parent class of TableWidget. When using TableView, you first need to build a model and then save the data; and TableWidget is an upgraded version of TableView. , it has a built-in data storage model QTableWidgetItem , when we use it, we don't have to build the model ourselves, but directly use the setItem() method to add data. Therefore, in actual development, it is recommended to use the TableWidget control as a table.
insert image description here
      Since the QTableWidget class inherits from QTableView, it has all the public methods of QTableView, and it also provides some unique methods of its own.

Common methods and descriptions of the TableWidget class

method illustrate
setRowCount() Set the number of rows in the table.
setColumnCount() Set the number of columns in the table.
setHorizontalHeaderLabels() Sets the horizontal header name in the table.
setVerticalHeaderLabels() Sets the vertical header name in the cell.
setItem() Set the content in each cell.
setCellWidget() Set the content of the cell as a QWIDget control.
resizeColumnsToContents() Make the width of the column of the table change with the content.
resizeRowsToContents() Make the height of the row of the table change with the content.
setEditTriggers()
  • Set whether the form can be edited, the values ​​are as follows:
  • QAbstractItemView.NoEditTriggers0No: cannot edit table content;
  • QAbstractItemView.CurrentChanged1Editing: allows editing of cells;
  • QAbstractItemView.DoubleClicked2Editing: Cells can be edited when double-clicked;
  • QAbstractItemView.SelectedClicked4Editing: Cells can be edited when clicked;
  • QAbstractItemView.EditKeyPressed8Editing: Cells can be edited when the modifier key is pressed;
  • QAbstractItemView.AngKeyPressed16Editing: Press any key to edit the cell.
setSpan()
  • Merge cells, the 4 parameters of this method are as follows:
  • row: the row index of the cell to be changed;
  • column: the column index of the cell to be changed;
  • rowSpanCount: the number of rows to be merged;
  • columnSpanCount: The number of columns that need to be merged.
setShowGrid() Set whether to display the grid lines, which are not displayed by default.
setSelectionBehavior()
  • Set the selection behavior of the table, the values ​​are as follows:
  • QAbstractItemView.SelectItems0Selecting: Select the current cell;
  • QAbstractItemView.SelectRows1Selecting: select the entire row;
  • QAbstractItemView.DoubleClicked2Editing: Select the entire column.
setTextAlignment()
  • Set the alignment of the text in the cell, the values ​​are as follows:
  • Qt.AlignLeft: Align with the left edge of the cell;
  • Qt.AlignRight: align with the right edge of the cell;
  • Qt.AlignHCenter: Horizontally centered in the cell;
  • Qt.AlignJustify: Justify both ends in the cell;
  • Qt.AlignTop: Align with the top edge of the cell;
  • Qt.AlignBottom: Align with the bottom edge of the cell;
  • Qt.AlignVCenter: vertical center alignment within the cell.
setAlternatingRowColors() Sets the table color to stagger.
setColumnWidth() Set the width of the cell.
setRowHeight() Set the height of the cell.
sortItems()
  • Set the sorting method of the cell content, the values ​​are as follows:
  • Qt.DescendingOrder: descending order;
  • Qt.AscendingOrder: ascending order.
rowCount() Get the number of rows in the table;
columnCount() Get the number of columns in the table.
verticalHeader() Get the vertical header of the table.
horizotalHeader() Get the table's horizontal title header.

      The QTableWidgetItem class represents the cells in the QTableWidget, and a table is composed of multiple cells.

Common methods and descriptions of the QTableWidgetItem class

method illustrate
setText() Set the text of the cell.
setCheckSate()
  • Set the selected state of the specified cell, the values ​​are as follows:
  • Qt.Checked: cell selected;
  • Qt.Unchecked: The cell is not selected.
setIcon() Sets the icon for the cell.
setBackground() Sets the background color of the cell.
setForeground() Sets the color of the text inside the cell.
setFont() Sets the font of the text in the cell.
text() Get the text of the cell.

2. Display database data in a table

      Using the TableWidget control to display data mainly uses the QTableWidgetItem class. Use this class to create cells in the table, and after specifying the text or icon to be displayed, you can use the setItem() method of the TableWidget object to add it to the table.

Example: Displaying MySQL Data Using a Table

      创建一个.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_())

运行程序,效果显示如下:
insert image description here

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

insert image description here
      如果需要隐藏表格的水平标题,可以使用如下代码:

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

效果如下图所示:
insert image description here

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

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

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

运行效果如下图:
insert image description here

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

insert image description here

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

运行效果如下:
insert image description here

示例:用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_())

运行效果如下:
insert image description here

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

运行效果于原来的对比如下:
insert image description here

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

运行效果如下:
insert image description here

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

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

setCellWidget(row, column, QWidget)

setCellWidget()方法的参数说明

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

示例:将“图书分类”显示为标准控件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_())

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

10. 合并指定单元格

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

setSpan(row, column, rowSpanCount, columnSpanCount)

setSpan()方法的参数说明

参数 说明
row 一个整数数字,表示要改变的单元格的行索引
column 一个整数数字,表示要改变的单元格的列索引
rowSpanCount 一个整数数字,表示需要合并的行数。
columSpanCount An integer number representing the number of columns that need to be merged.

Example: Merge cells with the same data

The key code is as follows:

        # 合并相同数据单元格
        # 合并第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)

The complete code is as follows:

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

The combined effect is as follows:
insert image description here

The original effect is as follows:
insert image description here

Guess you like

Origin blog.csdn.net/ungoing/article/details/127194935