PyQt实现3维数组与界面TableWidget双向绑定
以下是一个使用PyQt实现3维数组与界面TableWidget双向绑定的示例代码。该程序包含一个下拉菜单选择第0维索引,表格展示第1维和第2维的数据,并支持双向数据同步:
import sys
import numpy as np
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QComboBox, QTableWidget, QTableWidgetItem, QHeaderView)
from PyQt5.QtCore import Qtclass ArrayTableApp(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("3D Array Table Binding")self.setGeometry(100, 100, 600, 400)# 创建3D数组 (3x4x5)self.data_array = np.zeros((3, 4, 5), dtype=float)# 初始化一些测试数据for i in range(3):for j in range(4):for k in range(5):self.data_array[i, j, k] = i * 100 + j * 10 + k# 创建UIself.central_widget = QWidget()self.setCentralWidget(self.central_widget)self.layout = QVBoxLayout(self.central_widget)# 维度0选择下拉框self.dim0_combo = QComboBox()self.dim0_combo.addItems([f"维度0-{i}" for i in range(self.data_array.shape[0])])self.layout.addWidget(self.dim0_combo)# 表格展示维度1和维度2self.table = QTableWidget()self.table.setRowCount(self.data_array.shape[1]) # 维度1self.table.setColumnCount(self.data_array.shape[2]) # 维度2# 设置表头self.table.setHorizontalHeaderLabels([f"Col-{i}" for i in range(self.data_array.shape[2])])self.table.setVerticalHeaderLabels([f"Row-{i}" for i in range(self.data_array.shape[1])])# 表格自适应self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)self.layout.addWidget(self.table)# 连接信号self.dim0_combo.currentIndexChanged.connect(self.update_table)self.table.cellChanged.connect(self.update_array)# 初始化表格self.current_dim0 = 0self.update_table(0)def update_table(self, dim0_index):"""根据选择的维度0索引更新表格"""self.current_dim0 = dim0_index# 断开信号防止编辑触发更新self.table.cellChanged.disconnect()# 更新表格数据for i in range(self.data_array.shape[1]):for j in range(self.data_array.shape[2]):value = self.data_array[dim0_index, i, j]item = QTableWidgetItem(f"{value:.2f}")item.setTextAlignment(Qt.AlignCenter)item.setData(Qt.UserRole, value) # 存储原始值self.table.setItem(i, j, item)# 重新连接信号self.table.cellChanged.connect(self.update_array)def update_array(self, row, col):"""表格编辑时更新数组数据"""item = self.table.item(row, col)if item is not None:try:# 尝试转换为浮点数new_value = float(item.text())self.data_array[self.current_dim0, row, col] = new_value# 更新显示格式item.setText(f"{new_value:.2f}")except ValueError:# 无效输入恢复原值orig_value = self.data_array[self.current_dim0, row, col]item.setText(f"{orig_value:.2f}")# 打印当前数组状态(调试用)print(f"数组更新:dim0={self.current_dim0}, row={row}, col={col}")print(f"新值:{self.data_array[self.current_dim0, row, col]:.2f}")if __name__ == "__main__":app = QApplication(sys.argv)window = ArrayTableApp()window.show()sys.exit(app.exec_())
代码说明:
-
数据结构:
- 使用NumPy创建3×4×5的三维数组
- 初始化测试数据:每个元素值为 100 × i + 10 × j + k 100 \times i + 10 \times j + k 100×i+10×j+k
-
界面组件:
QComboBox
:选择第0维索引QTableWidget
:展示第1维和第2维数据(4行5列)
-
双向绑定机制:
- 数组到表格:
- 当下拉框选择变化时,
update_table()
方法加载对应维度的数据 - 表格单元格使用
QTableWidgetItem
显示数据,保留原始值在UserRole
中
- 当下拉框选择变化时,
- 表格到数组:
- 表格编辑触发
cellChanged
信号,调用update_array()
- 验证输入有效性,无效时恢复原值
- 表格编辑触发
- 数组到表格:
-
数据同步处理:
- 更新表格时暂时断开信号,避免循环触发
- 单元格显示保留两位小数
- 编辑时进行浮点数转换验证
功能特点:
- 维度0通过下拉菜单切换,实时更新表格内容
- 表格编辑后自动更新三维数组对应位置的值
- 输入验证机制防止非法输入
- 表格自适应窗口大小
- 数据变化实时打印到控制台(调试用)
使用说明:
- 运行程序显示3D数组查看器
- 通过顶部下拉菜单切换第一维度
- 在表格中双击单元格编辑数值
- 编辑后按Enter确认,数据会自动同步到后台数组
- 输入非数字内容会自动恢复之前的值
可以根据实际需求调整数组维度和初始化数据,此代码展示了PyQt中实现数据与UI双向绑定的核心模式。