点击上方"蓝字"关注我们
01、QSerialPort
QSerialPort是Qt框架中的一个类,用于串行通信。它提供了一个简单的接口,允许开发者通过串口与外部设备(如传感器、相机、单片机等)进行数据交换。QSerialPort支持多种串口操作,可以方便地设置波特率、数据位、停止位和校验位等通信参数。
主要特性:
设备管理:可以列出系统中的可用串口。
异步与同步读写:支持异步和同步的数据传输,允许开发者根据需要选择合适的方式。
信号与槽机制:利用Qt的信号与槽机制,处理数据接收、错误检测等事件。
流控制:支持软硬件流控制,保证数据传输的可靠性和完整性。
多平台支持:QSerialPort在多个操作系统上均可使用,包括Windows、Linux和macOS。
02、QPlainTextEdit
QPlainTextEdit是Qt框架中提供的一个类,用于显示和编辑纯文本内容。与QTextEdit不同,QPlainTextEdit专注于处理大量文本数据,并且仅支持简单的文本格式,不支持富文本(例如富文本编辑和格式化文本)。它适用于需要高效处理大文本的场景,如源代码编辑器和日志查看器。
主要特性:
高效性:QPlainTextEdit专为处理大文本而设计,适用于高性能需求。
文本处理功能:支持基本的文本操作,如查找、替换、选择、撤销和重做等。
行号显示:可以通过自定义实现添加行号显示功能,使其更适合代码编辑器的需求。
信号与槽机制:可以方便地与Qt的信号与槽机制结合,监听文本变化等事件。
自定义高亮:能够通过自定义实现语法高亮功能,适用于编程语言的文本编辑。
03、QSerialPortInfo
QSerialPortInfo是Qt框架中的一个类,用于提供有关可用串口的信息。它主要用于收集和展示系统上串口的状态和属性,以便开发者可以选择合适的串口进行通信。该类的功能通常与QSerialPort配合使用,帮助应用程序动态检测和管理串口设备。
主要特性:
- 获取系统串口信息:可以查询系统中所有可用的串口及其相关信息,如名称、描述、制造商等。
- 状态检查:可以检查串口是否当前可用或被占用,帮助开发者选择合适的串口进行连接。
- 简便的接口:提供一系列静态方法,使得获取串口信息更加方便和直观。
- 多平台支持:QSerialPortInfo在多个操作系统上都可以使用,适用于不同的硬件环境。
常用方法:
availablePorts(): 返回当前系统中所有可用串口的信息列表。
portName(): 返回串口的名称。
description(): 返回串口的描述信息。
manufacturer(): 返回串口的制造商信息。
isNull(): 检查QSerialPortInfo对象是否有效。
04、QIntValidator
QIntValidator是Qt框架中的一个类,用于为输入框或其他文本编辑组件提供整数值的验证。它允许开发者限制用户输入的范围,确保输入的值为有效的整数,并且可以设置该整数的最小和最大值。
主要特性:
整数输入验证:确保用户输入的是有效的整数值。
范围限制:可以设置最小值和最大值,确保输入在指定范围内。
与文本框结合使用:通常与QLineEdit等文本输入框结合使用,可以在输入过程中即时验证。
支持本地化:可以处理不同区域格式的数字输入(例如,千位分隔符等)。
05、项目实战
【转存慢慢看】
通过网盘分享的文件:terminal
链接: pan.baidu.com/s/1TZX33uo-… 提取码: pbiw
看看标准的代码规范
06、.pro
Qt6.5.3
QT += widgets # 添加 widgetsrequires(qtConfig(combobox)) # 确保组合框配置可用QT += serialportTARGET = terminal # 设置目标名称为 terminalTEMPLATE = app # 定义模板为应用程序SOURCES += \ # 指定源代码文件 main.cpp \ # 主程序文件 mainwindow.cpp \ # 主窗口实现文件 settingsdialog.cpp \ # 设置对话框实现文件 console.cpp # 控制台实现文件HEADERS += \ # 指定头文件 mainwindow.h \ # 主窗口头文件 settingsdialog.h \ # 设置对话框头文件 console.h # 控制台头文件FORMS += \ # 指定 UI 表单文件 mainwindow.ui \ # 主窗口设计文件 settingsdialog.ui # 设置对话框设计文件RESOURCES += \ # 指定资源文件 terminal.qrc # 资源描述文件# target.path = $$[QT_INSTALL_EXAMPLES]/serialport/terminal # 定义安装目标路径# INSTALLS += target # 添加目标到安装列表
07、settingsdialog.cpp
重点只分享部分代码,记得自己下载。
#include "settingsdialog.h"#include "ui_settingsdialog.h"#include <QIntValidator>#include <QLineEdit>#include <QSerialPortInfo>// 定义一个空字符串常量用于表示未适用的设置static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");// SettingsDialog 类的构造函数SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), // 调用父类构造函数 m_ui(new Ui::SettingsDialog), // 创建 UI 对象 m_intValidator(new QIntValidator(0, 4000000, this)) // 创建整数验证器,范围从 0 到 4000000{ m_ui->setupUi(this); // 设置用户界面 m_ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert); // 设置波特率下拉框不允许插入 // 连接信号与槽 connect(m_ui->applyButton, &QPushButton::clicked, this, &SettingsDialog::apply); // 连接应用按钮的点击信号 connect(m_ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsDialog::showPortInfoSlot); // 连接串口信息列表框索引变化的信号 connect(m_ui->baudRateBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsDialog::checkCustomBaudRatePolicySLot); // 连接波特率下拉框索引变化的信号 connect(m_ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SettingsDialog::checkCustomDevicePathPolicySlot); // 连接串口信息列表框索引变化的信号 fillPortsParameters(); // 填充端口参数 fillPortsInfo(); // 填充端口信息 updateSettings(); // 更新设置}// SettingsDialog 类的析构函数SettingsDialog::~SettingsDialog(){ delete m_ui; // 删除 UI 对象}// 获取当前设置SettingsDialog::Settings SettingsDialog::settings() const{ return m_currentSettings;}// 显示所选串口的信息void SettingsDialog::showPortInfoSlot(int idx){ if (idx == -1) // 如果索引无效,返回 return; const QStringList list = m_ui->serialPortInfoListBox->itemData(idx).toStringList(); // 获取串口信息 m_ui->descriptionLabel->setText(tr("描述: %1").arg(list.count() > 1 ? list.at(1) : tr(blankString))); // 设置描述标签 m_ui->manufacturerLabel->setText(tr("制造商: %1").arg(list.count() > 2 ? list.at(2) : tr(blankString))); // 设置制造商标签 m_ui->serialNumberLabel->setText(tr("序列号: %1").arg(list.count() > 3 ? list.at(3) : tr(blankString))); // 设置序列号标签 m_ui->locationLabel->setText(tr("位置: %1").arg(list.count() > 4 ? list.at(4) : tr(blankString))); // 设置位置标签 m_ui->vidLabel->setText(tr("供应商标识符: %1").arg(list.count() > 5 ? list.at(5) : tr(blankString))); // 设置供应商标识符标签 m_ui->pidLabel->setText(tr("产品标识符: %1").arg(list.count() > 6 ? list.at(6) : tr(blankString))); // 设置产品标识符标签}// 应用当前设置void SettingsDialog::apply(){ updateSettings(); // 更新设置 hide(); // 隐藏对话框}// 检查自定义波特率策略void SettingsDialog::checkCustomBaudRatePolicySLot(int idx){ const bool isCustomBaudRate = !m_ui->baudRateBox->itemData(idx).isValid(); // 判断是否是自定义波特率 m_ui->baudRateBox->setEditable(isCustomBaudRate); // 设置波特率框是否可编辑 if (isCustomBaudRate) { m_ui->baudRateBox->clearEditText(); // 清空编辑文本 QLineEdit *edit = m_ui->baudRateBox->lineEdit(); // 获取波特率输入框 edit->setValidator(m_intValidator); // 设置输入验证器 }}// 检查自定义设备路径策略void SettingsDialog::checkCustomDevicePathPolicySlot(int idx){ const bool isCustomPath = !m_ui->serialPortInfoListBox->itemData(idx).isValid(); // 判断是否是自定义设备路径 m_ui->serialPortInfoListBox->setEditable(isCustomPath); // 设置设备路径框是否可编辑 if (isCustomPath) m_ui->serialPortInfoListBox->clearEditText(); // 清空编辑文本}// 填充端口参数void SettingsDialog::fillPortsParameters(){ m_ui->baudRateBox->addItem(QStringLiteral("9600"), QSerialPort::Baud9600); // 添加波特率 9600 m_ui->baudRateBox->addItem(QStringLiteral("19200"), QSerialPort::Baud19200); // 添加波特率 19200 m_ui->baudRateBox->addItem(QStringLiteral("38400"), QSerialPort::Baud38400); // 添加波特率 38400 m_ui->baudRateBox->addItem(QStringLiteral("115200"), QSerialPort::Baud115200); // 添加波特率 115200 m_ui->baudRateBox->addItem(tr("自定义")); // 添加自定义波特率选项 m_ui->dataBitsBox->addItem(QStringLiteral("5"), QSerialPort::Data5); // 添加数据位 5 m_ui->dataBitsBox->addItem(QStringLiteral("6"), QSerialPort::Data6); // 添加数据位 6 m_ui->dataBitsBox->addItem(QStringLiteral("7"), QSerialPort::Data7); // 添加数据位 7 m_ui->dataBitsBox->addItem(QStringLiteral("8"), QSerialPort::Data8); // 添加数据位 8 m_ui->dataBitsBox->setCurrentIndex(3); // 设置当前选中的数据位为 8 m_ui->parityBox->addItem(tr("无"), QSerialPort::NoParity); // 添加无校验选项 m_ui->parityBox->addItem(tr("偶校验"), QSerialPort::EvenParity); // 添加偶校验选项 m_ui->parityBox->addItem(tr("奇校验"), QSerialPort::OddParity); // 添加奇校验选项 m_ui->parityBox->addItem(tr("标记校验"), QSerialPort::MarkParity); // 添加标记校验选项 m_ui->parityBox->addItem(tr("空格校验"), QSerialPort::SpaceParity); // 添加空格校验选项 m_ui->stopBitsBox->addItem(QStringLiteral("1"), QSerialPort::OneStop); // 添加停止位 1#ifdef Q_OS_WIN m_ui->stopBitsBox->addItem(tr("1.5"), QSerialPort::OneAndHalfStop); // 添加停止位 1.5(仅限 Windows)#endif m_ui->stopBitsBox->addItem(QStringLiteral("2"), QSerialPort::TwoStop); // 添加停止位 2 m_ui->flowControlBox->addItem(tr("无"), QSerialPort::NoFlowControl); // 添加无流控选项 m_ui->flowControlBox->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl); // 添加 RTS/CTS 硬件流控选项 m_ui->flowControlBox->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl); // 添加 XON/XOFF 软件流控选项}// 填充可用端口信息void SettingsDialog::fillPortsInfo(){ m_ui->serialPortInfoListBox->clear(); // 清空串口信息列表框 QString description; // 描述 QString manufacturer; // 制造商 QString serialNumber; // 序列号 const auto infos = QSerialPortInfo::availablePorts(); // 获取可用串口信息 for (const QSerialPortInfo &info : infos) { QStringList list; // 用于存储串口信息的列表 description = info.description(); // 获取串口描述 manufacturer = info.manufacturer(); // 获取制造商 serialNumber = info.serialNumber(); // 获取序列号 list << info.portName() // 串口名称 << (!description.isEmpty() ? description : blankString) // 描述 << (!manufacturer.isEmpty() ? manufacturer : blankString) // 制造商 << (!serialNumber.isEmpty() ? serialNumber : blankString) // 序列号 << info.systemLocation() // 系统位置 << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : blankString) // 供应商标识符 << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : blankString); // 产品标识符 m_ui->serialPortInfoListBox->addItem(list.first(), list); // 将信息添加到列表框 } m_ui->serialPortInfoListBox->addItem(tr("自定义")); // 添加自定义选项}// 更新当前设置void SettingsDialog::updateSettings(){ m_currentSettings.name = m_ui->serialPortInfoListBox->currentText(); // 获取当前选择的串口名称 // 获取波特率 if (m_ui->baudRateBox->currentIndex() == 4) { // 如果选择的是自定义波特率 m_currentSettings.baudRate = m_ui->baudRateBox->currentText().toInt(); // 获取自定义波特率 } else { m_currentSettings.baudRate = static_cast<QSerialPort::BaudRate>( m_ui->baudRateBox->itemData(m_ui->baudRateBox->currentIndex()).toInt()); // 获取选择的波特率 } m_currentSettings.stringBaudRate = QString::number(m_currentSettings.baudRate); // 转换为字符串表示 m_currentSettings.dataBits = static_cast<QSerialPort::DataBits>( m_ui->dataBitsBox->itemData(m_ui->dataBitsBox->currentIndex()).toInt()); // 获取数据位 m_currentSettings.stringDataBits = m_ui->dataBitsBox->currentText(); // 转换为字符串表示 m_currentSettings.parity = static_cast<QSerialPort::Parity>( m_ui->parityBox->itemData(m_ui->parityBox->currentIndex()).toInt()); // 获取校验位 m_currentSettings.stringParity = m_ui->parityBox->currentText(); // 转换为字符串表示 m_currentSettings.stopBits = static_cast<QSerialPort::StopBits>( m_ui->stopBitsBox->itemData(m_ui->stopBitsBox->currentIndex()).toInt()); // 获取停止位 m_currentSettings.stringStopBits = m_ui->stopBitsBox->currentText(); // 转换为字符串表示 m_currentSettings.flowControl = static_cast<QSerialPort::FlowControl>( m_ui->flowControlBox->itemData(m_ui->flowControlBox->currentIndex()).toInt()); // 获取流控 m_currentSettings.stringFlowControl = m_ui->flowControlBox->currentText(); // 转换为字符串表示 m_currentSettings.localEchoEnabled = m_ui->localEchoCheckBox->isChecked(); // 获取本地回显选项是否启用}
08、mainwindow.ui
09、settingsdialog.ui
10、演示
第一步 配置
第二步 设置
第三步 连接
连接成功,敲回车,即进入了串口终端。就像linux终端。
总结
代码整洁、规范、封装、信号与槽连接都要好好看,要有编程之美的思维。