QMessageBox 设置button按键大小
时间: 2023-08-28 22:12:40 浏览: 429
要设置 QMessageBox 中的按钮的大小,可以使用 QMessageBox 的 setButtonSize() 方法。该方法接受两个参数,分别是宽度和高度。
以下是一个示例代码,展示如何设置 QMessageBox 中按钮的大小:
```python
from PySide2.QtWidgets import QApplication, QMessageBox
app = QApplication([])
msg_box = QMessageBox()
msg_box.setText("This is a message box")
msg_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msg_box.setButtonSize(100, 50) # 设置按钮的宽度为100,高度为50
msg_box.exec_()
```
在上述示例中,我们创建了一个 QMessageBox 对象,并设置了文本和标准按钮。然后,使用 setButtonSize() 方法将按钮的大小设置为 100x50 像素。
注意,setButtonSize() 方法只在 Qt 5.15 或更高版本中可用。如果你使用的是较旧的 Qt 版本,可能需要使用其他方法来实现相同的效果。
相关问题
QMessageBox Qt5.9 设置button按键大小
在 Qt 5.9 中,QMessageBox 并没有提供直接设置按钮大小的方法。不过,你可以通过一些间接的方式来实现这个效果。一种方法是使用样式表(Stylesheet)来设置按钮的大小。
以下是一个示例代码,展示如何通过样式表设置 QMessageBox 中按钮的大小:
```cpp
#include <QApplication>
#include <QMessageBox>
#include <QPushButton>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QMessageBox msgBox;
msgBox.setText("This is a message box");
QPushButton *okButton = msgBox.addButton(QMessageBox::Ok);
okButton->setStyleSheet("width: 100px; height: 50px;");
QPushButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);
cancelButton->setStyleSheet("width: 100px; height: 50px;");
msgBox.exec();
return app.exec();
}
```
在上述示例中,我们创建了一个 QMessageBox 对象,并添加了 Ok 和 Cancel 两个按钮。然后,通过调用 addButton() 方法获取到这些按钮的指针,并使用 setStyleSheet() 方法设置按钮的样式表,从而间接设置按钮的大小为 100x50 像素。
请注意,这种方式是通过样式表来改变按钮的外观,实际上并没有直接设置按钮的大小。因此,具体效果可能因操作系统和样式引擎的不同而有所差异。如果你需要更精确地控制按钮的大小,可能需要考虑自定义消息框来实现。
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QHBoxLayout> #include <QVBoxLayout> #include <QMessageBox> #include <QGroupBox> #include <QFormLayout> #include <QPixmap> #include <QSerialPortInfo> #include <QDateTime> #include <windows.h> #include <dwmapi.h> #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #endif MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , m_serialWorker(nullptr) , timeoutTimer(new QTimer(this)) , currentActiveButton(nullptr) , workModeButton(nullptr) , m_isHandshakeSuccess(false) , sensorVoltageTimer(new QTimer(this)) , isGettingSensorVoltage(false) , m_isCISChecking(false) , m_agingTimer(new QTimer(this)) { this->setStyleSheet("QMainWindow{background-color:#F6F6F2;}"); if(HWND hwnd = (HWND)winId()) { BOOL darkMode = FALSE; DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &darkMode, sizeof(darkMode)); } ui->setupUi(this); setWindowTitle(tr("点钞机")); setMinimumSize(800, 600); //主布局-左右分割1:3 mainLayout = new QHBoxLayout(); mainLayout->setSpacing(10); mainLayout->setStretch(0, 1); //左侧区域 mainLayout->setStretch(1, 2); //中间区域 mainLayout->setStretch(2, 1); //右侧区域 //========== 左侧区域 ========== QWidget *leftWidget = new QWidget(); QVBoxLayout *leftLayout = new QVBoxLayout(leftWidget); leftLayout->setSpacing(10); QGroupBox *portGroup = new QGroupBox(tr("串口设置")); portGroup->setStyleSheet("QGroupBox { background-color: #F6F6F2; border: 1px solid #ccc; border-radius: 5px; margin-top: 10px;color:#388087; font-weight: bold; }" "QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px; background-color:#F6F6F2;font-weight: bold; }"); QVBoxLayout *portLayout = new QVBoxLayout(portGroup); portComboBox = new QComboBox(portGroup); portComboBox->setStyleSheet("background-color:#ebebe7;color:#388087;font-weight: bold; "); //波特率选择下拉框 baudRateComboBox = new QComboBox(portGroup); baudRateComboBox->setStyleSheet("background-color:#ebebe7;color:#388087;font-weight: bold; "); baudRateComboBox->addItem("115200", QSerialPort::Baud115200); baudRateComboBox->addItem("9600", QSerialPort::Baud9600); baudRateComboBox->setCurrentIndex(0); //默认115200 currentBaudRate = QSerialPort::Baud115200; //连接波特率变化信号 connect(baudRateComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::onBaudRateChanged); btnRefreshPorts = new QPushButton("刷新串口", portGroup); btnRefreshPorts->setStyleSheet("QPushButton {" "background-color:#e0e0e0;" "color:#388087;" "font-weight: bold;" "}" "QPushButton:hover{""background-color: #e0e0e0;color:#388087;" "}" "QPushButton:pressed {" "background-color: #a0a0a0;" "color:#388087;" "}"); btnConnect = new QPushButton("连接串口", portGroup); btnConnect->setStyleSheet("QPushButton {" "background-color:#e0e0e0;" "color:#388087;" "font-weight: bold;" "}" "QPushButton:hover{""background-color: #e0e0e0;color:#388087;" "}" "QPushButton:pressed {" "background-color: #a0a0a0;" "color:#388087;" "}"); portLayout->addWidget(portComboBox); portLayout->addWidget(baudRateComboBox); //添加波特率下拉框 portLayout->addWidget(btnRefreshPorts); portLayout->addWidget(btnConnect); portLayout->setStretch(0, 1); portLayout->setStretch(1, 1); portLayout->setStretch(2, 1); portLayout->setStretch(3, 1); leftLayout->addWidget(portGroup,2); QGroupBox *infoGroup = new QGroupBox("机器信息"); infoGroup->setStyleSheet("background-color:#F6F6F2;color:#388087;border: 1px solid #ccc;padding: 5px;font-weight: bold; "); QVBoxLayout *infoLayout = new QVBoxLayout(infoGroup); machineInfoLineEdit = new QTextEdit(); machineInfoLineEdit->setReadOnly(true); machineInfoLineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QFont font; font.setPointSize(12); machineInfoLineEdit->setFont(font); //设置行间距 machineInfoLineEdit->setStyleSheet( "QTextEdit {" " line-height: 150%;" " background-color: #F6F6F2;" " border: 1px solid #ccc;" " padding: 5px;" " color: black;" " font-weight: bold; " "}" ); machineInfoLineEdit->setLineWrapMode(QTextEdit::WidgetWidth); machineInfoLineEdit->setWordWrapMode(QTextOption::WrapAnywhere); //machineInfoLineEdit->setMinimumHeight(200); machineInfoLineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); infoLayout->addWidget(machineInfoLineEdit); leftLayout->addWidget(infoGroup, 3); //-------------计数显示区域-------------- CountingInfoWidget *countingWidget = new CountingInfoWidget(); QVBoxLayout *countLayout = new QVBoxLayout(countingWidget); countLayout->setSpacing(10); countLayout->setContentsMargins(10, 10, 10, 10); countLayout->setStretch(0, 3); //表格区域 countLayout->setStretch(1, 1); //按钮区域 //创建并配置表格 denominationTable = new QTableWidget(countingWidget); denominationTable->setObjectName("denominationTable"); denominationTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); denominationTable->setColumnCount(3); //金额、数量、单位 denominationTable->setRowCount(0); denominationTable->verticalHeader()->setVisible(false); //隐藏行头 denominationTable->horizontalHeader()->setVisible(false); //隐藏列头 denominationTable->setShowGrid(false); //隐藏网格线 denominationTable->setEditTriggers(QAbstractItemView::NoEditTriggers); //禁止编辑 denominationTable->setSelectionMode(QAbstractItemView::NoSelection); //禁止选择 denominationTable->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); //固定大小 //设置表格样式 denominationTable->setStyleSheet( "QTableWidget {" " background-color: transparent;" " border: none;" " color: #388087;" "}" "QTableWidget::item {" " padding: 2px;" " border: none;" "}" ); //设置列宽 denominationTable->setColumnWidth(0, 80); //金额列 denominationTable->setColumnWidth(1, 40); //数量列 denominationTable->setColumnWidth(2, 40); //单位列 //将表格添加到布局 //countLayout->addWidget(denominationTable, 3, Qt::AlignLeft | Qt::AlignTop); connect(countingWidget, &CountingInfoWidget::blankAreaClicked, this, &MainWindow::onAmountLabelClicked); //主布局:上部显示区域和下部按钮 QHBoxLayout *mainCountLayout = new QHBoxLayout(); //左侧布局 - 退钞数 QVBoxLayout *refundLayout = new QVBoxLayout(); QLabel* refundTitleLabel = new QLabel("退钞数"); //refundTitleLabel->setFixedWidth(120); refundTitleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); refundTitleLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;font:14px;border: none;font-weight: bold; "); refundTitleLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); refundLabel = new ClickableLabel(); // refundLabel->setFixedWidth(90); refundLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); refundLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;padding: 5px;border: none;font:bold 17px;font-weight: bold; "); refundLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); //添加SN显示label QHBoxLayout *refundRowLayout = new QHBoxLayout(); //refundRowLayout->addWidget(refundLabel); snLabel = new QLabel(); snLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;padding: 5px;border: none;font:bold 12px;font-weight: bold; "); snLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); snLabel->setMinimumWidth(150); //为SN留出足够空间 refundRowLayout->addWidget(refundTitleLabel); refundRowLayout->addWidget(snLabel); refundLayout->addWidget(denominationTable, 1); refundLayout->addLayout(refundRowLayout,0); refundLayout->addWidget(refundLabel,0); //使用水平布局替代直接添加refundLabel //中间布局-弹性空间 QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); //右侧布局-包含金额和张数 QVBoxLayout *rightcountLayout = new QVBoxLayout(); //金额部分 QVBoxLayout *amountLayout = new QVBoxLayout(); QLabel* amountTitleLabel = new QLabel("金额"); amountTitleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); amountTitleLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;font:14px;border: none;font-weight: bold; "); amountTitleLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); amountLabel = new ClickableLabel(); amountLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;padding: 5px;border: none;font:bold 17px;font-weight: bold; "); amountLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); amountLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); amountLayout->addStretch(); //弹性空间使金额靠右 amountLayout->addWidget(amountTitleLabel); amountLayout->addWidget(amountLabel); rightcountLayout->addLayout(amountLayout); rightcountLayout->addStretch(); //张数部分 QVBoxLayout *sheetLayout = new QVBoxLayout(); QLabel* sheetTitleLabel = new QLabel("张数"); sheetTitleLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;font:14px;border: none;font-weight: bold; "); sheetTitleLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); sheetNumberLabel = new ClickableLabel(); sheetNumberLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;padding: 5px;border: none;font:bold 17px;font-weight: bold; "); sheetNumberLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop); sheetTitleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sheetNumberLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sheetLayout->addStretch(); //弹性空间使张数靠右 sheetLayout->addWidget(sheetTitleLabel); sheetLayout->addWidget(sheetNumberLabel); rightcountLayout->addLayout(sheetLayout); refundLabel->setText("0"); amountLabel->setText("0"); sheetNumberLabel->setText("0"); //设置标签可点击 refundLabel->setCursor(Qt::PointingHandCursor); amountLabel->setCursor(Qt::PointingHandCursor); sheetNumberLabel->setCursor(Qt::PointingHandCursor); //将各部分添加到主布局 mainCountLayout->addLayout(refundLayout,1); mainCountLayout->addItem(spacer); mainCountLayout->addLayout(rightcountLayout,1); //连接点击信号 connect(refundLabel, &ClickableLabel::clicked, this, &MainWindow::onRefundLabelClicked); connect(amountLabel, &ClickableLabel::clicked, this, &MainWindow::onAmountLabelClicked); connect(sheetNumberLabel, &ClickableLabel::clicked, this, &MainWindow::onSheetNumberLabelClicked); //将主显示布局添加到计数组 countLayout->addLayout(mainCountLayout,2); buttonStyle = "QPushButton {" "background-color: #f8f8f8;" "border: 1px solid #ccc;" "border-radius: 5px;" "padding: 8px;" "width: 120px;" "height: 50px;" "color:#388087;" "font-weight: bold; " "}" "QPushButton:hover {" "background-color: #f0f0f0;" "color:#388087;" "font-weight: bold; " "}" "QPushButton:pressed {" "background-color: #c0c0c0;" "color:#388087;" "font-weight: bold; " "}"; //添加重置按钮 resetCountButton = new QPushButton("重置计数"); resetCountButton->setStyleSheet(buttonStyle); resetCountButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); connect(resetCountButton, &QPushButton::clicked, this,&MainWindow::on_resetCountButton_clicked); countLayout->addWidget(resetCountButton); leftLayout->addWidget(countingWidget, 3); mainLayout->addWidget(leftWidget, 1); //========== 中间区域 ========== QWidget *centerWidget = new QWidget(); QVBoxLayout *centerLayout = new QVBoxLayout(centerWidget); centerLayout->setSpacing(10); //机器状态区域 QGroupBox *statusGroup = new QGroupBox("机器状态"); statusGroup->setStyleSheet("QGroupBox { background-color: #F6F6F2; border: 1px solid #ccc; border-radius: 5px; margin-top: 10px;color:#388087; font-weight: bold; }" "QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px; background-color:#F6F6F2;font-weight: bold; }"); QHBoxLayout *statusLayout = new QHBoxLayout(statusGroup); machineStatusImage = new QLabel(); machineStatusImage->setAlignment(Qt::AlignCenter); machineStatusImage->setScaledContents(true); machineStatusImage->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // QLabel* overlayLabel = new QLabel(machineStatusImage); // overlayLabel->setStyleSheet("background-color: transparent; color: red; font-weight: bold;"); // overlayLabel->setText("QT"); // overlayLabel->move(250, 110); // 设置位置 // overlayLabel->adjustSize(); // overlayLabel->setAttribute(Qt::WA_TransparentForMouseEvents); // 允许点击穿透 voltageTable = new QTableWidget(); voltageTable->setColumnCount(3); //voltageTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); voltageTable->setHorizontalHeaderLabels({"传感器ID", "传感器名称", "电压值(V)"}); voltageTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); voltageTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); voltageTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); voltageTable->setStyleSheet( "QTableWidget {" " background-color: #F6F6F2;" " border: 1px solid #ccc;" " color: #388087;" "}" "QTableWidget::item {" " padding: 2px;" " border: none;" " background-color: #F6F6F2;" " color: #388087;" "}" "QTableWidget::item:selected {" " background-color: #F6F6F2;" " color: #388087;" "}" "QHeaderView {" " background-color: #F6F6F2;" //表头整体背景色 "}" "QScrollBar:vertical {" " background: #F6F6F2;" " width: 12px;" " margin: 0px 0px 0px 0px;" "}" "QHeaderView::section {" " background-color: #F6F6F2;" " padding: 4px;" " border: 1px solid #ccc;" " color: #388087;" "}" "QTableCornerButton::section {" " background-color: #F6F6F2;" //左上角空白区域 " border: 1px solid #ccc;" "}" ); voltageTable->setVisible(false); //初始隐藏表格 QPixmap pixmap(":/image/333.svg"); if(!pixmap.isNull()) { machineStatusImage->setMaximumSize(450, 700); QPixmap scaled = pixmap.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); machineStatusImage->setPixmap(scaled); } else { machineStatusImage->setText("图片加载失败"); } statusLayout->addWidget(machineStatusImage, 3); statusLayout->addWidget(voltageTable, 1); centerLayout->addWidget(statusGroup, 3); //信息显示区域 QGroupBox *messageGroup = new QGroupBox(); messageGroup->setStyleSheet("background-color:#F6F6F2;color:#388087;border: 1px solid #ccc;padding: 5px;font-weight: bold; "); QVBoxLayout *messageLayout = new QVBoxLayout(messageGroup); //添加顶部布局,包含标题和清除按钮 QHBoxLayout *messageHeaderLayout = new QHBoxLayout(); QLabel *messageTitleLabel = new QLabel("信息显示"); messageTitleLabel->setStyleSheet("background-color:#F6F6F2;color:#388087;font-weight: bold;"); QPushButton *clearButton = new QPushButton("清空"); clearButton->setStyleSheet("QPushButton {" "background-color: #f0f0f0;" "border: 1px solid #ccc;" "border-radius: 3px;" "padding: 3px 8px;" "color:#388087;" "font-weight: bold;" "}" "QPushButton:hover {" "background-color: #e0e0e0;" "}" "QPushButton:pressed {" "background-color: #a0a0a0;" "}"); clearButton->setFixedWidth(60); //设置固定宽度 messageHeaderLayout->addWidget(messageTitleLabel); messageHeaderLayout->addStretch(); messageHeaderLayout->addWidget(clearButton); messageLayout->addLayout(messageHeaderLayout); messageTextEdit = new QTextEdit(); messageTextEdit->setReadOnly(true); messageTextEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); messageTextEdit->setStyleSheet("QTextEdit { background-color: #F6F6F2; border: 1px solid #ccc; padding: 5px; color:black;font-weight: bold;/* font-family:宋体; */font-size:14px;}"); messageLayout->addWidget(messageTextEdit); //连接清除按钮的信号 connect(clearButton, &QPushButton::clicked, this, [this](){ messageTextEdit->clear(); }); centerLayout->addWidget(messageGroup, 2); mainLayout->addWidget(centerWidget, 2); //========== 右侧区域 ========== QWidget *rightWidget = new QWidget(); QVBoxLayout *rightLayout = new QVBoxLayout(rightWidget); rightLayout->setSpacing(10); //按钮区域 QGroupBox *buttonGroup = new QGroupBox("操作命令"); buttonGroup->setStyleSheet("QGroupBox { background-color: #F6F6F2; border: 1px solid #ccc black; border-radius: 5px; margin-top: 10px;color:#388087; font-weight: bold; }" "QGroupBox::title { subcontrol-origin: margin; left: 10px; padding: 0 3px; background-color:#F6F6F2;font-weight: bold; }"); QVBoxLayout *buttonLayout = new QVBoxLayout(buttonGroup); commandStack = new QStackedWidget(); commandStack->addWidget(createFirstCommandPage()); //第一页 commandStack->addWidget((createSecondCommandPage())); //第二页 //添加导航按钮 QHBoxLayout* navLayout = new QHBoxLayout(); addNavigationButtons(navLayout); buttonLayout->addLayout(navLayout); buttonLayout->addWidget(commandStack); rightLayout->addWidget(buttonGroup); mainLayout->addWidget(rightWidget, 1); //设置中心窗口 QWidget *centralWidget = new QWidget(); centralWidget->setLayout(mainLayout); setCentralWidget(centralWidget); // QToolBar* langToolBar = addToolBar(tr("语言")); // QAction* zhAction = langToolBar->addAction("中文"); // QAction* enAction = langToolBar->addAction("英语"); // connect(zhAction, &QAction::triggered, this, [this]() { // loadLanguage("zh_CN"); // }); // connect(enAction, &QAction::triggered, this, [this]() { // loadLanguage("en"); // }); //连接信号槽 connect(btnRefreshPorts, &QPushButton::clicked, this, &MainWindow::refreshPorts); connect(btnConnect, &QPushButton::clicked, this, &MainWindow::toggleConnection); //初始化UI状态 refreshPorts(); enableControls(false); initializeErrorMaps(); //初始化传感器名称映射 sensorNameMap["0X01"] = "QTH"; sensorNameMap["0X02"] = "QTL"; sensorNameMap["0X03"] = "PS1L"; sensorNameMap["0X04"] = "PS1M"; sensorNameMap["0X05"] = "PS1R"; sensorNameMap["0X06"] = "PS2L"; sensorNameMap["0X07"] = "PS2R"; sensorNameMap["0X08"] = "PS3L"; sensorNameMap["0X09"] = "PS3M"; sensorNameMap["0X0A"] = "PS3R"; sensorNameMap["0X0B"] = "ST"; sensorNameMap["0X0C"] = "STL"; sensorNameMap["0X0D"] = "STR"; sensorNameMap["0X0E"] = "STU"; sensorNameMap["0X0F"] = "PS4"; sensorNameMap["0X10"] = "UV1"; sensorNameMap["0X11"] = "UV2"; sensorNameMap["0X12"] = "DWP"; sensorNameMap["0X13"] = "RJH"; sensorNameMap["0X14"] = "RJL"; sensorNameMap["0X15"] = "BTU"; sensorNameMap["0X16"] = "BTD"; sensorNameMap["0X17"] = "CVU"; sensorNameMap["0X18"] = "CVD"; sensorNameMap["0X19"] = "UVM"; sensorNameMap["0X1A"] = "SAFE"; sensorNameMap["0X1B"] = "PS5"; sensorNameMap["0X1C"] = "TKL"; sensorNameMap["0X1D"] = "TKR"; sensorNameMap["0X1E"] = "QTLoc"; sensorNameMap["0X1F"] = "TDLoc"; sensorNameMap["0X20"] = "RJLoc"; sensorNameMap["0X21"] = "FL"; sensorNameMap["0X22"] = "Chn"; //老化定时器 connect(m_agingTimer, &QTimer::timeout, this, [this]() { m_agingSeconds++; updateAgingTimeDisplay(); }); } MainWindow::~MainWindow() { //清理串口工作线程 if(m_serialWorker) { m_serialWorker->stop(); //停止线程 m_serialWorker->wait(); delete m_serialWorker; m_serialWorker = nullptr; } delete ui; } //波特率改变处理 void MainWindow::onBaudRateChanged(int index) { currentBaudRate = baudRateComboBox->currentData().toInt(); //如果已连接,则更新波特率 if(m_serialWorker) { m_serialWorker->setBaudRate(currentBaudRate); logMessage(QString("波特率已更改为: %1").arg(baudRateComboBox->currentText())); } } void MainWindow::onRefundLabelClicked() { if(!m_serialWorker) { logMessage("串口未打开"); return; } //清空之前的退钞数据 m_rejectList.clear(); m_rejectReasons.clear(); if(m_rejectDialog && m_rejectDialog->isVisible()) { m_rejectDialog->close(); } //初始化对话框 initRejectDialog(); //发送获取退钞口信息列表命令 sendGetRejectListCommand(); setButtonActive(rejectListButton); } void MainWindow::onAmountLabelClicked() { if(!m_serialWorker) { logMessage("串口未打开"); return; } //清空之前的明细数据 m_detailList.clear(); initDetailDialog(); sendDetailedlistCommand(); setButtonActive(detailedlistButton); } void MainWindow::onSheetNumberLabelClicked() { onAmountLabelClicked(); } QWidget* MainWindow::createFirstCommandPage() { QWidget *page = new QWidget(); QGridLayout *grid = new QGridLayout(page); grid->setSpacing(10); grid->setContentsMargins(10, 10, 10, 10); buttonStyle = "QPushButton {" "background-color: #f8f8f8;" "border: 1px solid #ccc;" "border-radius: 5px;" "padding: 8px;" "width: 120px;" "height: 50px;" "color:#388087;" "font-weight: bold; " "}" "QPushButton:hover {" "background-color: #f0f0f0;" "color:#388087;" "font-weight: bold; " "}" "QPushButton:pressed {" "background-color: #c0c0c0;" "color:#388087;" "font-weight: bold; " "}"; QWidget *handshakeWidget = new QWidget(); QVBoxLayout *handshakeLayout = new QVBoxLayout(handshakeWidget); handshakeLayout->setContentsMargins(0, 0, 0, 0); handshakeLayout->setSpacing(2); QLabel *emptyLabel3 = new QLabel(); emptyLabel3->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel3->setAlignment(Qt::AlignLeft | Qt::AlignBottom); handshakeLayout->addWidget(emptyLabel3); QPushButton *handshakeButton = new QPushButton("握手命令"); handshakeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); handshakeButton->setStyleSheet(buttonStyle); handshakeLayout->addWidget(handshakeButton); grid->addWidget(handshakeWidget, 0, 0); QWidget *testWidget = new QWidget(); QVBoxLayout *testLayout = new QVBoxLayout(testWidget); testLayout->setContentsMargins(0, 0, 0, 0); testLayout->setSpacing(2); QLabel *emptyLabel4 = new QLabel(); emptyLabel4->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel4->setAlignment(Qt::AlignLeft | Qt::AlignBottom); testLayout->addWidget(emptyLabel4); QPushButton *testButton = new QPushButton("获取软件版本信息"); testButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); testButton->setStyleSheet(buttonStyle); testLayout->addWidget(testButton); grid->addWidget(testWidget, 0, 1); //启动机器按钮 QWidget *startMachineWidget = new QWidget(); QVBoxLayout *startMachineLayout = new QVBoxLayout(startMachineWidget); startMachineLayout->setContentsMargins(0, 0, 0, 0); startMachineLayout->setSpacing(2); QLabel *startMachineLabel = new QLabel("机器控制"); startMachineLabel->setStyleSheet("color:#388087; font-weight: bold;"); startMachineLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); startMachineLayout->addWidget(startMachineLabel); startMachineButton = new QPushButton("启动机器"); startMachineButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); startMachineButton->setStyleSheet(buttonStyle); startMachineLayout->addWidget(startMachineButton); grid->addWidget(startMachineWidget, 1, 0); //设置手动/自动启动 QWidget *handleSelfWidget = new QWidget(); QVBoxLayout *handleSelfLayout = new QVBoxLayout(handleSelfWidget); handleSelfLayout->setContentsMargins(0, 0, 0, 0); handleSelfLayout->setSpacing(2); QLabel *handleSelfLabel = new QLabel("手动/自动启动"); handleSelfLabel->setStyleSheet("color:#388087; font-weight: bold;"); handleSelfLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); handleSelfLayout->addWidget(handleSelfLabel); handleSelfButton = new QPushButton("设置手动/自动启动"); handleSelfButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); handleSelfButton->setStyleSheet(buttonStyle); handleSelfLayout->addWidget(handleSelfButton); grid->addWidget(handleSelfWidget, 1, 1); //工作模式按钮 QWidget *workModeWidget = new QWidget(); QVBoxLayout *workModeLayout = new QVBoxLayout(workModeWidget); workModeLayout->setContentsMargins(0, 0, 0, 0); workModeLayout->setSpacing(2); QLabel *workModeLabel = new QLabel("工作模式"); workModeLabel->setStyleSheet("color:#388087; font-weight: bold;"); workModeLayout->addWidget(workModeLabel); workModeLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); workModeButton = new QPushButton("选择工作模式"); workModeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); workModeButton->setStyleSheet(buttonStyle); // workModeButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); workModeLayout->addWidget(workModeButton); grid->addWidget(workModeWidget, 2, 0); QWidget *currencyWidget = new QWidget(); QVBoxLayout *currencyLayout = new QVBoxLayout(currencyWidget); currencyLayout->setContentsMargins(0, 0, 0, 0); currencyLayout->setSpacing(2); QLabel *currencyLabel = new QLabel("货币币种"); currencyLabel->setStyleSheet("color:#388087; font-weight: bold;"); currencyLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); currencyLayout->addWidget(currencyLabel); currencyButton = new QPushButton("获取货币币种"); currencyButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); currencyButton->setStyleSheet(buttonStyle); currencyLayout->addWidget(currencyButton); grid->addWidget(currencyWidget, 2, 1); //预置数按钮 QWidget *presetWidget = new QWidget(); QVBoxLayout *presetLayout = new QVBoxLayout(presetWidget); presetLayout->setContentsMargins(0, 0, 0, 0); presetLayout->setSpacing(2); QLabel *presetLabel = new QLabel("预置数"); presetLabel->setStyleSheet("color:#388087; font-weight: bold;"); presetLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); presetLayout->addWidget(presetLabel); presetButton = new QPushButton("设置预置数"); presetButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); presetButton->setStyleSheet(buttonStyle); presetLayout->addWidget(presetButton); grid->addWidget(presetWidget, 3, 0); //预置金额按钮 QWidget *presetAmountWidget = new QWidget(); QVBoxLayout *presetAmountLayout = new QVBoxLayout(presetAmountWidget); presetAmountLayout->setContentsMargins(0, 0, 0, 0); presetAmountLayout->setSpacing(2); QLabel *presetAmountLabel = new QLabel("预置金额"); presetAmountLabel->setStyleSheet("color:#388087; font-weight: bold;"); presetAmountLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); presetAmountLayout->addWidget(presetAmountLabel); presetAmountButton = new QPushButton("设置预置金额"); presetAmountButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); presetAmountButton->setStyleSheet(buttonStyle); presetAmountLayout->addWidget(presetAmountButton); grid->addWidget(presetAmountWidget, 3, 1); //走钞速度按钮 QWidget *speedWidget = new QWidget(); QVBoxLayout *speedLayout = new QVBoxLayout(speedWidget); speedLayout->setContentsMargins(0, 0, 0, 0); speedLayout->setSpacing(2); QLabel *speedLabel = new QLabel("走钞速度"); speedLabel->setStyleSheet("color:#388087; font-weight: bold;"); speedLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); speedLayout->addWidget(speedLabel); speedButton = new QPushButton("设置机器走钞速度"); speedButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); speedButton->setStyleSheet(buttonStyle); speedLayout->addWidget(speedButton); grid->addWidget(speedWidget, 4, 0); //版本清分按钮 QWidget *versionSortWidget = new QWidget(); QVBoxLayout *versionSortLayout = new QVBoxLayout(versionSortWidget); versionSortLayout->setContentsMargins(0, 0, 0, 0); versionSortLayout->setSpacing(2); QLabel *versionSortLabel = new QLabel("版本清分"); versionSortLabel->setStyleSheet("color:#388087; font-weight: bold;"); versionSortLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); versionSortLayout->addWidget(versionSortLabel); versionSortButton = new QPushButton("设置版本清分"); versionSortButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); versionSortButton->setStyleSheet(buttonStyle); versionSortLayout->addWidget(versionSortButton); grid->addWidget(versionSortWidget, 4, 1); //退钞口张数按钮 QWidget *rejectCountWidget = new QWidget(); QVBoxLayout *rejectCountLayout = new QVBoxLayout(rejectCountWidget); rejectCountLayout->setContentsMargins(0, 0, 0, 0); rejectCountLayout->setSpacing(2); QLabel *rejectCountLabel = new QLabel("退钞口张数"); rejectCountLabel->setStyleSheet("color:#388087; font-weight: bold;"); rejectCountLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); rejectCountLayout->addWidget(rejectCountLabel); rejectCountButton = new QPushButton("设置退钞口张数"); rejectCountButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); rejectCountButton->setStyleSheet(buttonStyle); rejectCountLayout->addWidget(rejectCountButton); grid->addWidget(rejectCountWidget, 5, 0); //查询货币组合按钮 QWidget *queryCurrencyWidget = new QWidget(); QVBoxLayout *queryCurrencyLayout = new QVBoxLayout(queryCurrencyWidget); queryCurrencyLayout->setContentsMargins(0, 0, 0, 0); queryCurrencyLayout->setSpacing(2); QLabel *queryCurrencyLabel = new QLabel("货币组合"); queryCurrencyLabel->setStyleSheet("color:#388087; font-weight: bold;"); queryCurrencyLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); queryCurrencyLayout->addWidget(queryCurrencyLabel); queryCurrencyButton = new QPushButton("查询货币组合"); queryCurrencyButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); queryCurrencyButton->setStyleSheet(buttonStyle); queryCurrencyLayout->addWidget(queryCurrencyButton); grid->addWidget(queryCurrencyWidget, 5, 1); QWidget *detailedListWidget = new QWidget(); QVBoxLayout *detailedListLayout = new QVBoxLayout(detailedListWidget); detailedListLayout->setContentsMargins(0, 0, 0, 0); detailedListLayout->setSpacing(2); QLabel *emptyLabel8 = new QLabel("明细列表"); emptyLabel8->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel8->setAlignment(Qt::AlignLeft | Qt::AlignBottom); detailedListLayout->addWidget(emptyLabel8); detailedlistButton = new QPushButton("获取明细列表"); detailedlistButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); detailedlistButton->setStyleSheet(buttonStyle); detailedListLayout->addWidget(detailedlistButton); grid->addWidget(detailedListWidget, 6, 0); QWidget *rejectListWidget = new QWidget(); QVBoxLayout *rejectListLayout = new QVBoxLayout(rejectListWidget); rejectListLayout->setContentsMargins(0, 0, 0, 0); rejectListLayout->setSpacing(2); QLabel *emptyLabel7 = new QLabel("退钞口信息列表"); emptyLabel7->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel7->setAlignment(Qt::AlignLeft | Qt::AlignBottom); rejectListLayout->addWidget(emptyLabel7); rejectListButton = new QPushButton("获取退钞口信息列表"); rejectListButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); rejectListButton->setStyleSheet(buttonStyle); rejectListLayout->addWidget(rejectListButton); grid->addWidget(rejectListWidget, 6, 1); //获取传感器电压 QWidget *SensorvoltageWidget = new QWidget(); QVBoxLayout *SensorvoltageLayout = new QVBoxLayout(SensorvoltageWidget); SensorvoltageLayout->setContentsMargins(0, 0, 0, 0); SensorvoltageLayout->setSpacing(2); QLabel *SensorvoltageLabel = new QLabel("传感器电压"); SensorvoltageLabel->setStyleSheet("color:#388087; font-weight: bold;"); SensorvoltageLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); SensorvoltageLayout->addWidget(SensorvoltageLabel); SensorvoltageButton = new QPushButton("获取传感器电压"); SensorvoltageButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); SensorvoltageButton->setStyleSheet(buttonStyle); SensorvoltageLayout->addWidget(SensorvoltageButton); grid->addWidget(SensorvoltageWidget, 7, 0); //防钓鱼传感器按钮 QWidget *antiFishWidget = new QWidget(); QVBoxLayout *antiFishLayout = new QVBoxLayout(antiFishWidget); antiFishLayout->setContentsMargins(0, 0, 0, 0); antiFishLayout->setSpacing(2); QLabel *antiFishLabel = new QLabel("防钓鱼"); antiFishLabel->setStyleSheet("color:#388087; font-weight: bold;"); antiFishLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); antiFishLayout->addWidget(antiFishLabel); ansiFishButton = new QPushButton("防钓鱼传感器"); ansiFishButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); ansiFishButton->setStyleSheet(buttonStyle); antiFishLayout->addWidget(ansiFishButton); grid->addWidget(antiFishWidget, 7, 1); //连接信号槽 connect(testButton, &QPushButton::clicked, this, &MainWindow::onGetDetailListClicked); connect(handshakeButton, &QPushButton::clicked, this, &MainWindow::onHandshakeClicked); connect(workModeButton, &QPushButton::clicked, this, &MainWindow::onWorkModeClicked); connect(currencyButton, &QPushButton::clicked, this, &MainWindow::onCurrencyButtonClicked); connect(presetButton, &QPushButton::clicked, this, &MainWindow::onPresetButtonClicked); connect(presetAmountButton, &QPushButton::clicked, this, &MainWindow::onPresetAmountButtonClicked); connect(rejectListButton, &QPushButton::clicked, this, &MainWindow::onGetRejectListClicked); connect(detailedlistButton, &QPushButton::clicked,this,&MainWindow::onDetailedlistClicked); connect(SensorvoltageButton, &QPushButton::clicked, this, &MainWindow::onSensorvoltageClicked); connect(speedButton,&QPushButton::clicked,this,&MainWindow::onSpeedButtonClicked); connect(versionSortButton,&QPushButton::clicked,this,&MainWindow::onVersionSortButtonClicked); connect(rejectCountButton, &QPushButton::clicked, this, &MainWindow::onRejectCountButtonClicked); connect(queryCurrencyButton, &QPushButton::clicked, this, &MainWindow::onSelectCurrency); connect(ansiFishButton,&QPushButton::clicked,this,&MainWindow::onAntiFishClicked); connect(startMachineButton, &QPushButton::clicked, this, &MainWindow::onStartMachineClicked); connect(handleSelfButton, &QPushButton::clicked, this, &MainWindow::onhandleSelfClicked); return page; } QWidget* MainWindow::createSecondCommandPage() { QWidget *page = new QWidget(); QGridLayout *grid = new QGridLayout(page); grid->setSpacing(10); grid->setContentsMargins(10, 10, 10, 10); //蜂鸣器按钮 QWidget *buzzerWidget = new QWidget(); QVBoxLayout *buzzerLayout = new QVBoxLayout(buzzerWidget); buzzerLayout->setContentsMargins(0, 0, 0, 0); buzzerLayout->setSpacing(2); buzzerLabel = new QLabel("蜂鸣器"); buzzerLabel->setStyleSheet("color:#388087; font-weight: bold;"); buzzerLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); buzzerLayout->addWidget(buzzerLabel); buzzerButton = new QPushButton("设置机器蜂鸣器"); buzzerButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); buzzerButton->setStyleSheet(buttonStyle); buzzerLayout->addWidget(buzzerButton); grid->addWidget(buzzerWidget, 0, 0); //防尘罩按钮 - 无label QWidget *dustCoverWidget = new QWidget(); QVBoxLayout *dustCoverLayout = new QVBoxLayout(dustCoverWidget); dustCoverLayout->setContentsMargins(0, 0, 0, 0); dustCoverLayout->setSpacing(2); //添加一个空的占位label,保持高度一致 QLabel *emptyLabel1 = new QLabel(); emptyLabel1->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel1->setAlignment(Qt::AlignLeft | Qt::AlignBottom); dustCoverLayout->addWidget(emptyLabel1); QPushButton *openDustCoverButton = new QPushButton("打开防尘罩"); openDustCoverButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); openDustCoverButton->setStyleSheet(buttonStyle); dustCoverLayout->addWidget(openDustCoverButton); grid->addWidget(dustCoverWidget,0, 1); //底部挡板按钮 - 无label QWidget *bottomGateWidget = new QWidget(); QVBoxLayout *bottomGateLayout = new QVBoxLayout(bottomGateWidget); bottomGateLayout->setContentsMargins(0, 0, 0, 0); bottomGateLayout->setSpacing(2); QLabel *emptyLabel2 = new QLabel(); emptyLabel2->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel2->setAlignment(Qt::AlignLeft | Qt::AlignBottom); bottomGateLayout->addWidget(emptyLabel2); QPushButton *openBottomGateButton = new QPushButton("打开底部挡板"); openBottomGateButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); openBottomGateButton->setStyleSheet(buttonStyle); bottomGateLayout->addWidget(openBottomGateButton); grid->addWidget(bottomGateWidget, 1, 0); //关闭防尘罩按钮 - 无label QWidget *closeDustCoverWidget = new QWidget(); QVBoxLayout *closeDustCoverLayout = new QVBoxLayout(closeDustCoverWidget); closeDustCoverLayout->setContentsMargins(0, 0, 0, 0); closeDustCoverLayout->setSpacing(2); QLabel *emptyLabel5 = new QLabel(); emptyLabel5->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel5->setAlignment(Qt::AlignLeft | Qt::AlignBottom); closeDustCoverLayout->addWidget(emptyLabel5); QPushButton *closeDustCoverButton = new QPushButton("关闭防尘罩"); closeDustCoverButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); closeDustCoverButton->setStyleSheet(buttonStyle); closeDustCoverLayout->addWidget(closeDustCoverButton); grid->addWidget(closeDustCoverWidget, 1, 1); //关闭底部挡板按钮 - 无label QWidget *closeBottomGateWidget = new QWidget(); QVBoxLayout *closeBottomGateLayout = new QVBoxLayout(closeBottomGateWidget); closeBottomGateLayout->setContentsMargins(0, 0, 0, 0); closeBottomGateLayout->setSpacing(2); QLabel *emptyLabel6 = new QLabel(); emptyLabel6->setStyleSheet("color:#388087; font-weight: bold;"); emptyLabel6->setAlignment(Qt::AlignLeft | Qt::AlignBottom); closeBottomGateLayout->addWidget(emptyLabel6); QPushButton *closeBottomGateButton = new QPushButton("关闭底部挡板"); closeBottomGateButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); closeBottomGateButton->setStyleSheet(buttonStyle); closeBottomGateLayout->addWidget(closeBottomGateButton); grid->addWidget(closeBottomGateWidget, 2, 0); //CIS校验按钮 QWidget *cisCheckWidget = new QWidget(); QVBoxLayout *cisCheckLayout = new QVBoxLayout(cisCheckWidget); cisCheckLayout->setContentsMargins(0, 0, 0, 0); cisCheckLayout->setSpacing(2); QLabel *cisCheckLabel = new QLabel("CIS校验"); cisCheckLabel->setStyleSheet("color:#388087; font-weight: bold;"); cisCheckLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); cisCheckLayout->addWidget(cisCheckLabel); cisCheckButton = new QPushButton("CIS传感器校验"); cisCheckButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); cisCheckButton->setStyleSheet(buttonStyle); cisCheckLayout->addWidget(cisCheckButton); grid->addWidget(cisCheckWidget, 2, 1); //出厂设置 QWidget *factoryResetWidget = new QWidget(); QVBoxLayout *factoryResetLayout = new QVBoxLayout(factoryResetWidget); factoryResetLayout->setContentsMargins(0, 0, 0, 0); factoryResetLayout->setSpacing(2); QLabel *factoryResetLabel = new QLabel(); factoryResetLabel->setStyleSheet("color:#388087; font-weight: bold;"); factoryResetLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); factoryResetLayout->addWidget(factoryResetLabel); QPushButton *factoryResetButton = new QPushButton("恢复出厂设置"); factoryResetButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); factoryResetButton->setStyleSheet(buttonStyle); factoryResetLayout->addWidget(factoryResetButton); grid->addWidget(factoryResetWidget, 3, 0); //按键功能按钮 QWidget *pressWidget = new QWidget(); QVBoxLayout *pressLayout = new QVBoxLayout(pressWidget); pressLayout->setContentsMargins(0, 0, 0, 0); pressLayout->setSpacing(2); QLabel *pressLabel = new QLabel("按键功能"); pressLabel->setStyleSheet("color:#388087; font-weight: bold;"); pressLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); pressLayout->addWidget(pressLabel); pressButton = new QPushButton("按键功能"); pressButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); pressButton->setStyleSheet(buttonStyle); pressLayout->addWidget(pressButton); grid->addWidget(pressWidget, 3, 1); //老化命令 QWidget *agingWidget = new QWidget(); QVBoxLayout *agingLayout = new QVBoxLayout(agingWidget); agingLayout->setContentsMargins(0, 0, 0, 0); agingLayout->setSpacing(2); QLabel *agingLabel = new QLabel("老化"); agingLabel->setStyleSheet("color:#388087; font-weight: bold;"); agingLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom); agingLayout->addWidget(agingLabel); agingButton = new QPushButton("准备老化"); agingButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); agingButton->setStyleSheet(buttonStyle); agingLayout->addWidget(agingButton); grid->addWidget(agingWidget, 4, 0); grid->setRowStretch(5, 1); //让第5行(索引4)占据剩余空间 //连接信号槽 connect(cisCheckButton, &QPushButton::clicked, this, [this](){ if(!m_serialWorker) { logMessage("串口未打开"); return; } setButtonActive(qobject_cast<QPushButton*>(sender())); sendCISCheckCommand(); }); connect(pressButton,&QPushButton::clicked,this,&MainWindow::onPressButtonClicked); connect(openDustCoverButton, &QPushButton::clicked, this, &MainWindow::onOpenDustCoverClicked); connect(openBottomGateButton, &QPushButton::clicked, this, &MainWindow::onOpenBottomGateClicked); connect(closeDustCoverButton, &QPushButton::clicked, this, &MainWindow::onCloseDustCoverClicked); connect(closeBottomGateButton, &QPushButton::clicked, this, &MainWindow::onCloseBottomGateClicked); connect(buzzerButton, &QPushButton::clicked, this, &MainWindow::onSetBuzzerClicked); connect(factoryResetButton, &QPushButton::clicked, this, &MainWindow::onFactoryResetClicked); connect(agingButton, &QPushButton::clicked, this, &MainWindow::onAgingClicked); return page; } #include "serialworker.h" #include <QDebug> #include <QSerialPortInfo> SerialWorker::SerialWorker(const QString &portName, qint32 baudRate, QObject *parent) : QThread(parent), m_portName(portName), m_serialPort(nullptr), m_running(false), m_baudRate(baudRate) { } SerialWorker::~SerialWorker() { stop(); } //设置波特率 void SerialWorker::setBaudRate(qint32 baudRate) { m_baudRate = baudRate; if(m_serialPort && m_serialPort->isOpen()) { m_serialPort->setBaudRate(m_baudRate); } } void SerialWorker::run() { // 检查串口是否已存在 bool portAvailable = false; const auto ports = QSerialPortInfo::availablePorts(); for(const QSerialPortInfo &port : ports) { if(port.portName() == m_portName) { portAvailable = true; break; } } if(!portAvailable) { emit errorOccurred(tr("串口 %1 不存在").arg(m_portName)); return; } m_serialPort = new QSerialPort(); m_serialPort->setPortName(m_portName); m_serialPort->setBaudRate(m_baudRate); //成员变量设置波特率 m_serialPort->setDataBits(QSerialPort::Data8); m_serialPort->setParity(QSerialPort::NoParity); m_serialPort->setStopBits(QSerialPort::OneStop); m_serialPort->setFlowControl(QSerialPort::NoFlowControl); if(!m_serialPort->open(QIODevice::ReadWrite)) { emit errorOccurred(tr("无法打开串口 %1: %2").arg(m_portName).arg(m_serialPort->errorString())); delete m_serialPort; m_serialPort = nullptr; return; } m_running = true; //读取串口数据 while(m_running) { if(m_serialPort->waitForReadyRead(100)) { //等待数据到达 QByteArray data = m_serialPort->readAll(); //读取可用数据 //尝试读取剩余数据 while(m_serialPort->waitForReadyRead(10)) { data += m_serialPort->readAll(); } emit dataReceived(data); //发送接收到的数据 } //检查串口是否仍然打开 if(!m_serialPort->isOpen()) { emit errorOccurred(tr("串口 %1 意外关闭").arg(m_portName)); break; } } //清理串口对象 if(m_serialPort) { m_serialPort->close(); delete m_serialPort; m_serialPort = nullptr; } } void SerialWorker::stop() { m_running = false; wait(); } void SerialWorker::send(const QByteArray &data) { //发送数据到串口 if(m_serialPort && m_serialPort->isOpen()) { if(m_serialPort->write(data) == -1) { emit errorOccurred(tr("发送数据失败: %1").arg(m_serialPort->errorString())); } } } 这个能否增加一个识别数据线是否断开呢,如果数据线断开我的PC就主动断开串口,并且在断开串口前在logMessage显示数据线已断开
<think>我们需要在SerialWorker中检测串口是否断开。一种方法是定期检查串口状态,但更有效的方法是利用串口错误信号。
在QSerialPort中,当发生错误(包括断开连接)时,会发出errorOccurred信号。我们可以连接这个信号,当检测到断开时,关闭串口并通知主线程。
修改SerialWorker类:
1. 在run函数中,连接errorOccurred信号到自定义槽函数,在槽函数中处理错误(特别是ResourceError,表示设备断开)。
2. 当检测到设备断开时,关闭串口并跳出循环,然后通知主界面。
但是,由于SerialWorker在独立的线程中运行,我们需要确保信号和槽是线程安全的(使用Qt::QueuedConnection)。
具体步骤:
1. 在SerialWorker类中定义一个槽函数handleSerialError,用于处理错误。
2. 在run函数中连接errorOccurred信号到handleSerialError槽。
3. 在handleSerialError中,如果错误是ResourceError(即设备断开),则设置标志并关闭串口。
同时,主窗口(MainWindow)也需要知道串口断开,以便更新界面。我们可以通过errorOccurred信号传递错误信息。
修改如下:</think>是的,可以在串口通信中添加数据线断开检测功能。以下是修改后的 `SerialWorker` 类实现,它会检测数据线断开并在断开时主动关闭串口,同时在断开前在日志中显示"数据线已断开":
```cpp
#include "serialworker.h"
#include <QDebug>
#include <QSerialPortInfo>
#include <QThread>
SerialWorker::SerialWorker(const QString &portName, qint32 baudRate, QObject *parent)
: QThread(parent), m_portName(portName), m_serialPort(nullptr), m_running(false), m_baudRate(baudRate)
{
// 设置定时器用于检测数据线断开
m_disconnectTimer = new QTimer(this);
m_disconnectTimer->setInterval(2000); // 每2秒检测一次
connect(m_disconnectTimer, &QTimer::timeout, this, &SerialWorker::checkPortDisconnected);
}
SerialWorker::~SerialWorker()
{
stop();
}
void SerialWorker::setBaudRate(qint32 baudRate)
{
m_baudRate = baudRate;
if(m_serialPort && m_serialPort->isOpen())
{
m_serialPort->setBaudRate(m_baudRate);
}
}
void SerialWorker::run()
{
// 检查串口是否已存在
bool portAvailable = false;
const auto ports = QSerialPortInfo::availablePorts();
for(const QSerialPortInfo &port : ports)
{
if(port.portName() == m_portName)
{
portAvailable = true;
break;
}
}
if(!portAvailable)
{
emit errorOccurred(tr("串口 %1 不存在").arg(m_portName));
return;
}
m_serialPort = new QSerialPort();
m_serialPort->setPortName(m_portName);
m_serialPort->setBaudRate(m_baudRate);
m_serialPort->setDataBits(QSerialPort::Data8);
m_serialPort->setParity(QSerialPort::NoParity);
m_serialPort->setStopBits(QSerialPort::OneStop);
m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
if(!m_serialPort->open(QIODevice::ReadWrite))
{
emit errorOccurred(tr("无法打开串口 %1: %2").arg(m_portName).arg(m_serialPort->errorString()));
delete m_serialPort;
m_serialPort = nullptr;
return;
}
m_running = true;
// 启动数据线断开检测定时器
m_disconnectTimer->start();
//读取串口数据
while(m_running)
{
if(m_serialPort->waitForReadyRead(100))
{
//等待数据到达
QByteArray data = m_serialPort->readAll(); //读取可用数据
//尝试读取剩余数据
while(m_serialPort->waitForReadyRead(10))
{
data += m_serialPort->readAll();
}
emit dataReceived(data); //发送接收到的数据
}
//检查串口是否仍然打开
if(!m_serialPort->isOpen())
{
emit errorOccurred(tr("串口 %1 意外关闭").arg(m_portName));
break;
}
}
// 停止检测定时器
m_disconnectTimer->stop();
//清理串口对象
if(m_serialPort)
{
m_serialPort->close();
delete m_serialPort;
m_serialPort = nullptr;
}
}
void SerialWorker::stop()
{
m_running = false;
wait();
}
void SerialWorker::send(const QByteArray &data)
{
//发送数据到串口
if(m_serialPort && m_serialPort->isOpen())
{
if(m_serialPort->write(data) == -1)
{
emit errorOccurred(tr("发送数据失败: %1").arg(m_serialPort->errorString()));
}
}
}
// 检测数据线是否断开
void SerialWorker::checkPortDisconnected()
{
if(!m_serialPort || !m_serialPort->isOpen())
return;
bool portExists = false;
const auto ports = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &port : ports) {
if (port.portName() == m_portName) {
portExists = true;
break;
}
}
if (!portExists) {
// 在日志中显示数据线已断开
emit errorOccurred(tr("数据线已断开"));
// 主动关闭串口
if (m_serialPort) {
m_serialPort->close();
delete m_serialPort;
m_serialPort = nullptr;
}
// 停止工作线程
m_running = false;
// 通知主线程串口已关闭
emit portClosed();
}
}
```
### 修改说明:
1. **添加定时检测机制**:
- 在 `SerialWorker` 类中添加了 `QTimer` 成员 `m_disconnectTimer`
- 构造函数中初始化定时器并设置间隔为2秒
- 定时器连接到 `checkPortDisconnected` 槽函数
2. **实现数据线断开检测**:
```cpp
void SerialWorker::checkPortDisconnected()
{
if(!m_serialPort || !m_serialPort->isOpen())
return;
bool portExists = false;
const auto ports = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &port : ports) {
if (port.portName() == m_portName) {
portExists = true;
break;
}
}
if (!portExists) {
// 在日志中显示数据线已断开
emit errorOccurred(tr("数据线已断开"));
// 主动关闭串口
if (m_serialPort) {
m_serialPort->close();
delete m_serialPort;
m_serialPort = nullptr;
}
// 停止工作线程
m_running = false;
// 通知主线程串口已关闭
emit portClosed();
}
}
```
3. **线程生命周期管理**:
- 在 `run()` 方法中启动定时器
- 在 `run()` 方法结束时停止定时器
- 在检测到断开时发出 `portClosed()` 信号通知主线程
4. **主窗口需要连接的信号**:
在 `MainWindow` 类中,需要连接以下信号:
```cpp
// 在创建 SerialWorker 后连接
connect(m_serialWorker, &SerialWorker::portClosed, this, [this](){
toggleConnection(); // 切换连接状态
logMessage("串口已主动关闭:数据线已断开");
});
connect(m_serialWorker, &SerialWorker::errorOccurred, this, &MainWindow::logMessage);
```
### 工作原理:
1. 串口工作线程启动后,定时器每2秒检查一次串口是否存在
2. 当检测到串口从系统中消失(数据线被拔出),立即:
- 发送 "数据线已断开" 错误消息
- 主动关闭串口
- 停止工作线程
- 发出 `portClosed()` 信号通知主窗口
3. 主窗口收到信号后更新UI状态并记录日志
这种实现方式确保了当数据线被拔出时,程序能够及时检测到并优雅地关闭串口连接,避免程序处于半连接状态。
阅读全文
相关推荐

















