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
相关产品推荐
相关产品推荐

