PyQt5控件学习之-QTableWidget

目录

   0. 前言
   1. QTableWidget介绍
   2. QTableWidget简单示例
   3. QTableWidget中添加其他控件(QComboBox)
   4. 进阶版
   5. 结束语


0. 前言

回到顶部👆

  PyQt5控件学习之-QTableWidget:主要用于设计一个表格,表格内容中包含了其他控件,并且获取这些控件的值。


1. QTableWidget介绍

回到顶部👆

  QTableWidget是Qt程序中常用的显示数据表格的控件,QTableWidget是QTableView的子类,它使用标准的数据模型,并且其单元数据是通过QTableWidgetItem对象来实现的,使用QTableWidget时就需要QTableWidgetItem。用来表示表格中的一个单元格,整个表格就是用各个单元格构建起来的。
QTableWidget类中的常用方法

方法描述
setROwCount(int row)设置QTableWidget表格控件的行数
setColumnCount(int col)设置QTableWidget表格控件的列数
setHorizontalHeaderLabels()设置QTableWidget表格控件的水平标签
setVerticalHeaderLabels()设置QTableWidget表格控件的垂直标签
setItem(int ,int ,QTableWidgetItem)在QTableWidget表格控件的每个选项的单元控件内添加控件
horizontalHeader()获得QTableWidget表格控件的表格头,以便执行隐藏
rowCount()获得QTableWidget表格控件的行数
columnCount()获得QTableWidget表格控件的列数
setEditTriggers(EditTriggers triggers)设置表格是否可以编辑,设置表格的枚举值
setSelectionBehavior设置表格的选择行为
setTextAlignment()设置单元格内文本的对齐方式
setSpan(int row,int column,int rowSpanCount,int columnSpanCount)合并单元格,要改变单元格的第row行,column列,要合并rowSpancount行数和columnSpanCount列数
setShowGrid()在默认情况下表格的显示是有网格的,可以设置True或False用于是否显示,默认True
setColumnWidth(int column,int width)设置单元格行的宽度
setRowHeight(int row,int height)设置单元格列的高度

编辑规则的枚举值类型

选项描述
QAbstractItemView.NoEditTriggers0No0不能对表格内容进行修改
QAbstractItemView.CurrentChanged1Editing1任何时候都能对单元格进行修改
QAbstractItemView.DoubleClicked2Editing2双击单元格
QAbstractItemView.SelectedClicked4Editing4单击已经选中的内容
QAbstractItemView.EditKeyPressed8Editing8当修改键按下时修改单元格
QAbstractItemView.AnyKeyPressed16Editing16按任意键修改单元格
QAbstractItemView.AllEditTriggers31Editing31包括以上所有条件

表格选择行为的枚举值

选项描述
QAbstractItemView.SelectItems0Selecting0选中单个单元格
QAbstractItemView.SelectRows1Selecting1选中一行
QAbstractItemView.SelectColumns2Selecting2选中一列

单元格文本水平对齐方式

选项描述
Qt.AlignLeft将单元格内的内容沿单元格的左边缘对齐
Qt.AlignRight将单元格内的内容沿单元格的右边缘对齐
Qt.AlignHCenter在可用空间中,居中显示在水平方向上
Qt.AlignJustify将文本在可用空间内对齐,默认从左到右

单元格文本垂直对齐方式

选项描述
Qt.AlignTop与顶部对齐
Qt.AlignBottom与底部对齐
Qt.AlignVCenter在可用空间中,居中显示在垂直方向上
Qt.AlignBaseline与基线对齐

2. QTableWidget简单示例

回到顶部👆

   下面示例展示了一个简单的表格应用,包括设置表格的行列数目,如何添加数据,如何设置表格内容不可编辑等,代码如下:
"""
__Title__ = 'example.py'
__Author__ = 'Administrator'
__Date__ = '2020/11/29'
__Version__ = 'Python 3.7.9'
__Software__ = 'PyCharm'
"""
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Table(QWidget):
    def __init__(self):
        super(Table, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("QTableWidget例子")
        self.resize(400, 300)
        layout = QHBoxLayout()
        # 设置一个4行3列的表格
        tableWidget = QTableWidget(4, 3)
        # 设置标题
        tableWidget.setHorizontalHeaderLabels(['姓名', '性别', '体重(kg)'])
        # 添加数据
        item = QTableWidgetItem('王者荣耀')
        # 设置名字不可编辑
        item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
        tableWidget.setItem(0, 0, item)

        item = QTableWidgetItem('男')
        tableWidget.setItem(0, 1, item)

        item = QTableWidgetItem('170')
        tableWidget.setItem(0, 2, item)

        # 添加tableWidget到水平布局中
        layout.addWidget(tableWidget)
        # 应用水平布局
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Table()
    win.show()
    sys.exit(app.exec_())


3. QTableWidget中添加其他控件(QComboBox)

回到顶部👆

  先看一下效果,有兴趣的同学可以先试着搞个这样的,代码在后面展示
效果
  为了达到上面的效果,需要在表格中添加一个QComboBox控件,该控件中添加了座位的信息,这里采用页面和逻辑分离的模式,QTableWidget_Test.ui为UI页面文件(通过pyuic转换为QTableWidget_Test.py),main.py为主逻辑文件具体实现如下:
QTableWidget_Test.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'QTableWidget_Test.ui'
#
# Created by: PyQt5 UI code generator 5.15.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(588, 375)
        self.tableWidget = QtWidgets.QTableWidget(Form)
        self.tableWidget.setGeometry(QtCore.QRect(0, 0, 591, 381))
        # 设置表格行数为7
        self.tableWidget.setRowCount(7)
        # 设置列数为4
        self.tableWidget.setColumnCount(4)
        # 设置控件名为tableWidget
        self.tableWidget.setObjectName("tableWidget")

        self.retranslateUi(Form)
        # 信号自动绑定槽函数
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "QTableWidget_Ui"))

main.py

"""
__Title__ = 'main.py'
__Author__ = 'Administrator'
__Date__ = '2020/11/22'
__Version__ = 'Python 3.7.9'
__Software__ = 'PyCharm'
"""
import sys
import random
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QComboBox, QTableWidgetItem
from QTableWidget_Test import Ui_Form


class MyGui(QWidget, Ui_Form):
    def __init__(self):
        super(MyGui, self).__init__()
        self.setupUi(self)
        # 水平布局
        self.layout = QHBoxLayout()
        # 将表格控件添加到水平布局
        self.layout.addWidget(self.tableWidget)
        # 设置标题
        label_list = ['车次', '始发地', '目的地', '座位']
        self.tableWidget.setHorizontalHeaderLabels(label_list)
        # 定义车次列表
        car_list = ['K211', 'D342', 'Z21', 'G1432', 'T211', 'D9540', 'K234']
        # 定义始发地和目的地
        area_info = ['北京', '上海', '深圳', '广州', '新疆', '武汉', '哈尔滨']
        # 定义车次和座位的关系
        seat_info = {
            'K': ['硬座', '硬卧', '软卧', '无座'],
            'T': ['硬座', '硬卧', '软卧', '无座'],
            'Z': ['硬座', '硬卧', '软卧', '无座'],
            'D': ['二等座', '一等座', '商务座', '无座'],
            'G': ['二等座', '一等座', '商务座']
        }
        # 开始向表格中填充数据
        for row in range(len(car_list)):
            for column in range(len(label_list)):
                # 列为0,填入普通文字
                if column == 0:
                    # 内容
                    item = QTableWidgetItem(car_list[row])
                    # 设置此格不可编辑,修改
                    item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    # 将内容填入位置(row, column)
                    self.tableWidget.setItem(row, column, item)
                elif column == 1 or column == 2:
                    # 内容
                    item = QTableWidgetItem(area_info[random.randint(0, len(area_info) - 1)])
                    # 设置此格不可编辑,修改
                    item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    # 将内容填入位置(row, column)
                    self.tableWidget.setItem(row, column, item)
                else:
                    # 下拉选择控件
                    self.comb = QComboBox()
                    # 向下拉控件中添加内容
                    self.comb.addItems(seat_info[car_list[row][0]])
                    # 为下拉控件添加信号和槽函数
                    self.comb.currentIndexChanged.connect(self.comb_change)
                    # 将控件填入位置(row, column)
                    self.tableWidget.setCellWidget(row, column, self.comb)
        # 为表格控件添加信号和槽函数
        self.tableWidget.clicked.connect(self.click_position)
        # 应用水平布局
        self.setLayout(self.layout)

    def click_position(self):
        """
        表格控件点击信号绑定的槽函数
        :return: None
        """
        # 当前点击行标
        row = self.tableWidget.currentRow()
        # 当前点击列标
        column = self.tableWidget.currentColumn()
        print('当前位置: (%s, %s)' % (row, column))

    def comb_change(self):
        """
        获取下拉(comb)控件的值
        :return: None
        """
        # 当前点击行标
        row = self.tableWidget.currentRow()
        # 当前点击列标
        column = self.tableWidget.currentColumn()
        # self.sender():发送信号的控件
        print('row:{}, column: {}, seat: {}'.format(row, column, self.sender().currentText()))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MyGui()
    win.show()
    sys.exit(app.exec_())

4. 进阶版

回到顶部👆

  在上一步实现的基础上,又有一个新的需求,在每一行前面添加一个点击按钮,当按钮选中时,QCombBox控件才可以选择座位,各个按钮是互斥的(只能有一个被选中),效果如下:
upload
这里ui文件保持不变, 实现的主逻辑代码如下:
main_upload.py

"""
__Title__ = 'main.py'
__Author__ = 'Administrator'
__Date__ = '2020/11/22'
__Version__ = 'Python 3.7.9'
__Software__ = 'PyCharm'
"""
import sys
import random
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QComboBox, \
    QTableWidgetItem, QRadioButton, QHeaderView, QButtonGroup, QVBoxLayout, QAbstractItemView
from QTableWidget_Test import Ui_Form


class MyGui(QWidget, Ui_Form):
    def __init__(self):
        super(MyGui, self).__init__()
        self.setupUi(self)
        # 全局水平布局
        self.layout = QHBoxLayout()

        # 增加一个按钮组
        self.group = QButtonGroup()
        # 设置按钮组内的按钮互斥(只能一个被选中)
        self.group.setExclusive(True)

        # 设置标题
        label_list = ['', '车次', '始发地', '目的地', '座位']
        self.tableWidget.setHorizontalHeaderLabels(label_list)

        # 表格头随控件变化(水平方向占满窗体)
        self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 隐藏列表头(垂直方向的数字表[0, 1, 2...])
        self.tableWidget.verticalHeader().setVisible(False)
        # 设置表格内容不可编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 设置数据按车次字母排序(排序需要放在前面,放在后面会乱掉)
        self.tableWidget.sortItems(1, Qt.AscendingOrder)

        # 定义车次列表
        car_list = ['K211', 'D342', 'Z21', 'G1432', 'T211', 'D9540', 'K234']
        # 定义始发地和目的地
        area_info = ['北京', '上海', '深圳', '广州', '新疆', '武汉', '哈尔滨',
                     '重庆', '海南', '南昌', '西安', '南京', '合肥', '福州']
        # 定义车次和座位的关系
        seat_info = {
            'K': ['硬座', '硬卧', '软卧', '无座'],
            'T': ['硬座', '硬卧', '软卧', '无座'],
            'Z': ['硬座', '硬卧', '软卧', '无座'],
            'D': ['二等座', '一等座', '商务座', '无座'],
            'G': ['二等座', '一等座', '商务座']
        }
        # 开始向表格中填充数据
        for row in range(len(car_list)):
            for column in range(len(label_list)):
                # 列为0,填入radiobutton控件
                if column == 0:
                    # 添加radiobutton控件
                    self.radio = QRadioButton()
                    # radio控件加入按钮组,后续遍历使用
                    self.group.addButton(self.radio)
                    # 绑定槽函数
                    self.radio.clicked.connect(self.radio_check)

                    # 添加垂直布局,为了使radio控件可以居中
                    v = QVBoxLayout()
                    # radio控件添加进垂直布局
                    v.addWidget(self.radio)
                    # 设置垂直布局中的控件居中
                    v.setAlignment(Qt.AlignCenter)
                    # 新增窗体应用垂直布局
                    w = QWidget()
                    # 窗体应用布局
                    w.setLayout(v)

                    # 将控件填入位置(row, column)
                    self.tableWidget.setCellWidget(row, column, w)
                # 列为1,填入车次
                elif column == 1:
                    # 内容
                    item = QTableWidgetItem(car_list[row])
                    # 设置此格不可编辑,修改(上面定义了全局的,这里可以注释)
                    # item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    # 将内容填入位置(row, column)
                    self.tableWidget.setItem(row, column, item)
                # 列为2或3,填入始发站或目的地
                elif column == 2 or column == 3:
                    # 内容
                    item = QTableWidgetItem(area_info[random.randint(0, len(area_info) - 1)])
                    # 设置此格不可编辑,修改(上面定义了全局的,这里可以注释)
                    # item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
                    # 将内容填入位置(row, column)
                    self.tableWidget.setItem(row, column, item)
                # 列为4,填入QCombBox控件
                else:
                    # 下拉选择控件
                    self.comb = QComboBox()
                    # 向下拉控件中添加内容
                    self.comb.addItems(seat_info[car_list[row][0]])
                    # 设置QComboBox控件不可用
                    self.comb.setEnabled(False)
                    # 设置背景色(代表不可用)
                    self.comb.setStyleSheet("background-color: rgb(198, 199, 206)")
                    # 为下拉控件添加信号和槽函数
                    self.comb.currentIndexChanged.connect(self.comb_change)
                    # 将控件填入表格
                    self.tableWidget.setCellWidget(row, column, self.comb)

        # 为表格控件添加信号和槽函数
        self.tableWidget.itemClicked.connect(self.click_position)
        # 将表格控件添加到水平布局
        self.layout.addWidget(self.tableWidget)
        # 应用水平布局
        self.setLayout(self.layout)

    def radio_check(self):
        """
        radio按钮被点击是触发
        :return: None
        """
        # 遍历按钮组中的按钮
        for index, button in enumerate(self.group.buttons()):
            # 判断所有按钮状态
            if button.isChecked():
                # 被选中的按钮将该行的座位列控件QComBox改为可用
                self.tableWidget.cellWidget(index, 4).setEnabled(True)
                # 设置背景色(代表可用)
                self.tableWidget.cellWidget(index, 4).setStyleSheet("background-color: rgb(255, 255, 255)")
                # 获取默认的座位值
                print('当前默认座位: %s' % (self.tableWidget.cellWidget(index, 4).currentText()))
            else:
                # 未被选中的按钮将该行的座位列控件QComBox改为不可用
                self.tableWidget.cellWidget(index, 4).setEnabled(False)
                # 设置背景色(代表不可用)
                self.tableWidget.cellWidget(index, 4).setStyleSheet("background-color: rgb(198, 199, 206)")

    def click_position(self, item):
        """
        表格控件点击信号绑定的槽函数
        :param item: 点击表格传过来的数据
        :return: None
        """
        # 当前点击行标
        row = self.tableWidget.currentRow()
        # 当前点击列标
        column = self.tableWidget.currentColumn()
        print('当前位置: row: %s, columns: %s, 内容: %s' % (row, column, item.text()))

    def comb_change(self):
        """
        获取下拉(comb)控件的值
        :return: None
        """
        # 当前点击行标
        row = self.tableWidget.currentRow()
        # 当前点击列标
        column = self.tableWidget.currentColumn()
        # self.sender():发送信号的控件
        print('当前位置: row: %s, columns: %s, 内容: %s' % (row, column, self.sender().currentText()))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # 创建窗体
    win = MyGui()
    # 展示窗体
    win.show()
    sys.exit(app.exec_())

代码注解:

1、表格内容不可编辑
方式一: 通过tableWidget设置全局(推荐使用)self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
方式二: 修改Item为不可编辑,再填入单元格(这种方式点击控件所在格时也会打印坐标位置)
item = QTableWidgetItem(car_list[row]) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
2、表格头随控件变化(水平方向占满窗体)
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
3、隐藏列表头(垂直方向的数字表[0, 1, 2…])
self.tableWidget.verticalHeader().setVisible(False)
4、设置数据按车次字母排序(排序需要放在表格创建时前面,放在后面会乱掉,如下所示)
self.tableWidget.sortItems(1, Qt.AscendingOrder)
乱序
5、单元格内控件居中
self.radio = QRadioButton()  #需要添加到单元格的控件
v = QVBoxLayout()  #垂直布局(因为单元格内只添加一个控件,所以水平、垂直布局都可以)
v.addWidget(self.radio)  #向局部布局中添加控件
v.setAlignment(Qt.AlignCenter)  #设置布局中的所有控件居中(水平、垂直)显示
w = QWidget()  #新建一个空白控件
w.setLayout(v)  #上面已经添加radio控件的垂直布局放入空白控件中
self.tableWidget.setCellWidget(row, column, w)  #将上一步的控件填入单元格
6、点击radio控件,如何获取到同一行的QCombBox控件?
self.tableWidget.cellWidget(index, 4)  #获取控件


5. 结束语

回到顶部👆

  本文只是记录了基本的用法和自己想到的某个场景的实现,更多的功能或者你自己想实现的需求,可以依葫芦画瓢来实现。看到这里,各位看官忍心不给个关注和点赞么!

本文涉及代码:点击下载本文涉及代码
参考:
1、pyqt5中的tableWidget添加checkBox、comboBox
2、PyQt5 单元格里添加控件
3、PyQt5 - Table Widget初始化+内容防止编辑
4、PyQt5高级界面控件之QTableWidget

  • 7
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值