以下是一个使用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 Qt
class 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
# 创建UI
self.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和维度2
self.table = QTableWidget()
self.table.setRowCount(self.data_array.shape[1]) # 维度1
self.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 = 0
self.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双向绑定的核心模式。