一、QT下的三驾马车
1、QT的串口编程
QT的串口编程使用QtSerialPort模块,它提供了对串口设备的支持,使得应用程序能够方便地与硬件设备通过串口进行通信。串口编程常用于设备通信、数据采集等领域。
- 初始化串口: 使用 QSerialPort 类来创建串口对象,设置串口的基本属性,如波特率、数据位、停止位等。
QSerialPort *serial = new QSerialPort(this);
serial->setPortName("COM1"); // 设置串口名称
serial->setBaudRate(QSerialPort::Baud9600); // 设置波特率
serial->setDataBits(QSerialPort::Data8); // 数据位
serial->setParity(QSerialPort::NoParity); // 校验位
serial->setStopBits(QSerialPort::OneStop); // 停止位
- 打开串口:
if (serial->open(QIODevice::ReadWrite)) {
qDebug() << "串口打开成功!";
} else {
qDebug() << "串口打开失败!";
}
- 数据发送与接收: 发送数据可以通过 write() 方法,接收数据可以使用 readyRead() 信号来监听。
serial->write("Hello, Serial Port!"); // 发送数据
connect(serial, &QSerialPort::readyRead, this, &MainWindow::onReadyRead);
- 数据接收方法:
void MainWindow::onReadyRead() {
QByteArray data = serial->readAll(); // 读取串口数据
qDebug() << data;
}
2、QT下的网络编程
QT支持多种网络协议的编程,主要使用 QTcpSocket 和 QTcpServer 类来进行TCP协议的编程。
- 客户端网络编程: 使用 QTcpSocket 类来创建客户端与服务器进行通信。
QTcpSocket *socket = new QTcpSocket(this);
socket->connectToHost("localhost", 1234); // 连接到服务器
socket->write("Hello, Server!"); // 发送数据
- 服务器端编程: 使用 QTcpServer 类来创建一个简单的服务器。
QTcpServer *server = new QTcpServer(this);
if (server->listen(QHostAddress::Any, 1234)) {
qDebug() << "服务器已启动!";
} else {
qDebug() << "服务器启动失败!";
}
connect(server, &QTcpServer::newConnection, this, &MainWindow::onNewConnection);
客户端连接到服务器后,接收到的连接可以通过 newConnection 信号来处理。
3、QT下的GPIO
在QT中,GPIO(通用输入输出)通常通过操作底层硬件接口来进行控制,例如通过/dev/下的文件进行输入输出。在QT中并没有直接的GPIO模块,因此通常需要借助底层操作系统的接口进行GPIO编程。
二、仿写串口助手
步骤一:做好UI界面
仿写串口助手的第一步是创建一个界面,界面通常包括以下组件:
-
接收框:显示从串口接收到的数据
![[Pasted image 20250415110752.png]] -
发送框:用户输入要发送的数据
![[Pasted image 20250415110823.png]] -
发送按钮:点击后将发送框中的数据发送出去
-
串口配置区:包括串口号选择、波特率选择、数据位选择、校验位选择、停止位选择等
-
打开/关闭串口按钮:用于打开或关闭串口
步骤二:实现串口操作功能
- 打开串口:
void MainWindow::on_OpenButton_clicked() {
QString portName = ui->comboBoxPortName->currentText();
int baudRate = ui->comboBoxBaudRate->currentText().toInt();
QString dataBits = ui->comboBoxDataBits->currentText();
QString parity = ui->comboBoxParity->currentText();
QString stopBits = ui->comboBoxStopBits->currentText();
serial->setPortName(portName);
serial->setBaudRate(baudRate);
// 设置其他串口参数...
if (serial->open(QIODevice::ReadWrite)) {
ui->OpenButton->setText("关闭");
qDebug() << "串口打开成功!";
} else {
qDebug() << "串口打开失败!";
}
}
- 关闭串口:
void MainWindow::on_CloseButton_clicked() {
serial->close();
ui->OpenButton->setText("打开");
qDebug() << "串口已关闭!";
}
- 发送数据:
void MainWindow::on_SendButton_clicked() {
QString data = ui->SendTextEdit->toPlainText();
serial->write(data.toUtf8());
qDebug() << "发送数据: " << data;
}
- 接收数据:
void MainWindow::onReadyRead() {
QByteArray data = serial->readAll();
ui->ReceiveTextEdit->append(data);
qDebug() << "接收到数据: " << data;
}
步骤三:实现其他功能
- 自动换行:在接收框中实现自动换行功能,方便查看数据
- 清空接收框:添加一个按钮,点击后清空接收框中的内容
- 保存接收数据:将接收的数据保存到文件中
- 打开串口时的错误处理:处理打开串口时可能出现的各种错误
串口代码案例:
#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QString>
#include <QMessageBox>
// 构造函数:初始化 UI 和串口设置
Widget::Widget(QWidget *parent) :
QWidget(parent), // 调用 QWidget 构造函数
ui(new Ui::Widget) // 初始化 UI 对象
{
ui->setupUi(this); // 设置 UI 界面
QStringList serialNamePort;
// 创建一个字符串列表,用于存储串口名称
serialPort = new QSerialPort(this);
// 创建 QSerialPort 对象,用于串口通信
// 连接串口的 readyRead 信号到槽函数 serialPortReadyRead_slot
connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialPortReadyRead_slot()));
// 遍历可用的串口,并将串口名称添加到 combobox 中
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
serialNamePort << info.portName();
// 将串口名称加入列表
ui->serialCb->addItems(serialNamePort);
// 将串口名称添加到界面上的 comboBox 中
}
}
// 析构函数:清理内存
Widget::~Widget()
{
delete ui; // 删除 UI 对象,释放内存
}
// 串口数据读取槽函数:每次串口有数据时被调用
void Widget::serialPortReadyRead_slot()
{
QString buf;
// 创建字符串变量,用于存储接收到的数据
buf = QString(serialPort->readAll());
// 读取串口的所有数据并转换为 QString 格式
ui->recvEdit->appendPlainText(buf);
// 将接收到的数据添加到界面上的接收框中
}
// 打开串口按钮的点击事件
void Widget::on_OpenBt_clicked()
{
QSerialPort::BaudRate bauRates; // 声明变量,用于存储波特率
QSerialPort::DataBits dataBits; // 声明变量,用于存储数据位
QSerialPort::StopBits stopBits; // 声明变量,用于存储停止位
QSerialPort::Parity checkBits; // 声明变量,用于存储校验位
// 根据 combobox 中选择的波特率设置 bauRates
if(ui->baundrateCb->currentText() == "4800")
{
bauRates = QSerialPort::Baud4800;
}else if(ui->baundrateCb->currentText() == "9600") {
bauRates = QSerialPort::Baud9600;
}else if(ui->baundrateCb->currentText() == "115200") {
bauRates = QSerialPort::Baud115200;
}
// 根据 combobox 中选择的数据位设置 dataBits
if(ui->dataCb->currentText() == "5") {
dataBits = QSerialPort::Data5;
}else if(ui->dataCb->currentText() == "6") {
dataBits = QSerialPort::Data6;
}else if(ui->dataCb->currentText() == "7") {
dataBits = QSerialPort::Data7;
} else if(ui->dataCb->currentText() == "8") {
dataBits = QSerialPort::Data8;
}
// 根据 combobox 中选择的停止位设置 stopBits
if(ui->stopCb->currentText() == "1") {
stopBits = QSerialPort::OneStop;
} else if(ui->stopCb->currentText() == "1.5") {
stopBits = QSerialPort::OneAndHalfStop;
} else if(ui->stopCb->currentText() == "2") {
stopBits = QSerialPort::TwoStop;
}
// 根据 combobox 中选择的校验位设置 checkBits
if(ui->checkCb->currentText() == "none") {
checkBits = QSerialPort::NoParity;
}
// 设置串口的各种属性
serialPort->setPortName(ui->serialCb->currentText()); // 设置串口名称
serialPort->setBaudRate(bauRates); // 设置波特率
serialPort->setDataBits(dataBits); // 设置数据位
serialPort->setStopBits(stopBits); // 设置停止位
serialPort->setParity(checkBits); // 设置校验位
// 打开串口,如果成功则弹出提示框
if(serialPort->open(QIODevice::ReadWrite)) {
QMessageBox::information(this, "提示", "成功打开串口"); // 打开成功,弹出提示框
} else {
QMessageBox::critical(this, "错误", "无法打开串口"); // 打开失败,弹出错误框
}
}
// 关闭串口按钮的点击事件
void Widget::on_CloseBt_clicked()
{
serialPort->close(); // 关闭串口
}
// 发送数据按钮的点击事件
void Widget::on_SendBt_clicked()
{
// 获取文本框中的内容并发送到串口
serialPort->write(ui->sendEdit->text().toLocal8Bit().data());
}
// 清空接收区按钮的点击事件
void Widget::on_ClearBt_clicked()
{
ui->recvEdit->clear(); // 清空接收框中的内容
}
// 串口回车换行按钮的点击事件
void Widget::on_checkBox_stateChanged(int arg1)
{
QString a = "\r\n"; // 定义回车换行字符
serialPort->write(a.toLocal8Bit().data()); // 向串口发送回车换行字符
}