#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include "Version.h" #include "StyledMessageBox.h" #include "DialogConfig.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 设置窗口图标 #ifdef _WIN32 this->setWindowIcon(QIcon(":/resource/logo.ico")); #else this->setWindowIcon(QIcon(":/resource/logo.png")); #endif // 隐藏标题栏 setWindowFlags(Qt::FramelessWindowHint); // 设置状态栏 QFont statusFont = statusBar()->font(); statusFont.setPointSize(12); statusBar()->setFont(statusFont); statusBar()->setStyleSheet("QStatusBar { color: rgb(239, 241, 245); padding: 20px; }"); // 添加版本信息到状态栏(只显示版本号) QString versionText = QString("%1").arg(GetControlVersionOnly()); QLabel* versionLabel = new QLabel(versionText); versionLabel->setStyleSheet("color: rgb(239, 241, 245); font-size: 20px;"); statusBar()->addPermanentWidget(versionLabel); // 设置窗口大小为1200x700,不自动最大化 this->resize(1200, 700); this->setMinimumSize(1200, 700); // 设置最小尺寸 // 安装事件过滤器到顶部groupBox,用于拖动窗口 ui->groupBox->installEventFilter(this); // 初始化工作流程显示组件 m_workflowWidget = new WorkflowWidget(this); QVBoxLayout* workflowLayout = new QVBoxLayout(ui->frame_workflow); workflowLayout->setContentsMargins(0, 0, 0, 0); workflowLayout->addWidget(m_workflowWidget); // 初始化设备状态显示组件 m_deviceStatusWidget = new DeviceStatusWidget(this); m_deviceStatusWidget->setCameraCount(1); // 显示1个相机(用于显示控制器状态) m_deviceStatusWidget->setCamera1Name("控制器"); m_deviceStatusWidget->setCameraClickable(false); // 控制器不可点击 QVBoxLayout* deviceLayout = new QVBoxLayout(ui->frame_device); deviceLayout->setContentsMargins(0, 0, 0, 0); deviceLayout->addWidget(m_deviceStatusWidget); // 初始化日志辅助类 m_logHelper = new DetectLogHelper(ui->detect_log, this); // 创建Presenter m_presenter = new DemoControlPresenter(this); // 连接信号槽 connect(m_presenter, &DemoControlPresenter::statusMessageUpdated, this, &MainWindow::onStatusMessageUpdated); connect(m_presenter, &DemoControlPresenter::workflowStepChanged, this, &MainWindow::onWorkflowStepChanged); connect(m_presenter, &DemoControlPresenter::controllerConnectionChanged, this, &MainWindow::onControllerConnectionChanged); connect(m_presenter, &DemoControlPresenter::robotConnectionChanged, this, &MainWindow::onRobotConnectionChanged); connect(m_presenter, &DemoControlPresenter::detectionResultUpdated, this, &MainWindow::onDetectionResultUpdated); // 初始化按钮状态 ui->btn_pause->setEnabled(false); ui->btn_step->setEnabled(true); // 初始化 Init(); } MainWindow::~MainWindow() { if (m_presenter) { delete m_presenter; m_presenter = nullptr; } delete ui; } void MainWindow::Init() { updateStatusLog("主控程序初始化中..."); // 在线程中执行初始化 std::thread initThread([this]() { int result = m_presenter->Init(); if (result != 0) { updateStatusLog(QString("初始化失败,错误码:%1").arg(result)); } else { updateStatusLog("系统初始化完成"); } // 从配置文件加载配置 QMetaObject::invokeMethod(this, [this]() { // 加载配置到Presenter DialogConfig::LoadConfigToPresenter(m_presenter); updateStatusLog("配置已加载"); // 从配置文件读取连接参数 QSettings settings(DialogConfig::GetConfigFilePath(), QSettings::IniFormat); QString controllerIP = settings.value("Controller/IP", "192.168.0.88").toString(); int controllerPort = settings.value("Controller/Port", 502).toInt(); QString robotIP = settings.value("Robot/IP", "192.168.58.2").toString(); updateStatusLog(QString("正在连接控制器 %1:%2...").arg(controllerIP).arg(controllerPort)); m_presenter->ConnectToController(controllerIP, controllerPort); updateStatusLog(QString("正在连接机械臂 %1...").arg(robotIP)); m_presenter->ConnectToRobot(robotIP); }, Qt::QueuedConnection); }); initThread.detach(); } void MainWindow::updateStatusLog(const QString& message) { if (m_logHelper) { m_logHelper->appendLog(message); } } void MainWindow::on_btn_start_clicked() { if (!m_presenter) { updateStatusLog("系统未初始化"); return; } if (!m_presenter->IsControllerConnected()) { StyledMessageBox::warning(this, "警告", "控制器未连接,无法启动工作流程"); return; } if (!m_presenter->IsRobotConnected()) { StyledMessageBox::warning(this, "警告", "机械臂未连接,无法启动工作流程"); return; } updateStatusLog("启动工作流程..."); m_presenter->StartWorkflow(); // 更新按钮状态:连续执行模式 ui->btn_start->setEnabled(false); ui->btn_pause->setEnabled(true); ui->btn_pause->setText("暂停"); ui->btn_step->setEnabled(false); // 连续执行时禁用单步 } void MainWindow::on_btn_stop_clicked() { if (!m_presenter) { updateStatusLog("系统未初始化"); return; } updateStatusLog("停止工作流程..."); m_presenter->StopWorkflow(); m_workflowWidget->reset(); // 更新按钮状态:停止后恢复初始状态 ui->btn_start->setEnabled(true); ui->btn_pause->setEnabled(false); ui->btn_pause->setText("暂停"); ui->btn_step->setEnabled(true); } void MainWindow::on_btn_pause_clicked() { if (!m_presenter) { updateStatusLog("系统未初始化"); return; } if (m_presenter->IsWorkflowPaused()) { // 当前是暂停状态,点击恢复 updateStatusLog("恢复工作流程..."); m_presenter->ResumeWorkflow(); ui->btn_pause->setText("暂停"); ui->btn_step->setEnabled(false); // 恢复后禁用单步 ui->btn_start->setEnabled(false); // 恢复后禁用开始 } else { // 当前是运行状态,点击暂停 updateStatusLog("暂停工作流程..."); m_presenter->PauseWorkflow(); ui->btn_pause->setText("继续"); ui->btn_step->setEnabled(true); // 暂停后启用单步 ui->btn_start->setEnabled(false); // 暂停时仍然禁用开始 } } void MainWindow::on_btn_step_clicked() { if (!m_presenter) { updateStatusLog("系统未初始化"); return; } if (!m_presenter->IsControllerConnected()) { StyledMessageBox::warning(this, "警告", "控制器未连接,无法执行单步"); return; } if (!m_presenter->IsRobotConnected()) { StyledMessageBox::warning(this, "警告", "机械臂未连接,无法执行单步"); return; } updateStatusLog("执行单步..."); m_presenter->StepWorkflow(); // 更新按钮状态 if (!m_presenter->IsWorkflowRunning()) { // 首次单步,启动工作流程 ui->btn_start->setEnabled(false); ui->btn_pause->setEnabled(true); ui->btn_pause->setText("继续"); } } void MainWindow::on_btn_config_clicked() { if (!m_presenter) { updateStatusLog("系统未初始化"); return; } if (!m_dialogConfig) { m_dialogConfig = new DialogConfig(m_presenter, this); } m_dialogConfig->exec(); } void MainWindow::on_btn_fullscreen_clicked() { if (m_isFullScreen) { // 退出全屏,恢复到正常窗口 setWindowFlags(Qt::FramelessWindowHint); setGeometry(m_normalGeometry); showNormal(); m_isFullScreen = false; updateStatusLog("退出全屏"); } else { // 进入全屏 m_normalGeometry = geometry(); setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); showFullScreen(); m_isFullScreen = true; updateStatusLog("进入全屏"); } } void MainWindow::on_btn_hide_clicked() { this->showMinimized(); } void MainWindow::on_btn_close_clicked() { this->close(); } void MainWindow::onStatusMessageUpdated(const QString& message) { updateStatusLog(message); } void MainWindow::onWorkflowStepChanged(WorkflowStep step, const QString& message) { m_workflowWidget->updateStep(step); updateStatusLog(message); // 如果工作流程完成,检查是否真的结束了 if (step == WorkflowStep::Completed) { // 延迟检查工作流程是否真的停止 QTimer::singleShot(100, this, [this]() { if (!m_presenter->IsWorkflowRunning()) { // 工作流程已停止,更新按钮状态 ui->btn_start->setEnabled(true); ui->btn_pause->setEnabled(false); ui->btn_pause->setText("暂停"); ui->btn_step->setEnabled(true); } else if (m_presenter->IsWorkflowStepMode()) { // 单步模式下完成一轮,保持"继续"按钮状态不变 // 按钮应该显示"继续",因为处于单步等待状态 ui->btn_pause->setText("继续"); } }); } else if (step == WorkflowStep::Error) { // 出错时立即更新按钮状态 ui->btn_start->setEnabled(true); ui->btn_pause->setEnabled(false); ui->btn_pause->setText("暂停"); ui->btn_step->setEnabled(true); } } void MainWindow::onControllerConnectionChanged(bool connected) { // 更新设备状态显示(使用相机1状态显示控制器连接状态) if (m_deviceStatusWidget) { m_deviceStatusWidget->updateCamera1Status(connected); } if (connected) { updateStatusLog("控制器已连接"); } else { updateStatusLog("控制器已断开"); } } void MainWindow::onRobotConnectionChanged(bool connected) { if (m_deviceStatusWidget) { m_deviceStatusWidget->updateRobotStatus(connected); } if (connected) { updateStatusLog("机械臂已连接"); } else { updateStatusLog("机械臂已断开"); } } void MainWindow::onDetectionResultUpdated(const DetectionResult& result) { m_workflowWidget->updateDetectionResult(result); } void MainWindow::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { ResizeRegion region = getResizeRegion(event->pos()); if (region != None) { // 开始缩放 m_isResizing = true; m_resizeRegion = region; m_resizeStartPos = event->globalPos(); m_resizeStartGeometry = this->geometry(); event->accept(); } } } void MainWindow::mouseMoveEvent(QMouseEvent *event) { if (m_isResizing && (event->buttons() & Qt::LeftButton)) { // 处理窗口缩放 QPoint delta = event->globalPos() - m_resizeStartPos; QRect newGeometry = m_resizeStartGeometry; if (m_resizeRegion & Left) { newGeometry.setLeft(m_resizeStartGeometry.left() + delta.x()); } if (m_resizeRegion & Right) { newGeometry.setRight(m_resizeStartGeometry.right() + delta.x()); } if (m_resizeRegion & Top) { newGeometry.setTop(m_resizeStartGeometry.top() + delta.y()); } if (m_resizeRegion & Bottom) { newGeometry.setBottom(m_resizeStartGeometry.bottom() + delta.y()); } // 确保不小于最小尺寸 if (newGeometry.width() >= minimumWidth() && newGeometry.height() >= minimumHeight()) { this->setGeometry(newGeometry); } event->accept(); } else if (!m_isDragging) { // 更新鼠标光标 ResizeRegion region = getResizeRegion(event->pos()); updateCursor(region); } } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_isResizing = false; m_resizeRegion = None; m_isDragging = false; updateCursor(None); event->accept(); } } MainWindow::ResizeRegion MainWindow::getResizeRegion(const QPoint& pos) { int region = None; if (pos.x() <= RESIZE_BORDER_WIDTH) { region |= Left; } else if (pos.x() >= width() - RESIZE_BORDER_WIDTH) { region |= Right; } if (pos.y() <= RESIZE_BORDER_WIDTH) { region |= Top; } else if (pos.y() >= height() - RESIZE_BORDER_WIDTH) { region |= Bottom; } return static_cast(region); } void MainWindow::updateCursor(ResizeRegion region) { switch (region) { case TopLeft: case BottomRight: setCursor(Qt::SizeFDiagCursor); break; case TopRight: case BottomLeft: setCursor(Qt::SizeBDiagCursor); break; case Left: case Right: setCursor(Qt::SizeHorCursor); break; case Top: case Bottom: setCursor(Qt::SizeVerCursor); break; default: setCursor(Qt::ArrowCursor); break; } } bool MainWindow::eventFilter(QObject *obj, QEvent *event) { // 只在顶部groupBox区域允许拖动 if (obj == ui->groupBox) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton) { m_isDragging = true; m_dragPosition = mouseEvent->globalPos() - this->frameGeometry().topLeft(); return true; } } else if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast(event); if (m_isDragging && (mouseEvent->buttons() & Qt::LeftButton)) { this->move(mouseEvent->globalPos() - m_dragPosition); return true; } } else if (event->type() == QEvent::MouseButtonRelease) { QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton) { m_isDragging = false; return true; } } } return QMainWindow::eventFilter(obj, event); }