diff --git a/ui/main_window_ui.py b/ui/main_window_ui.py index 0868f75..4dc4d16 100644 --- a/ui/main_window_ui.py +++ b/ui/main_window_ui.py @@ -335,12 +335,17 @@ class MainWindowUI(QMainWindow): self.stop_button = QPushButton("暂停") self.stop_button.setFont(self.normal_font) self.stop_button.setStyleSheet(button_style + "background-color: #ffebee; border: 1px solid #f44336;") + + self.report_button = QPushButton("报表") + self.report_button.setFont(self.normal_font) + self.report_button.setStyleSheet(button_style + "background-color: #e0e0e0; border: 1px solid #cccccc;") # 使用网格布局排列按钮 self.button_layout.addWidget(self.input_button, 0, 0) self.button_layout.addWidget(self.output_button, 0, 1) self.button_layout.addWidget(self.start_button, 0, 2) self.button_layout.addWidget(self.stop_button, 0, 3) + self.button_layout.addWidget(self.report_button, 0, 4) self.control_layout.addWidget(self.button_container) diff --git a/ui/report_dialog_ui.py b/ui/report_dialog_ui.py new file mode 100644 index 0000000..d2b9d87 --- /dev/null +++ b/ui/report_dialog_ui.py @@ -0,0 +1,169 @@ +from PySide6.QtWidgets import ( + QDialog, QVBoxLayout, QHBoxLayout, QLabel, + QTableWidget, QTableWidgetItem, QHeaderView, + QPushButton, QComboBox, QFrame, QDateEdit +) +from PySide6.QtCore import Qt, QDate +from PySide6.QtGui import QFont + +class ReportDialogUI(QDialog): + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("统计报表") + self.resize(1000, 600) + self.init_ui() + + def init_ui(self): + # 设置字体 + self.title_font = QFont("微软雅黑", 14, QFont.Bold) + self.normal_font = QFont("微软雅黑", 12) + + # 主布局 + self.main_layout = QVBoxLayout(self) + self.main_layout.setContentsMargins(10, 10, 10, 10) + self.main_layout.setSpacing(10) + + # 创建筛选条件区域 + self.create_filter_section() + + # 创建报表内容区域 + self.create_report_section() + + # 创建按钮区域 + self.create_button_section() + + def create_filter_section(self): + """创建筛选条件区域""" + # 筛选条件容器 + self.filter_frame = QFrame() + self.filter_frame.setFrameShape(QFrame.StyledPanel) + self.filter_layout = QHBoxLayout(self.filter_frame) + + # 日期选择 + self.date_label = QLabel("日期范围:") + self.date_label.setFont(self.normal_font) + self.start_date = QDateEdit() + self.start_date.setFont(self.normal_font) + self.start_date.setCalendarPopup(True) + self.start_date.setDate(QDate.currentDate()) + self.date_separator = QLabel("-") + self.end_date = QDateEdit() + self.end_date.setFont(self.normal_font) + self.end_date.setCalendarPopup(True) + self.end_date.setDate(QDate.currentDate()) + + # 报表类型选择 + self.type_label = QLabel("报表类型:") + self.type_label.setFont(self.normal_font) + self.type_combo = QComboBox() + self.type_combo.setFont(self.normal_font) + self.type_combo.addItems(["日报表", "月报表", "年报表"]) + + # 查询按钮 + self.query_button = QPushButton("查询") + self.query_button.setFont(self.normal_font) + self.query_button.setStyleSheet(""" + QPushButton { + padding: 8px 16px; + background-color: #1976D2; + color: white; + border-radius: 4px; + } + QPushButton:hover { + background-color: #1565C0; + } + """) + + # 添加组件到筛选布局 + self.filter_layout.addWidget(self.date_label) + self.filter_layout.addWidget(self.start_date) + self.filter_layout.addWidget(self.date_separator) + self.filter_layout.addWidget(self.end_date) + self.filter_layout.addSpacing(20) + self.filter_layout.addWidget(self.type_label) + self.filter_layout.addWidget(self.type_combo) + self.filter_layout.addSpacing(20) + self.filter_layout.addWidget(self.query_button) + self.filter_layout.addStretch() + + # 添加到主布局 + self.main_layout.addWidget(self.filter_frame) + + def create_report_section(self): + """创建报表内容区域""" + # 报表表格 + self.report_table = QTableWidget() + self.report_table.setFont(self.normal_font) + + # 设置列 + self.report_table.setColumnCount(8) + self.report_table.setHorizontalHeaderLabels([ + "日期", "工程号", "品名", "规格", + "生产数量", "合格数量", "不合格数量", "合格率" + ]) + + # 设置表格样式 + self.report_table.setStyleSheet(""" + QTableWidget { + border: 1px solid #ddd; + gridline-color: #ddd; + } + QHeaderView::section { + background-color: #f5f5f5; + padding: 5px; + border: 1px solid #ddd; + font-weight: bold; + } + """) + + # 调整列宽 + header = self.report_table.horizontalHeader() + for i in range(8): + header.setSectionResizeMode(i, QHeaderView.Stretch) + + # 添加到主布局 + self.main_layout.addWidget(self.report_table) + + def create_button_section(self): + """创建按钮区域""" + # 按钮容器 + self.button_frame = QFrame() + self.button_layout = QHBoxLayout(self.button_frame) + + # 导出按钮 + self.export_button = QPushButton("导出Excel") + self.export_button.setFont(self.normal_font) + self.export_button.setStyleSheet(""" + QPushButton { + padding: 8px 16px; + background-color: #4CAF50; + color: white; + border-radius: 4px; + } + QPushButton:hover { + background-color: #43A047; + } + """) + + # 关闭按钮 + self.close_button = QPushButton("关闭") + self.close_button.setFont(self.normal_font) + self.close_button.setStyleSheet(""" + QPushButton { + padding: 8px 16px; + background-color: #FF5722; + color: white; + border-radius: 4px; + } + QPushButton:hover { + background-color: #F4511E; + } + """) + + # 添加按钮到布局 + self.button_layout.addStretch() + self.button_layout.addWidget(self.export_button) + self.button_layout.addWidget(self.close_button) + + # 添加到主布局 + self.main_layout.addWidget(self.button_frame) \ No newline at end of file diff --git a/widgets/main_window.py b/widgets/main_window.py index 5fb68d1..2e2e9d6 100644 --- a/widgets/main_window.py +++ b/widgets/main_window.py @@ -43,6 +43,7 @@ from utils.inspection_config_manager import InspectionConfigManager from utils.pallet_type_manager import PalletTypeManager # 导入串口管理 from utils.serial_manager import SerialManager +from widgets.report_dialog import ReportDialog class MainWindow(MainWindowUI): """主窗口""" @@ -246,7 +247,8 @@ class MainWindow(MainWindowUI): if self.camera_enabled and hasattr(self, 'camera_display'): self.camera_display.signal_camera_status.connect(self.handle_camera_status) - + # 连接报表按钮点击事件 + self.report_button.clicked.connect(self.on_report) def update_inspection_columns(self): """更新检验列配置 - 使用检验配置管理器获取启用的列数和标题""" @@ -2367,4 +2369,13 @@ class MainWindow(MainWindowUI): """处理从加载对话框接收到的订单号""" logging.info(f"主窗口接收到订单号: {order_code}") # 存储当前订单号 - self._current_order_code = order_code \ No newline at end of file + self._current_order_code = order_code + + def on_report(self): + """报表按钮点击处理""" + try: + dialog = ReportDialog(self) + dialog.exec_() + except Exception as e: + logging.error(f"打开报表对话框失败: {str(e)}") + QMessageBox.warning(self, "错误", f"打开报表对话框失败: {str(e)}") \ No newline at end of file diff --git a/widgets/report_dialog.py b/widgets/report_dialog.py new file mode 100644 index 0000000..7b4cf6d --- /dev/null +++ b/widgets/report_dialog.py @@ -0,0 +1,105 @@ +from PySide6.QtWidgets import QMessageBox +from PySide6.QtCore import Qt +from ui.report_dialog_ui import ReportDialogUI +import pandas as pd +from datetime import datetime +import logging + +class ReportDialog(ReportDialogUI): + def __init__(self, parent=None): + super().__init__(parent) + self.init_signals() + + def init_signals(self): + """初始化信号连接""" + # 查询按钮点击事件 + self.query_button.clicked.connect(self.on_query) + + # 导出按钮点击事件 + self.export_button.clicked.connect(self.on_export) + + # 关闭按钮点击事件 + self.close_button.clicked.connect(self.close) + + def on_query(self): + """查询按钮点击处理""" + try: + # 获取查询条件 + start_date = self.start_date.date().toString(Qt.ISODate) + end_date = self.end_date.date().toString(Qt.ISODate) + report_type = self.type_combo.currentText() + + # TODO: 根据条件从数据库查询数据 + # 这里需要实现具体的查询逻辑 + + # 示例数据 + data = [ + { + "日期": "2024-03-20", + "工程号": "GC001", + "品名": "产品A", + "规格": "规格1", + "生产数量": 100, + "合格数量": 95, + "不合格数量": 5, + "合格率": "95%" + } + ] + + # 更新表格显示 + self.update_table(data) + + except Exception as e: + logging.error(f"查询报表数据失败: {str(e)}") + QMessageBox.warning(self, "错误", f"查询数据失败: {str(e)}") + + def update_table(self, data): + """更新表格数据 + + Args: + data: 包含报表数据的列表 + """ + # 清空表格 + self.report_table.setRowCount(0) + + # 添加数据行 + for row_idx, row_data in enumerate(data): + self.report_table.insertRow(row_idx) + for col_idx, (key, value) in enumerate(row_data.items()): + item = QTableWidgetItem(str(value)) + item.setTextAlignment(Qt.AlignCenter) + self.report_table.setItem(row_idx, col_idx, item) + + def on_export(self): + """导出按钮点击处理""" + try: + # 获取表格数据 + data = [] + for row in range(self.report_table.rowCount()): + row_data = {} + for col in range(self.report_table.columnCount()): + header = self.report_table.horizontalHeaderItem(col).text() + item = self.report_table.item(row, col) + value = item.text() if item else "" + row_data[header] = value + data.append(row_data) + + if not data: + QMessageBox.warning(self, "警告", "没有数据可以导出") + return + + # 创建DataFrame + df = pd.DataFrame(data) + + # 生成文件名 + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"统计报表_{timestamp}.xlsx" + + # 导出到Excel + df.to_excel(filename, index=False, engine='openpyxl') + + QMessageBox.information(self, "成功", f"报表已导出到: {filename}") + + except Exception as e: + logging.error(f"导出报表失败: {str(e)}") + QMessageBox.warning(self, "错误", f"导出报表失败: {str(e)}") \ No newline at end of file