You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide2中QTableWidgetItem编辑显部分值,结束后计算总值

这个需求其实很典型,核心就是利用Qt的**数据角色(Data Roles)**来区分「编辑时显示的内容」和「正常显示的内容」。我给你分别提供PySide2和Qt C++的完整实现方案,你可以直接参考:

PySide2 实现方案

首先我们明确核心逻辑:通过重写QTableWidgetItem的data()和setData()方法,让编辑模式下返回MyObject的int_1,正常显示时返回int_1 + int_2的总值;编辑完成后自动更新MyObject并刷新显示。

1. 定义基础的MyObject类

class MyObject:
    def __init__(self, int1: int, int2: int):
        self.int_1 = int1
        self.int_2 = int2

2. 自定义MyQTableWidgetItem类

from PySide2.QtWidgets import QTableWidgetItem
from PySide2.QtCore import Qt

class MyQTableWidgetItem(QTableWidgetItem):
    def __init__(self, my_obj: MyObject):
        super().__init__()
        self.my_obj = my_obj
        # 初始化时直接显示总值
        self.setData(Qt.DisplayRole, self.my_obj.int_1 + self.my_obj.int_2)

    def data(self, role: int):
        # 编辑模式下返回int_1
        if role == Qt.EditRole:
            return self.my_obj.int_1
        # 正常显示时返回计算后的总值
        elif role == Qt.DisplayRole:
            return self.my_obj.int_1 + self.my_obj.int_2
        # 其他角色交给父类处理
        return super().data(role)

    def setData(self, role: int, value):
        if role == Qt.EditRole:
            # 尝试将输入转为整数,处理非法输入
            try:
                new_int1 = int(value)
                self.my_obj.int_1 = new_int1
                # 更新显示角色的数据,触发界面刷新
                super().setData(Qt.DisplayRole, self.my_obj.int_1 + self.my_obj.int_2)
            except ValueError:
                # 输入不是整数时,可以选择忽略或弹出提示
                pass
        # 其他角色的设置交给父类
        super().setData(role, value)

3. 使用示例

from PySide2.QtWidgets import QApplication, QTableWidget, QWidget, QVBoxLayout
import sys

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = QWidget()
    layout = QVBoxLayout(window)
    
    table = QTableWidget(3, 1)
    layout.addWidget(table)
    
    # 创建测试数据并添加到表格
    obj1 = MyObject(10, 20)
    obj2 = MyObject(5, 15)
    obj3 = MyObject(30, 5)
    
    table.setItem(0, 0, MyQTableWidgetItem(obj1))
    table.setItem(1, 0, MyQTableWidgetItem(obj2))
    table.setItem(2, 0, MyQTableWidgetItem(obj3))
    
    window.show()
    sys.exit(app.exec_())
Qt C++ 实现方案

逻辑和PySide2完全一致,只是语法换成C++:

1. 定义MyObject类

class MyObject {
public:
    int int_1;
    int int_2;
    MyObject(int int1, int int2) : int_1(int1), int_2(int2) {}
};

2. 自定义MyQTableWidgetItem类

#include <QTableWidgetItem>
#include <QVariant>

class MyQTableWidgetItem : public QTableWidgetItem {
private:
    MyObject* m_myObj;
public:
    explicit MyQTableWidgetItem(MyObject* obj) : QTableWidgetItem(), m_myObj(obj) {
        // 初始化显示总值
        setData(Qt::DisplayRole, m_myObj->int_1 + m_myObj->int_2);
    }

    QVariant data(int role) const override {
        if (role == Qt::EditRole) {
            return m_myObj->int_1;
        } else if (role == Qt::DisplayRole) {
            return m_myObj->int_1 + m_myObj->int_2;
        }
        return QTableWidgetItem::data(role);
    }

    void setData(int role, const QVariant& value) override {
        if (role == Qt::EditRole) {
            bool ok;
            int newInt1 = value.toInt(&ok);
            if (ok) {
                m_myObj->int_1 = newInt1;
                // 更新显示数据
                QTableWidgetItem::setData(Qt::DisplayRole, m_myObj->int_1 + m_myObj->int_2);
            }
        }
        QTableWidgetItem::setData(role, value);
    }
};

3. 使用示例

#include <QApplication>
#include <QTableWidget>
#include <QWidget>
#include <QVBoxLayout>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QWidget window;
    QVBoxLayout* layout = new QVBoxLayout(&window);
    
    QTableWidget* table = new QTableWidget(3, 1);
    layout->addWidget(table);
    
    MyObject* obj1 = new MyObject(10, 20);
    MyObject* obj2 = new MyObject(5, 15);
    MyObject* obj3 = new MyObject(30, 5);
    
    table->setItem(0, 0, new MyQTableWidgetItem(obj1));
    table->setItem(1, 0, new MyQTableWidgetItem(obj2));
    table->setItem(2, 0, new MyQTableWidgetItem(obj3));
    
    window.show();
    return app.exec();
}

额外说明

如果MyObject的int_2可能被其他逻辑修改,你可以给MyObject添加一个valueChanged信号,让MyQTableWidgetItem连接这个信号,当int_2变化时自动刷新显示值。

内容的提问来源于stack exchange,提问作者FinnStark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:38:13