Qt的QComboBox点击时自动更新列表(自动刷新QSerialPort)

本文介绍如何在Qt中实现QComboBox点击时自动更新列表并触发QSerialPort的刷新。通过覆盖主窗口的eventFilter函数,监听QComboBox的鼠标点击事件来实现这一功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用QComboBox的鼠标点击事件,触发选项更新。具体方式为覆写主窗体的eventFilter函数。

1.在MainWindow头文件中加入:

private slots:
	bool eventFilter(QObject *watched, QEvent *event);

2. 在MainWindow构造函数中安装QComboBox的事件过滤器:

ui->comboBoxSerialPort->installEventFilter(this);

3. 实现该函数:

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonPress)
    {
        if(watched == ui->comboBoxSerialPort)
        {
            QComboBox* comboBox = qobject_cast<QComboBox *>(watched);

            comboBox->clear();

            QList<QSerialPortInfo> serials = QSerialPortInfo::availablePorts();
            foreach (QSerialPortInfo info, serials)
            {
                comboBox->addItem(info.portName());
            }
        }
    }
    return QMainWindow::eventFilter(watched, event);
}

Qt | QComboBox点击时自动更新列表(自动刷新QSerialPort)_雍正不秃头的博客-优快云博客_qcombobox点击事件

<think>我们使用Qt5的QSerialPort模块来实现串口调试助手。主要步骤包括: 1. 在.pro文件中添加serialport模块 2. 获取可用串口列表并显示 3. 打开和关闭串口 4. 发送数据 5. 接收数据并显示 6. 设置串口参数(波特率、数据位、停止位、校验位等) 根据引用[2],我们需要在.pro文件中添加: QT += core gui serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 下面我们逐步实现: 步骤1:创建项目 - 使用Qt Creator创建一个新的Qt Widgets Application项目。 - 在.pro文件中添加上述模块。 步骤2:设计UI - 在mainwindow.ui中,我们可以添加以下控件: QComboBox:用于选择串口号 QPushButton:刷新串口、打开串口、关闭串口、发送数据 QComboBox:波特率(常用9600,115200等)、数据位(5,6,7,8)、停止位(1,1.5,2)、校验位(无、奇、偶、标记、空格) QTextEdit:用于显示接收到的数据 QLineEdit或QTextEdit:用于输入要发送的数据 QCheckBox:是否自动发送换行符(如回车换行) 步骤3:编写代码 在mainwindow.h中: #include <QMainWindow> #include <QSerialPort> #include <QSerialPortInfo> private slots: void on_btnRefresh_clicked(); // 刷新串口 void on_btnOpen_clicked(); // 打开串口 void on_btnClose_clicked(); // 关闭串口 void on_btnSend_clicked(); // 发送数据 void readData(); // 读取串口数据 private: QSerialPort *serial; 在mainwindow.cpp中: 初始化串口对象,并连接信号与槽。 详细代码实现如下: mainwindow.h: ```cpp #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSerialPort> #include <QSerialPortInfo> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_btnRefresh_clicked(); void on_btnOpen_clicked(); void on_btnClose_clicked(); void on_btnSend_clicked(); void readData(); private: Ui::MainWindow *ui; QSerialPort *serial; }; #endif // MAINWINDOW_H ``` mainwindow.cpp: ```cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QMessageBox> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); serial = new QSerialPort(this); // 连接读取数据的信号 connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData); // 初始刷新串口列表 on_btnRefresh_clicked(); // 初始化波特率等选项 ui->baudRateBox->addItem("9600"); ui->baudRateBox->addItem("19200"); ui->baudRateBox->addItem("38400"); ui->baudRateBox->addItem("115200"); ui->baudRateBox->setCurrentIndex(3); // 默认115200 ui->dataBitsBox->addItem("5"); ui->dataBitsBox->addItem("6"); ui->dataBitsBox->addItem("7"); ui->dataBitsBox->addItem("8"); ui->dataBitsBox->setCurrentIndex(3); // 默认8 ui->stopBitsBox->addItem("1"); ui->stopBitsBox->addItem("1.5"); ui->stopBitsBox->addItem("2"); ui->stopBitsBox->setCurrentIndex(0); // 默认1 ui->parityBox->addItem("None"); ui->parityBox->addItem("Even"); ui->parityBox->addItem("Odd"); ui->parityBox->addItem("Mark"); ui->parityBox->addItem("Space"); ui->parityBox->setCurrentIndex(0); // 默认无校验 } MainWindow::~MainWindow() { delete ui; } // 刷新串口 void MainWindow::on_btnRefresh_clicked() { ui->portNameBox->clear(); foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { ui->portNameBox->addItem(info.portName()); } } // 打开串口 void MainWindow::on_btnOpen_clicked() { serial->setPortName(ui->portNameBox->currentText()); serial->setBaudRate(ui->baudRateBox->currentText().toInt()); // 数据位 switch (ui->dataBitsBox->currentIndex()) { case 0: serial->setDataBits(QSerialPort::Data5); break; case 1: serial->setDataBits(QSerialPort::Data6); break; case 2: serial->setDataBits(QSerialPort::Data7); break; case 3: serial->setDataBits(QSerialPort::Data8); break; default: break; } // 停止位 switch (ui->stopBitsBox->currentIndex()) { case 0: serial->setStopBits(QSerialPort::OneStop); break; case 1: serial->setStopBits(QSerialPort::OneAndHalfStop); break; case 2: serial->setStopBits(QSerialPort::TwoStop); break; default: break; } // 校验位 switch (ui->parityBox->currentIndex()) { case 0: serial->setParity(QSerialPort::NoParity); break; case 1: serial->setParity(QSerialPort::EvenParity); break; case 2: serial->setParity(QSerialPort::OddParity); break; case 3: serial->setParity(QSerialPort::MarkParity); break; case 4: serial->setParity(QSerialPort::SpaceParity); break; default: break; } if (serial->open(QIODevice::ReadWrite)) { ui->statusBar->showMessage(tr("串口已打开")); ui->btnOpen->setEnabled(false); ui->btnClose->setEnabled(true); } else { QMessageBox::critical(this, tr("错误"), serial->errorString()); } } // 关闭串口 void MainWindow::on_btnClose_clicked() { if (serial->isOpen()) { serial->close(); ui->statusBar->showMessage(tr("串口已关闭")); ui->btnOpen->setEnabled(true); ui->btnClose->setEnabled(false); } } // 发送数据 void MainWindow::on_btnSend_clicked() { if (!serial->isOpen()) { QMessageBox::warning(this, tr("警告"), tr("串口未打开")); return; } QString data = ui->sendEdit->toPlainText(); // 假设发送区是一个QTextEdit if (data.isEmpty()) { return; } // 如果勾选了自动发送换行,则添加换行符 if (ui->checkBox_newline->isChecked()) { data += "\r\n"; } serial->write(data.toUtf8()); } // 读取数据 void MainWindow::readData() { QByteArray data = serial->readAll(); if (data.isEmpty()) { return; } // 将数据显示在接收区 ui->recvEdit->appendPlainText(QString(data)); // 假设接收区是一个QPlainTextEdit } ``` 步骤4:UI设计 在Qt Designer中,我们需要放置以下控件(控件名称可以自定义): 端口号:QComboBox -> portNameBox 刷新按钮:QPushButton -> btnRefresh 打开按钮:QPushButton -> btnOpen 关闭按钮:QPushButton -> btnClose 波特率:QComboBox -> baudRateBox 数据位:QComboBox -> dataBitsBox 停止位:QComboBox -> stopBitsBox 校验位:QComboBox -> parityBox 发送区:QTextEdit -> sendEdit 接收区:QPlainTextEdit -> recvEdit (使用QPlainTextEdit可以显示大量文本) 发送按钮:QPushButton -> btnSend 自动换行:QCheckBox -> checkBox_newline 注意:在UI设计中,请确保将接收区的QPlainTextEdit设置为只读(readOnly属性为true)。 步骤5:测试 编译运行程序,连接串口设备(如USB转串口模块)进行测试。 以上就是一个简单的串口调试助手的实现。根据引用[1]和引用[2]的提示,我们实现了基本的串口通信功能。 注意:在实际应用中,可能还需要添加更多功能,如十六进制发送和显示、自动发送、保存接收数据等。但以上代码已经实现了基本功能。 如果遇到问题,可以检查串口是否被其他程序占用,或者串口参数设置是否正确。 引用说明: [1] 提供了实现串口调试助手的背景和参考。 [2] 提供了.pro文件的配置和获取串口列表的方法。 [3] 提供了main.cpp的示例,但我们在MainWindow中实现功能。 根据用户需求,我们提供了C++和Qt5实现串口调试助手的基本步骤和代码。 §§相关问题§§ 1. 如何实现串口数据的十六进制发送和显示? 2. 如何实现定自动发送数据? 3. 如何保存串口接收到的数据到文件?</think>### 使用Qt5实现简单串口调试助手 以下是基于Qt5实现串口调试助手的完整步骤和代码示例: #### 1. 环境配置 在项目文件(`.pro`)中添加串口模块依赖: ```qmake QT += core gui serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets ``` #### 2. 主窗口设计(`mainwindow.ui`) 创建包含以下控件的UI界面: - 串口号选择框(QComboBox) - 波特率选择框(QComboBox) - 打开/关闭按钮(QPushButton) - 数据接收文本框(QTextEdit) - 数据发送输入框(QLineEdit) - 发送按钮(QPushButton) #### 3. 核心代码实现 **mainwindow.h** 头文件: ```cpp #include <QMainWindow> #include <QSerialPort> #include <QSerialPortInfo> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void refreshPorts(); // 刷新串口列表 void toggleConnection(); // 打开/关闭串口 void sendData(); // 发送数据 void readData(); // 读取数据 private: Ui::MainWindow *ui; QSerialPort *serial; }; ``` **mainwindow.cpp** 实现文件: ```cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include <QMessageBox> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), serial(new QSerialPort(this)) { ui->setupUi(this); // 初始化波特率选项 ui->baudRateBox->addItems({"9600", "19200", "38400", "57600", "115200"}); ui->baudRateBox->setCurrentIndex(4); // 默认115200 // 连接信号槽 connect(ui->refreshButton, &QPushButton::clicked, this, &MainWindow::refreshPorts); connect(ui->connectButton, &QPushButton::clicked, this, &MainWindow::toggleConnection); connect(ui->sendButton, &QPushButton::clicked, this, &MainWindow::sendData); connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData); // 初始刷新串口列表 refreshPorts(); } MainWindow::~MainWindow() { delete ui; } // 刷新可用串口 void MainWindow::refreshPorts() { ui->portBox->clear(); foreach (const QSerialPortInfo &port, QSerialPortInfo::availablePorts()) { ui->portBox->addItem(port.portName()); } } // 打开/关闭串口连接 void MainWindow::toggleConnection() { if (serial->isOpen()) { serial->close(); ui->connectButton->setText("打开串口"); ui->statusbar->showMessage("串口已关闭"); } else { serial->setPortName(ui->portBox->currentText()); serial->setBaudRate(ui->baudRateBox->currentText().toInt()); if (serial->open(QIODevice::ReadWrite)) { ui->connectButton->setText("关闭串口"); ui->statusbar->showMessage("已连接: " + serial->portName()); } else { QMessageBox::critical(this, "错误", "无法打开串口: " + serial->errorString()); } } } // 发送数据 void MainWindow::sendData() { if (!serial->isOpen()) { QMessageBox::warning(this, "警告", "请先打开串口"); return; } QByteArray data = ui->sendEdit->text().toUtf8(); serial->write(data); ui->sendEdit->clear(); } // 接收数据 void MainWindow::readData() { QByteArray data = serial->readAll(); ui->receiveText->append(QString::fromUtf8(data)); } ``` #### 4. 主程序入口(`main.cpp`) ```cpp #include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } ``` #### 5. 功能说明 1. **串口管理**: - 自动检测可用串口 - 支持波特率选择(9600-115200) - 打开/关闭连接控制 2. **数据传输**: - 文本数据发送 - 实接收显示 - 支持UTF-8编码 3. **界面设计**: - 接收区自动滚动显示 - 状态栏连接状态提示 - 错误处理机制 #### 6. 使用说明 1. 点击 **刷新** 按钮扫描可用串口 2. 选择目标串口和波特率 3. 点击 **打开串口** 建立连接 4. 在发送框输入数据后点击 **发送** 5. 接收区自动显示返回数据 > 注意:实际使用需确保串口未被其他程序占用,且波特率与设备设置一致[^1][^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值