当前位置: 首页 > news >正文

QT(c++)开发自学笔记:1.串口

新建工程与界面介绍

新建文件,不要选错成Application (Qt for python)了

这里选择QDialog

新建之后可以点开看到文件夹中的dialog.cpp

#include "dialog.h"
#include "./ui_dialog.h"Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);
}Dialog::~Dialog()
{delete ui;
}
  • Dialog::Dialog(QWidget *parent):这是成员函数的定义,使用作用域解析运算符 :: 指定函数属于Dialog类。函数名与类名相同,表示构造函数。参数列表(QWidget *parent) 定义了一个指针参数parent,类型为QWidget*(Qt的窗口部件基类指针),用于传递父窗口指针。
  • : QDialog(parent):这是初始化列表(Initializer List)的开始,以冒号:开头,用于在函数体执行前初始化基类和成员变量。格式为: 成员/基类(参数)。调用基类QDialog的构造函数,传递parent参数。QDialog是Qt的对话框基类,这里实现继承初始化。
  • , ui(new Ui::Dialog):初始化列表的延续,以逗号,分隔多个初始化项。初始化成员变量ui(在头文件中声明为Ui::Dialog *ui;),使用new动态分配内存,创建Ui::Dialog对象的实例。Ui::Dialog是命名空间Ui下的类(Qt UI生成)。
  • { ui->setupUi(this); }:函数体,用花括号{}包围。内部语句ui->setupUi(this);
    • ui->:使用箭头运算符->访问指针ui指向的对象成员。
    • setupUi(this):调用Ui::Dialog类的成员函数setupUi,参数this是当前对象指针(Dialog*),用于将UI控件绑定到当前对话框。
  • Dialog::~Dialog():表示析构函数(Destructor),销毁对话框。无参数列表(),且无返回值类型。
  • { delete ui; }:函数体,用{}包围。内部语句delete ui;
    • delete 是C++运算符,用于释放动态分配的内存(对应构造函数中的new)。
    • ui 是指针变量,delete ui 会调用Ui::Dialog的析构函数并释放内存。

一些快捷键

ctrl+B:编译

ctrl+R:运行

F4:再.h和.cpp直接切换

添加控件的基本形式

新建之后,点开dialog.ui

新建一个ComBox

点击该框,右下角可以改名

注意左下角的控件

报错问题:当前QT版本不支持串口

        运行完程序之后,会自动弹出QT支持包,选择一个版本功能中有”Serial Port“功能的进行安装(比如我6.9.2不支持串口,但是6.9.3可以),然后再到左侧框”项目“选项中把6.9.3相关的全部运行,6.9.2的给关掉

注意:只开前两个,后面两个不要开(我这样之后仍然报错,仍未解决) 所以采用以下方法:

直接打开Qt维护工具,也就是MaintenanceTool.exe

把6.9.2给全部取消勾选,点下一步

然后等移除之后,新建一个工程,刚才那个工程的东西全部复制过来算了

完整添加控件和代码

添加以下控件,并精确设置objectName(在属性编辑器中,右上角的Property Editor):

控件类型objectName(名称)布局建议位置
QComboBoxcomboBoxPort上方,选择串口
QComboBoxcomboBoxBaud上方,选择波特率
QPushButtonpushButtonOpen中间,打开/关闭按钮
QLineEditlineEditSend下方,发送输入框
QPushButtonpushButtonSend下方,发送按钮
QTextEdittextEditReceive最下方,接收显示区(设置readOnly=true,便于只读)

        

最终布局类似于这样:

dialog.h文件代码如下:

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QSerialPort>
#include <QSerialPortInfo>QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();private slots:void openSerialPort();void closeSerialPort();void sendData();void readData();private:Ui::Dialog *ui;QSerialPort *serial;
};#endif // DIALOG_H

dialog.cpp代码如下:

#include "dialog.h"
#include "./ui_dialog.h"
#include <QDebug>
#include <QMessageBox>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog), serial(new QSerialPort(this))
{ui->setupUi(this);// 假设UI元素:ui->comboBoxPort (QComboBox for ports), ui->comboBoxBaud (QComboBox for baud rates),// ui->pushButtonOpen (QPushButton for open/close), ui->textEditReceive (QTextEdit for received data),// ui->lineEditSend (QLineEdit for send data), ui->pushButtonSend (QPushButton for send).// 填充可用串口for (const QSerialPortInfo &info : QSerialPortInfo::availablePorts()) {ui->comboBoxPort->addItem(info.portName());}// 填充常见波特率ui->comboBoxBaud->addItems({"9600", "19200", "38400", "57600", "115200"});// 连接信号槽connect(ui->pushButtonOpen, &QPushButton::clicked, this, &Dialog::openSerialPort);connect(ui->pushButtonSend, &QPushButton::clicked, this, &Dialog::sendData);connect(serial, &QSerialPort::readyRead, this, &Dialog::readData);connect(serial, QOverload<QSerialPort::SerialPortError>::of(&QSerialPort::errorOccurred),this, [](QSerialPort::SerialPortError error) {if (error != QSerialPort::NoError) {qDebug() << "Serial port error:" << error;}});serial->setBaudRate(QSerialPort::Baud9600); // 默认波特率serial->setDataBits(QSerialPort::Data8);serial->setParity(QSerialPort::NoParity);serial->setStopBits(QSerialPort::OneStop);serial->setFlowControl(QSerialPort::NoFlowControl);
}Dialog::~Dialog()
{if (serial->isOpen()) {serial->close();}delete ui;
}void Dialog::openSerialPort()
{if (serial->isOpen()) {closeSerialPort();} else {serial->setPortName(ui->comboBoxPort->currentText());serial->setBaudRate(ui->comboBoxBaud->currentText().toInt());if (serial->open(QIODevice::ReadWrite)) {ui->pushButtonOpen->setText("关闭串口");QMessageBox::information(this, "成功", "串口打开成功");} else {QMessageBox::warning(this, "错误", "无法打开串口: " + serial->errorString());}}
}void Dialog::closeSerialPort()
{if (serial->isOpen()) {serial->close();ui->pushButtonOpen->setText("打开串口");QMessageBox::information(this, "成功", "串口关闭成功");}
}void Dialog::sendData()
{if (serial->isOpen() && !ui->lineEditSend->text().isEmpty()) {QByteArray data = ui->lineEditSend->text().toUtf8();serial->write(data);ui->lineEditSend->clear();} else {QMessageBox::warning(this, "错误", "串口未打开或发送数据为空");}
}void Dialog::readData()
{if (serial->bytesAvailable()) {QByteArray data = serial->readAll();ui->textEditReceive->append(data);}
}

main.cpp代码如下:

#include "dialog.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}

CMakeLists.txt代码如下:

cmake_minimum_required(VERSION 3.16)project(Text1004Test VERSION 0.1 LANGUAGES CXX)# 手动指定Qt 6.9.3完整路径(用正斜杠,无空格;替换为您的确切路径,例如 D:/QTWorks/6.9.3/mingw_64)
set(CMAKE_PREFIX_PATH "D:/QTWorks/6.9.3/mingw_64")set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 临时调试:启用详细查找日志(构建后移除)
# set(CMAKE_FIND_DEBUG_MODE TRUE)# 查找Qt 6(优先),包含Widgets和SerialPort组件
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets SerialPort)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets SerialPort)# 调试输出:打印找到的Qt路径和组件状态
message(STATUS "Qt Version: ${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}")
message(STATUS "Qt Install Prefix: ${Qt6_DIR}/..")
message(STATUS "SerialPort Found: ${Qt6SerialPort_FOUND}")  # 应为TRUEset(PROJECT_SOURCESmain.cppdialog.cppdialog.hdialog.ui  # 确保包含.ui文件
)if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)qt_add_executable(Text1004TestMANUAL_FINALIZATION${PROJECT_SOURCES})
else()if(ANDROID)add_library(Text1004Test SHARED${PROJECT_SOURCES})else()add_executable(Text1004Test${PROJECT_SOURCES})endif()
endif()# 链接Widgets和SerialPort
target_link_libraries(Text1004Test PRIVATEQt${QT_VERSION_MAJOR}::WidgetsQt${QT_VERSION_MAJOR}::SerialPort
)# iOS/macOS捆绑设置
if(${QT_VERSION} VERSION_LESS 6.1.0)set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.Text1004Test)
endif()
set_target_properties(Text1004Test PROPERTIES${BUNDLE_ID_OPTION}MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}MACOSX_BUNDLE TRUEWIN32_EXECUTABLE TRUE
)include(GNUInstallDirs)
install(TARGETS Text1004TestBUNDLE DESTINATION .LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)if(QT_VERSION_MAJOR EQUAL 6)qt_finalize_executable(Text1004Test)
endif()

然后再下个串口调试助手,开一对虚拟串口,两个互选一下试试互发消息

能互相收到就成功了,这个简单的例子可以用来熟悉一下这种”控件+代码“的设计模式

http://www.dtcms.com/a/442499.html

相关文章:

  • 最小外接矩形2显示四条边缘
  • 什么是网站建设与维护潘嘉严个人网站
  • 天津做网站哪家好如何申请域名后缀
  • MCP(trae)+ wireshark-提高干活效率
  • 机器视觉3D检测中,.ply(Polygon File Format) 3D点云格式
  • 如何网站优化排名做兼职比较正规的网站
  • 兰亭妙微高端网站设计案例:品牌官网如何做到美学与转化并重
  • 网站主机提供商:选择与您业务相匹配的托管服务
  • Linux学习笔记--insmod 命令
  • 做树状图的网站html全屏网站
  • 网站页面设计师如何编辑网站模板
  • 网站服务器网络企业网站设计方案
  • 数仓一些问题
  • 君正T32开发笔记之AOV实例介绍
  • 包含HPA配置与资源限制示例
  • 做影视网站用主机还是用服务器合肥网络优化公司有几家
  • 网站开发属于哪个部门贵阳网站建设电话
  • fiddler详解
  • 系统版本管理规范:从分支策略到发布流程
  • 【LLM-RL】GRPO->DAPO->GSPO训练区别
  • 建设中心小学网站上海16个区排名
  • Linux下查看和关闭进程的方法
  • 【ROS2学习笔记】动作
  • 李宏毅machine learning 2021学习笔记——Vit
  • 第三十一篇|AI 驱动的教育数据建模:以冈山外语学院为样本的结构化分析
  • 深圳网站的优化公司哪家好wordpress上传代码
  • 架构学习之旅-架构的由来
  • 洛阳市建设工程评标专家网站网站开发长沙
  • 专业的数字化转型培训方案哪家好
  • 第68篇:AI+零售:智能推荐、无人商店与需求预测