首页
统计
留言
投币
友链
关于
Search
1
抖音鸡汤(一)
15 阅读
2
扩展:268条PCB Layout设计规范!
7 阅读
3
新版Keilv5安装相关问题大全
7 阅读
4
Arduino库介绍——AccelStepper
6 阅读
5
Ubuntu系统——虚拟机ubuntu22.04没有网
3 阅读
基础
CPP语法
算法题
硬件设计
PCBLayout
电子设计
单片机
ESP32
STM32
STC51
Arduino
LuatOS
FreeRTOS
LVGL
Linux
QT
树莓派
T113S3
Linux系统
Linux应用开发
Linux驱动开发
IoT
MQTT
Lora
NB-IOT
米家
涂鸦
AI
OpenCV
项目
杂谈 | 日记
投资笔记
登录
Search
标签搜索
Arduino
ESP32
PCBLayout
鸡汤
ubuntu
步进电机
KEIL
CPP
QT
OTA
会焊工的程序猿
累计撰写
10
篇文章
累计收到
0
条评论
首页
栏目
基础
CPP语法
算法题
硬件设计
PCBLayout
电子设计
单片机
ESP32
STM32
STC51
Arduino
LuatOS
FreeRTOS
LVGL
Linux
QT
树莓派
T113S3
Linux系统
Linux应用开发
Linux驱动开发
IoT
MQTT
Lora
NB-IOT
米家
涂鸦
AI
OpenCV
项目
杂谈 | 日记
投资笔记
页面
统计
留言
投币
友链
关于
搜索到
1
篇与
的结果
2026-02-02
QT开发入门笔记——北京迅为
1 QT工程1.1qt基础qt的移植性非常的强。一套代码我们不用改太多,直接通用所有的平台。不久的将来,qt会被用到MCU上,学习QT还是非常有意义的。1.2做一个简单的qt界面如何创建一个QT工程?步骤一:步骤二:不要有中文路径步骤三:工程文件分析:点击forms,然后双击ui文件,就可以进入ui编辑器。ui编辑器面板介绍:做一个简单的QQ登录界面,我们用到组件放图片,放文本,放gif图的组件就是 qlabel 放账号和密码的对话框我们用的组件是 qlinedit 按钮我们使用的组件是 qpushbutton1.3关联信号和槽自动关联:在ui界面里,右键点击对应的控件->转到槽自动关联会给我们的工程添加以下内容:槽函数只能声明到private slots或者public slots 下面。(QT特有)手动关联:使用connect这个函数。connect(ui->logoBt,SIGNAL(clicked()),this,SLOT(logoBt_clicked_slots())); connect(A,SIGNAL(B),C,SLOT(D));//当对象A发出B信号时候,就会触发对象C的槽函数D1.4添加图片图标下载网址: iconfont-阿里巴巴矢量图标库1、添加图片:右键项目名->添加新文件->Qt->Qt Resource FileResourrces文件夹下右键.qrc文件->Open with->资源编辑器-添加前缀(一般默认根文件)->Crtl+S 保存文件->添加文件 注意:记得保存!!!2、引用图片右击想要的控件->改变样式表->添加资源->border-image。可以添加多张照片。1.5添加新的页面右键项目名->添加新文件->Qt->Qt 设计师类界面->设置类名26、28行,创建类的对象。问题:在这个类下随意创建一个对象就是我们在编辑的ui界面void MainWindow::on_loginBt_clicked() { qDebug() << "loginBt_clicked"; QString ssid = ui->ssidEdit->text(); QString pwd = ui->pswdEdit->text(); if(ssid == "yyx" && pwd == "123")//判断密码 { ctrl* ct = new ctrl; ct->setGeometry(this->geometry());//读取窗口的高宽数据进行设置 ct->show();//显示跳转的页面 } } void ctrl::on_backBt_clicked() { this->close();//这句话就可以关闭本文件对应的界面 }2 QT三驾马车qt下的串口编程,网络编程(TCP UDP),操作GPIO3 串口编程3.1自制串口调试助手3.1.1串口调试助手界面设计做一个串口调试助手需要用到的组件如下接受框:属性选择:发送框:UI设计界面如下:3.1.2串口调试助手程序设计由于版本比较高,会出现字体大小不合适的情况,需要在吗main.cpp里添加一段代码#include "widget.h" #include <QApplication> #include <iconv.h> int main(int argc, char* argv[]) { if(QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))//判断QT版本 { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); } QApplication a(argc, argv); Widget w; w.setWindowTitle("阿轩串口调试助手 V1.0.0");//界面程序名称 w.show(); return a.exec(); }需要在xxx.pro文件里上serialport库,QT += core gui serialport界面操作代码#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QSerialPort> #include <QString> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget* parent = nullptr); ~Widget(); QSerialPort* serialPort = new QSerialPort(this); void serial_open_Bt_state();//串口打开时按钮盒选项的状态 void serial_close_Bt_state();//串口关闭时按钮盒选项的状态 private slots: void on_openBt_clicked(); void serialPortReadyRead_Slot(); void on_sendBt_clicked(); void on_clearBt_clicked(); void on_pushButton_1_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); void on_pushButton_4_clicked(); void on_pushButton_5_clicked(); void on_pushButton_6_clicked(); void on_pushButton_7_clicked(); void on_pushButton_8_clicked(); void on_pushButton_9_clicked(); void on_pushButton_10_clicked(); void on_pushButton_11_clicked(); void on_pushButton_12_clicked(); void on_pushButton_13_clicked(); void on_pushButton_14_clicked(); void on_pushButton_15_clicked(); private: Ui::Widget* ui; }; #endif // WIDGET_H #include "widget.h" #include "ui_widget.h" #include <QSerialPortInfo> #include <QMessageBox> bool serial_state = false; Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); QStringList serialNamePort; foreach (const QSerialPortInfo& info, QSerialPortInfo::availablePorts())//自动检测端口 { serialNamePort << info.portName(); } ui->serialCb->addItems(serialNamePort);//自动检测到的端口输出给串口选择框 connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialPortReadyRead_Slot()));//检测串口收到的数据 serial_close_Bt_state();//启动时默认是未打开 } Widget::~Widget() { delete ui; } //串口打开之后一些按钮状态需要改变 void Widget::serial_open_Bt_state() { ui->sendBt->setEnabled(true); ui->pushButton_1->setEnabled(true); ui->pushButton_2->setEnabled(true); ui->pushButton_3->setEnabled(true); ui->pushButton_4->setEnabled(true); ui->pushButton_5->setEnabled(true); ui->pushButton_6->setEnabled(true); ui->pushButton_7->setEnabled(true); ui->pushButton_8->setEnabled(true); ui->pushButton_9->setEnabled(true); ui->pushButton_10->setEnabled(true); ui->pushButton_11->setEnabled(true); ui->pushButton_12->setEnabled(true); ui->pushButton_13->setEnabled(true); ui->pushButton_14->setEnabled(true); ui->pushButton_15->setEnabled(true); ui->serialCb->setEnabled(false); ui->baundrateCb->setEnabled(false); ui->dataCb->setEnabled(false); ui->checkCb->setEnabled(false); ui->stopCb->setEnabled(false); } //串口关闭后一些按钮状态也需要改变 void Widget::serial_close_Bt_state() { ui->sendBt->setEnabled(false); ui->pushButton_1->setEnabled(false); ui->pushButton_2->setEnabled(false); ui->pushButton_3->setEnabled(false); ui->pushButton_4->setEnabled(false); ui->pushButton_5->setEnabled(false); ui->pushButton_6->setEnabled(false); ui->pushButton_7->setEnabled(false); ui->pushButton_8->setEnabled(false); ui->pushButton_9->setEnabled(false); ui->pushButton_10->setEnabled(false); ui->pushButton_11->setEnabled(false); ui->pushButton_12->setEnabled(false); ui->pushButton_13->setEnabled(false); ui->pushButton_14->setEnabled(false); ui->pushButton_15->setEnabled(false); ui->serialCb->setEnabled(true); ui->baundrateCb->setEnabled(true); ui->dataCb->setEnabled(true); ui->checkCb->setEnabled(true); ui->stopCb->setEnabled(true); } //读取串口发来的信息并显示 void Widget::serialPortReadyRead_Slot() { QString buf; buf = QString(serialPort->readAll()); ui->recvEdit->appendPlainText(buf); } //串口开关按钮 void Widget::on_openBt_clicked() { if(serial_state == false) { QSerialPort::BaudRate baudRate;//波特率 QSerialPort::DataBits dataBits;//数据位 QSerialPort::StopBits stopBits;//停止位 QSerialPort::Parity checkBits;//校验位 //读取选择的波特率 if(ui->baundrateCb->currentText() == "1200") { baudRate = QSerialPort::Baud1200; } else if(ui->baundrateCb->currentText() == "2400") { baudRate = QSerialPort::Baud2400; } else if(ui->baundrateCb->currentText() == "4800") { baudRate = QSerialPort::Baud4800; } else if(ui->baundrateCb->currentText() == "9600") { baudRate = QSerialPort::Baud9600; } else if(ui->baundrateCb->currentText() == "19200") { baudRate = QSerialPort::Baud19200; } else if(ui->baundrateCb->currentText() == "38400") { baudRate = QSerialPort::Baud38400; } else if(ui->baundrateCb->currentText() == "57600") { baudRate = QSerialPort::Baud57600; } else if(ui->baundrateCb->currentText() == "115200") { baudRate = QSerialPort::Baud115200; } //读取选择的数据位 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; } //读取选择的停止位 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; } //读取选择的效验位 if(ui->checkCb->currentText() == "none") { checkBits = QSerialPort::NoParity; } serialPort->setPortName(ui->serialCb->currentText());//设置串口号 serialPort->setBaudRate(baudRate);//设置波特率 serialPort->setDataBits(dataBits);//设置数据位 serialPort->setStopBits(stopBits);//设置停止位 serialPort->setParity(checkBits);//设置校验位 //打开并判断是否打开成功 if(serialPort->open(QIODevice::ReadWrite) == true) { //QMessageBox::information(this, "提示", "成功"); // ui->labelstate->setText("串口已打开");//弹窗 serial_state = true; serial_open_Bt_state(); ui->openBt->setText("关闭串口"); } else { QMessageBox::information(this, "提示", "失败"); } } else { serialPort->close(); // ui->labelstate->setText("串口关闭");//弹窗 serial_state = false; serial_close_Bt_state(); ui->openBt->setText("打开串口"); } } void Widget::on_sendBt_clicked() { serialPort->write(ui->sendEdit->text().toLocal8Bit().data());//转为QByteString类型字符串,并且再转换成char*发送,防止乱码 serialPort->write("\r\n"); } void Widget::on_clearBt_clicked() { ui->recvEdit->clear(); } void Widget::on_pushButton_1_clicked() { serialPort->write(ui->lineEdit_1->text().toLocal8Bit().data()); } void Widget::on_pushButton_2_clicked() { serialPort->write(ui->lineEdit_2->text().toLocal8Bit().data()); } void Widget::on_pushButton_3_clicked() { serialPort->write(ui->lineEdit_3->text().toLocal8Bit().data()); } void Widget::on_pushButton_4_clicked() { serialPort->write(ui->lineEdit_4->text().toLocal8Bit().data()); } void Widget::on_pushButton_5_clicked() { serialPort->write(ui->lineEdit_5->text().toLocal8Bit().data()); } void Widget::on_pushButton_6_clicked() { serialPort->write(ui->lineEdit_6->text().toLocal8Bit().data()); } void Widget::on_pushButton_7_clicked() { serialPort->write(ui->lineEdit_7->text().toLocal8Bit().data()); } void Widget::on_pushButton_8_clicked() { serialPort->write(ui->lineEdit_8->text().toLocal8Bit().data()); } void Widget::on_pushButton_9_clicked() { serialPort->write(ui->lineEdit_9->text().toLocal8Bit().data()); } void Widget::on_pushButton_10_clicked() { serialPort->write(ui->lineEdit_10->text().toLocal8Bit().data()); } void Widget::on_pushButton_11_clicked() { serialPort->write(ui->lineEdit_11->text().toLocal8Bit().data()); } void Widget::on_pushButton_12_clicked() { serialPort->write(ui->lineEdit_12->text().toLocal8Bit().data()); } void Widget::on_pushButton_13_clicked() { serialPort->write(ui->lineEdit_13->text().toLocal8Bit().data()); } void Widget::on_pushButton_14_clicked() { serialPort->write(ui->lineEdit_14->text().toLocal8Bit().data()); } void Widget::on_pushButton_15_clicked() { serialPort->write(ui->lineEdit_15->text().toLocal8Bit().data()); } 4 软件打包成windows可执行文件QT如何打包生成独立可执行.exe文件_qt打包成可执行程序-CSDN博客4.1我们把工厂切换到release模式,然后编译release模式:基本没有调试信息。debug模式:有很多调试信息。4.2改一下图标先把图标加到工程所在文件夹。然后在pro文件里面添加RC_ICONS=serial_iocn.ico注意:图标的格式必须为.ico这个格式的,其他格式不行。4.3封包操作4.3.1将QT程序使用Release编译**4.3.2新建一个文件夹,将Release编译生成的exe文件复制到新建文件夹中先找到Release编译生成的exe文件夹位置,与项目创建的文件夹有关: 临时文件夹 --》 release --》 xx .exe文件 比如我的这个就是在D:\QtPro\build-Serial-Desktop_Qt_5_12_9_MinGW_64_bit-Release\release 把exe文件拷贝出来 随便在哪创建一个空的文件夹,然后将.exe文件拷贝进去 比如我在E盘新建了QTtest文件夹 4.3.3使用命令终端添加程序所需的依赖库在开始菜单中找到Qt命令终端(版本可能不一样打开对应版本就行),进入刚才新建的文件夹目录,使用 windeployqt 对生成的exe 文件进行打配置动态库文件: 一般来说,打开命令行终端后默认是在QT的安装路径下,这样需要先把路径切过去到exe文件的路径下再使用 windeployqt 命令 + .exe文件名操作或者直接windeployqt + .exe文件绝对路径 这样就成功了,可以双击exe文件测试是否可以正常打开。 到这一步其实可以选择把整个文件夹打个压缩包,然后就可以发送到其他PC端使用了,只需解压缩即可。 如果还觉得麻烦,想只用一个exe文件就能独立工作,那就接着往下操作。4.4合并打包程序(下面的步骤只适用于Windows系统下)4.4.1安装Enigma virtual box工具Enigma Virtual Box是软件虚拟化工具,它可以将多个文件封装到应用程序主文件,从而制作成为单执行文件的绿色软件。它支持所有类型的文件格式,虚拟化后的软件不释放任何临时文件到您的硬盘,文件模拟过程仅在内存运行。Enigma virtual box官方链接:https://enigmaprotector.com/cn/downloads.html 进入官网后找到红框部分点击下载即可,不需要注册账号: 下载后点击安装,安装过程一直next就行,注意勾选创建桌面快捷方式,默认是不创建的。 安装好后打开可以设置中文语言: 4.4.2打开安装好的Enigma Virtual Box,点击浏览,找到第三步的目录下的exe文件4.4.3点击增加,选择递归添加文件,选中demo文件夹点击确定4.4.4选择目标文件夹后点击确定4.4.5点击文件选项,选中压缩文件,点击确定4.4.6最后点击执行封包,等待结束即可。4.4.7最终生成的文件名和路径,找到该文件双击打开测试是否正常至此整个打包过程结束5 网络编程(TCP UDP)QT的网络编程:网络编程有TCP和UDP。5.1TCP协议TCP编程需要用到俩个类:QTcpServer和QTcpSocket查找帮助可知都需要添加network5.1.1服务器设计#include "widget.h" #include "ui_widget.h" // 构造函数,初始化Widget对象 Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // 设置UI tcpServer = new QTcpServer(this); // 创建一个新的QTcpServer对象 tcpSocket = new QTcpSocket(this); // 创建一个新的QTcpSocket对象 // 连接信号和槽,当有新的连接时调用newConnection_Slot槽函数 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection_Slot())); } // 槽函数,当有新的连接时调用 void Widget::newConnection_Slot() { tcpSocket = tcpServer->nextPendingConnection(); // 获取下一个挂起的连接 // 连接信号和槽,当有数据可读时调用readyRead_Slot槽函数 connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); } // 槽函数,当有数据可读时调用 void Widget::readyRead_Slot() { // 将读取到的数据追加到recvTextEdit文本编辑器中 ui->recvTextEdit->appendPlainText(tcpSocket->readAll()); } // 析构函数,清理资源 Widget::~Widget() { delete ui; // 删除UI对象 } // 槽函数,当打开按钮被点击时调用 void Widget::on_openBt_clicked() { // 监听所有IP地址和端口,端口号从portEdit文本框中获取并转换为无符号整数 tcpServer->listen(QHostAddress::Any, ui->portEdit->text().toUInt()); } // 槽函数,当关闭按钮被点击时调用 void Widget::on_closeBt_clicked() { tcpServer->close(); // 关闭服务器 } // 槽函数,当发送按钮被点击时调用 void Widget::on_sendBt_clicked() { // 发送sendEdit文本框中的数据,数据转换为本地8位字节数组 // 发送前需要转换一下,转为QByteString类型字符串,并且再转换成char*发送,防止乱码 tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data()); } 5.2.2客户端设计#include "widget.h" #include "ui_widget.h" // 构造函数,初始化Widget对象 Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // 设置UI tcpSocket = new QTcpSocket(this); // 创建一个新的QTcpSocket对象 } // 析构函数,清理资源 Widget::~Widget() { delete ui; // 删除UI对象 } // 槽函数,当连接成功时调用 void Widget::connected_Slot() { // 连接信号和槽,当有数据可读时调用readyRead_Slot槽函数 connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); } // 槽函数,当有数据可读时调用 void Widget::readyRead_Slot() { // 将读取到的数据追加到recvTextEdit文本编辑器中 ui->recvTextEdit->appendPlainText(tcpSocket->readAll()); } // 槽函数,当打开按钮被点击时调用 void Widget::on_openBt_clicked() { // 连接到主机,IP地址和端口号分别从ipEdit和portEdit文本框中获取并转换 tcpSocket->connectToHost(ui->ipEdit->text(), ui->portEdit->text().toUInt()); // 连接信号和槽,当连接成功时调用connected_Slot槽函数 connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected_Slot())); } // 槽函数,当关闭按钮被点击时调用 void Widget::on_closeBt_clicked() { tcpSocket->close(); // 关闭连接 } // 槽函数,当发送按钮被点击时调用 void Widget::on_sendBt_clicked() { // 发送sendEdit文本框中的数据,数据转换为本地8位字节数组 tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data()); } 5.2UDP协议udp不分客户端和服务器,只需要使用一个类QUdpSocket#include "widget.h" #include "ui_widget.h" // 构造函数,初始化Widget对象 Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); // 设置UI udpSocket = new QUdpSocket(this); // 创建一个新的QUdpSocket对象 // 设置按钮的初始状态 ui->openBt->setEnabled(true); ui->closBt->setEnabled(false); ui->sendBt->setEnabled(false); } // 析构函数,清理资源 Widget::~Widget() { delete ui; // 删除UI对象 } // 槽函数,当有数据可读时调用 void Widget::readyRead_Slot() { while (udpSocket->hasPendingDatagrams()) // 当有挂起的数据报时 { QByteArray array; array.resize(udpSocket->pendingDatagramSize()); // 调整数组大小以适应数据报 udpSocket->readDatagram(array.data(), array.size()); // 读取数据报 QString buf = array.data(); // 将数据转换为QString ui->recvEdit->appendPlainText(buf); // 将数据追加到recvEdit文本编辑器中 } } // 槽函数,当打开按钮被点击时调用 void Widget::on_openBt_clicked() { // 绑定本地端口,成功则启用相关按钮 if(udpSocket->bind(ui->localPort->text().toUInt()) == true) { ui->openBt->setEnabled(false); ui->closBt->setEnabled(true); ui->sendBt->setEnabled(true); } // 连接信号和槽,当有数据可读时调用readyRead_Slot槽函数 connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot())); } // 槽函数,当关闭按钮被点击时调用 void Widget::on_closBt_clicked() { udpSocket->close(); // 关闭UDP连接 // 重置按钮的状态 ui->openBt->setEnabled(true); ui->closBt->setEnabled(false); ui->sendBt->setEnabled(false); } // 槽函数,当发送按钮被点击时调用 void Widget::on_sendBt_clicked() { QHostAddress address; address.setAddress(ui->aimIp->text()); // 设置目标IP地址 quint16 port = ui->aimPort->text().toUInt(); // 获取目标端口号 QString sendbuff = ui->sendEdit->text(); // 获取发送数据 // 发送数据报 udpSocket->writeDatagram(sendbuff.toLocal8Bit().data(), sendbuff.length(), address, port); } 6 时间编程qtime:qt的时间类qtimer:qt的定时类#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); connect( & timer, SIGNAL(timeout()), this, SLOT(timeout_Slot())); time.setHMS(0, 0, 0, 0); ui->showTime->setText(time.toString("hh:mm:ss:zzz")); } Widget::~Widget() { delete ui; } void Widget::timeout_Slot() { //qDebug() << "timeout_Slot"; time = time.addMSecs(30); ui->showTime->setText(time.toString("hh:mm:ss:zzz")); } void Widget::on_starBt_clicked() { //timer.setSingleShot(true);//只计时一次 timer.start(30); } void Widget::on_closBt_clicked() { timer.stop(); } void Widget::on_resetBt_clicked() { timer.stop(); time.setHMS(0, 0, 0, 0); ui->showTime->setText(time.toString("hh:mm:ss:zzz")); } static int i = 0; void Widget::on_bitBt_clicked() { QString temp; i = i + 1; temp.sprintf("%d--->", i); ui->bitTime->append(temp); ui->bitTime->append(time.toString("hh:mm:ss:zzz")); } void Widget::on_clearBt_clicked() { ui->bitTime->clear(); i = 0; }
2026年02月02日
1 阅读
0 评论
0 点赞