PyQt5-高级控件QTableWidget和QTableView

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

from PyQt5.Qt import *
import sys


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QTableWidget-人员信息')
        self.resize(600, 600)
        self.__setup_ui()

    def __setup_ui(self):
        self.table_widget = QTableWidget(self)
        self.table_widget.setColumnCount(3)  # 3列
        self.table_widget.setHorizontalHeaderLabels(['姓名', '身高', '体重'])  # 表头
        self.table_widget.setShowGrid(True)  # 显示网格

        # self.table_widget.verticalHeader().setVisible(False)  # 不显示垂直表头

        # 注意:单元格可以设置大小、还可以设置成控件、也可以添加图片,还可以设置右键菜单等灵活的操作模式

        # 设置表格为自使用伸缩模式,即可根据窗口大小来改变网格的大小
        self.table_widget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 也可以单独设置每一列的伸缩样式
        # self.table_widget.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        # self.table_widget.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeToContents)
        # self.table_widget.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)

        self.table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)  # 表格禁止编辑

        self.table_widget.setRowCount(3)  # 不设置行数,内容无法展示

        for i in range(3):
            name_item = QTableWidgetItem(f'name_{i + 1}')
            name_item.setTextAlignment(Qt.AlignLeft)  # 创建item并设置内容、对齐方式

            height_item = QTableWidgetItem(f'{180 + i}')
            height_item.setTextAlignment(Qt.AlignCenter)

            weight_item = QTableWidgetItem(f'{60 + i}')
            weight_item.setTextAlignment(Qt.AlignRight)

            # 单元格设置前景色
            if height_item.text() == '180':
                height_item.setForeground(QBrush(QColor("#24B64E")))
            else:
                name_item.setForeground(QBrush(QColor("#f00")))
                height_item.setForeground(QBrush(QColor("#f00")))
                weight_item.setForeground(QBrush(QColor("#f00")))

            # 设置单元格内容
            self.table_widget.setItem(i, 0, name_item)  # 行/列/内容
            self.table_widget.setItem(i, 1, height_item)
            self.table_widget.setItem(i, 2, weight_item)

        btn = QPushButton('添加一行内容', self)

        v_l = QVBoxLayout()
        v_l.addWidget(self.table_widget)
        v_l.addWidget(btn)
        self.setLayout(v_l)

        # 信号
        self.table_widget.itemChanged.connect(self.__item_change_slot)
        self.table_widget.cellPressed.connect(self.table_widget.resizeRowsToContents)
        self.table_widget.itemDoubleClicked.connect(self.__item_double_click_slot)
        btn.clicked.connect(self.__btn_click)

    def __btn_click(self):
        current_row = self.table_widget.rowCount()
        self.table_widget.setRowCount(current_row + 1)
        self.table_widget.setItem(current_row, 0, QTableWidgetItem('new_1'))
        self.table_widget.setItem(current_row, 1, QTableWidgetItem('new_2'))
        self.table_widget.setItem(current_row, 2, QTableWidgetItem('new_3'))

    @staticmethod
    def __item_change_slot(item: QTableWidgetItem):
        print('itemChanged信号触发:', item)
        print(f'item变更的行{item.row()},变更的列{item.column()}')

    @staticmethod
    def __item_double_click_slot(item: QTableWidgetItem):
        if item.column() == 2:  # 仅第3列触发
            print('您双击了 第{}行,第{}列 的cell'.format(item.row() + 1, item.column() + 1))


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

运行效果图

在通常情况下,一个应用需要和一批数据进行交互,然后以表格的形式输出这些信息,这时就需要用到QTableView类了。
在QTableView中可以使用自定义的数据模型来显示内容,通过setModel来绑定数据源。

QTableWidget继承自QTableView,主要区别是QTableView可以使用自定义的数据模型来显示内容(先通过setModel来绑定数据源)。
而QTableWidget只能使用标准的数据模型,并且其单元格数据是通过QTableWidgetItem对象实现的,通常QTableWidget就能够满足我们的要求。

from PyQt5.Qt import *
import sys


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QTableView-表格视图控件')
        self.resize(600, 600)

        # 设置数据层次结构,4行4列
        self.model = QStandardItemModel(4, 4)
        # 设置水平方向四个头标签文本内容
        self.model.setHorizontalHeaderLabels(['标题1', '标题2', '标题3', '标题4'])

        # 添加数据
        for row in range(4):
            for column in range(4):
                item = QStandardItem(f'row {row}, column {column}')
                # 设置4行4列,每个表格item位置的文本值
                self.model.setItem(row, column, item)

        # 实例化表格视图,设置模型为自定义的模型
        self.table_view = QTableView()
        self.table_view.setModel(self.model)

        # 将表格填满窗口
        # 水平方向标签拓展剩下的窗口部分,填满表格
        self.table_view.horizontalHeader().setStretchLastSection(True)
        # 水平方向,表格大小拓展到适当的尺寸
        self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # 添加数据
        self.model.appendRow([
                QStandardItem('11'),
                QStandardItem('22'),
                QStandardItem('33'),
                QStandardItem('44'),
            ])

        # 删除当前所选中的数据(通过btn按钮实现)
        self.btn = QPushButton(text='删除', parent=self)
        self.btn.clicked.connect(self.on_btn_slot)  # type: ignore

        v_l = QVBoxLayout()
        v_l.addWidget(self.table_view)
        v_l.addWidget(self.btn)
        self.setLayout(v_l)

    def on_btn_slot(self):
        """ 删除操作 """
        # 第1种方法
        indexes = self.table_view.selectionModel().selection().indexes()  # 取当前选中的所有行
        if len(indexes) > 0:
            index = indexes[0]  # 取第一行的索引
            self.model.removeRows(index.row(), 1)

        # 第2种方法
        # index = self.table_view.currentIndex()
        # print(index.row())
        # self.model.removeRow(index.row())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

运行效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值