pyqt 自定义QTableWidget
自定义QTableWidget
`import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QWidget,
QComboBox, QTabWidget, QTableWidget, QTableWidgetItem)
from PyQt5.QtCore import Qt
import re
class CustomTableWidget(QTableWidget):
def init(self, rows=0, cols=0, parent=None):
super().init(rows, cols, parent)
# 允许编辑表格
self.setEditTriggers(QTableWidget.DoubleClicked | QTableWidget.EditKeyPressed)
self.setSelectionBehavior(QTableWidget.SelectRows)
self.setSelectionMode(QTableWidget.SingleSelection)
self.setAlternatingRowColors(True)
self.setShowGrid(True)
self.setWordWrap(True)
self.setCornerButtonEnabled(True)
def extract_number(self, text):
"""从文本中提取数字"""
if not text:
return 0
# 尝试直接转换为数字
try:
return float(text)
except ValueError:
# 如果直接转换失败,尝试提取数字部分
numbers = re.findall(r'-?\d+\.?\d*', text)
if numbers:
return float(numbers[0])
return None
class UTTabWidget(QTabWidget):
def init(self, parent=None):
super().init(parent)
self.initUI()
def initUI(self):
self.add_tab1("员工信息")
self.add_tab2("考勤记录")
self.add_tab3("薪资统计")
def add_tab1(self, title):
tab = CustomTableWidget(10, 5) # 10行5列
tab.setHorizontalHeaderLabels(["ID", "姓名", "实际工时", "标准工时", "结果"])
# tab.blockSignals(True)
# 添加示例数据
data = [
["001", "张三", "40", "40", ""],
["002", "李四", "38", "40", ""],
["003", "王五", "42", "40", ""]
]
for i, row_data in enumerate(data):
for j, cell_data in enumerate(row_data):
item = QTableWidgetItem(str(cell_data))
tab.setItem(i, j, item)
# 绑定事件
tab.itemChanged.connect(self.on_tab1_item_changed)
for i in range(len(data)):
self.update_tab1_result_column(tab, i)
self.addTab(tab, title)
def add_tab2(self, title):
tab = CustomTableWidget(10, 5) # 10行5列
tab.setHorizontalHeaderLabels(["日期", "员工", "实际出勤", "应出勤", "结果"])
# 添加示例数据
data = [
["2023-01-01", "张三", "8", "8", ""],
["2023-01-01", "李四", "7", "8", ""],
["2023-01-02", "王五", "9", "8", ""]
]
for i, row_data in enumerate(data):
for j, cell_data in enumerate(row_data):
item = QTableWidgetItem(str(cell_data))
tab.setItem(i, j, item)
self.addTab(tab, title)
def add_tab3(self, title):
tab = CustomTableWidget(10, 5) # 10行5列
tab.setHorizontalHeaderLabels(["月份", "员工", "实发工资", "应发工资", "结果"])
# 添加示例数据
data = [
["1月", "张三", "8000", "8000", ""],
["1月", "李四", "7500", "8000", ""],
["2月", "王五", "9000", "8500", ""]
]
for i, row_data in enumerate(data):
for j, cell_data in enumerate(row_data):
item = QTableWidgetItem(str(cell_data))
tab.setItem(i, j, item)
self.addTab(tab, title)
def on_tab1_item_changed(self, item):
"""tab1专用的单元格变更处理函数"""
row = item.row()
col = item.column()
# 只处理第3列和第4列(索引2和3)的变更
if col in [2, 3]:
self.update_tab1_result_column(item.tableWidget(), row)
def update_tab1_result_column(self, table, row):
"""更新tab1的结果列"""
# 确保行存在且有足够的列数
if row >= table.rowCount() or table.columnCount() < 5:
return
# 获取第三列和第四列的值
third_item = table.item(row, 2)
fourth_item = table.item(row, 3)
if third_item and fourth_item:
try:
# 提取数字值
third_value = float(third_item.text()) if third_item.text() else 0
fourth_value = float(fourth_item.text()) if fourth_item.text() else 0
# 计算差值
diff = third_value - fourth_value
# 获取或创建第五列的单元格
result_item = table.item(row, 4)
if not result_item:
result_item = QTableWidgetItem()
table.setItem(row, 4, result_item)
# 根据差值更新第五列
if diff == 0: # 工时相等为pass
result_item.setText("pass")
else:
result_item.setText("fail")
except (ValueError, TypeError):
# 如果转换失败,设置为fail
result_item = table.item(row, 4)
if not result_item:
result_item = QTableWidgetItem()
table.setItem(row, 4, result_item)
result_item.setText("fail")
class PRDTabWidget(QTabWidget):
def init(self, parent=None):
super().init(parent)
self.initUI()
def initUI(self):
self.add_tab1("产品信息")
self.add_tab2("库存统计")
self.add_tab3("销售报告")
def add_tab1(self, title):
tab = CustomTableWidget(10, 5) # 10行5列
tab.setHorizontalHeaderLabels(["产品编号", "产品名称", "实际成本", "预算成本", "结果"])
# 添加示例数据
data = [
["P001", "笔记本电脑", "4500", "5000", ""],
["P002", "台式机", "3500", "3500", ""],
["P003", "显示器", "800", "1000", ""]
]
for i, row_data in enumerate(data):
for j, cell_data in enumerate(row_data):
item = QTableWidgetItem(str(cell_data))
tab.setItem(i, j, item)
# 更新结果列
for i in range(tab.rowCount()):
tab.update_result_column(i)
self.addTab(tab, title)
def add_tab2(self, title):
tab = CustomTableWidget(10, 5) # 10行5列
tab.setHorizontalHeaderLabels(["仓库", "产品", "实际库存", "安全库存", "结果"])
# 添加示例数据
data = [
["一号仓", "笔记本电脑", "50", "30", ""],
["二号仓", "台式机", "20", "25", ""],
["一号仓", "显示器", "100", "80", ""]
]
for i, row_data in enumerate(data):
for j, cell_data in enumerate(row_data):
item = QTableWidgetItem(str(cell_data))
tab.setItem(i, j, item)
# 更新结果列
for i in range(tab.rowCount()):
tab.update_result_column(i)
self.addTab(tab, title)
def add_tab3(self, title):
tab = CustomTableWidget(10, 5) # 10行5列
tab.setHorizontalHeaderLabels(["季度", "产品", "实际销量", "目标销量", "结果"])
# 添加示例数据
data = [
["Q1", "笔记本电脑", "200", "250", ""],
["Q1", "台式机", "150", "150", ""],
["Q2", "显示器", "300", "280", ""]
]
for i, row_data in enumerate(data):
for j, cell_data in enumerate(row_data):
item = QTableWidgetItem(str(cell_data))
tab.setItem(i, j, item)
# 更新结果列
for i in range(tab.rowCount()):
tab.update_result_column(i)
self.addTab(tab, title)
class MainWindow(QMainWindow):
def init(self):
super().init(parent=None)
self.setWindowTitle("auto report v1.0.0")
self.setGeometry(100, 100, 800, 600)
self.initUI()
def initUI(self):
# 创建中央部件
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 创建主布局
layout = QVBoxLayout(central_widget)
# 创建下拉框并添加选项
self.category_combo = QComboBox()
self.category_combo.addItems([
"员工管理",
"产品管理",
])
# 创建自定义的tab组件
self.tab_widget = UTTabWidget()
# 添加组件到布局
layout.addWidget(self.category_combo)
layout.addWidget(self.tab_widget)
# 绑定事件
self.category_combo.currentTextChanged.connect(self.update_tabs)
def update_tabs(self, text):
"""根据下拉框选择更新tabs"""
# 保存当前tab的位置
current_index = self.tab_widget.currentIndex()
# 删除旧的tab_widget
layout = self.centralWidget().layout()
layout.removeWidget(self.tab_widget)
self.tab_widget.deleteLater()
# 创建新的tab_widget
if text == "员工管理":
self.tab_widget = UTTabWidget()
elif text == "产品管理":
self.tab_widget = PRDTabWidget()
else:
self.tab_widget = QTabWidget()
# 添加新的tab_widget到布局
layout.addWidget(self.tab_widget)
# 恢复之前的tab位置
if current_index < self.tab_widget.count():
self.tab_widget.setCurrentIndex(current_index)
def main():
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
if name == "main":
main()
`

浙公网安备 33010602011771号