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

【QT】——1_QT学习笔记

一、QT是什么?

QT 是一个功能强大、应用广泛的跨平台 C++ 应用程序开发框架,它不仅提供了丰富多样、美观实用的图形界面组件,还具备高效灵活的信号与槽通信机制,能够帮助开发者轻松构建出复杂且性能优越的应用程序,广泛应用于桌面应用、移动应用、嵌入式系统等众多领域。

对比维度QT(基于 C++)C#
语言类型C++ 是一种中级编程语言C# 是一种高级编程语言
运行平台跨平台(Windows、Mac、Linux 等)主要在 Windows 平台上表现出色,也支持跨平台但相对较弱
内存管理手动内存管理,需要开发者自行处理自动内存管理,减少内存泄漏风险
性能通常在性能关键型应用中表现较好性能也不错,但可能略逊于 C++ 在某些场景
开发效率相对较低,需要更多的底层代码编写较高,有丰富的库和工具支持
语法复杂度语法相对复杂语法较为简洁易懂
应用领域多用于嵌入式系统、工业控制等常用于 Web 应用、Windows 桌面应用、游戏开发等
社区支持社区活跃,资源丰富社区强大,有大量的开源项目和文档

二、QT中需要掌握什么?

1、C++编程语言:
(1)基本语法:变量,数据类型,控制结构;
(2)理解面向对象编程的概念:类,对象,继承,多态等
(3)内存管理:指针、动态内存分配等


2、QT 框架基础知识:
(1)了解QT的架构和工作原理
(2)熟悉 QT 的信号与槽机制
(3)掌握 QT 的窗口部件(Widgets)


3、图形用户界面(GUI)设计:
(1)控件布局
(2)学会自定义窗口部件的外观和行为


4、事件处理
(1)处理各种用户交互事件,如鼠标点击、键盘输入等
(2)理解事件的传播和捕获机制


5、数据存储和处理
(1)学会使用 QT 提供的数据结构和容器,如 QList、QMap 等
(2)掌握文件读写操作,以便保存和加载数据


6、多线程编程
(1)在 QT 中创建和管理多线程,以提高程序的性能和响应性
(2)处理多线程之间的同步和通信问题

三、安装

四、实践小实验

1、UI设计

自定义窗口部件的外观和行为,添加组合框;
在这里插入图片描述

2、信号与槽机制和事件处理

#include "widget.h"
#include "ui_widget.h"#include <QMessageBox>
#include <QDebug>
#include <QFile>
#include <QFileDialog>
#include <QTimer>
#include <QStringList>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);resize(800,600);                                //窗口限制setWindowTitle("Serial_Port");SendByte=0;ReceByte=0;serial = new QSerialPort(this);ui->comboBox_2->setCurrentIndex(5);             //初始化ui->comboBox_3->setCurrentIndex(3);ui->comboBox_4->setCurrentIndex(2);ui->comboBox_5->setCurrentIndex(0);ui->lineEdit->setText("1000");ui->checkBox->setCheckState(Qt::Checked);ui->checkBox_4->setCheckState(Qt::Checked);ui->pushButton_7->setEnabled(false);ui->checkBox_7->setEnabled(false);connect(serial,SIGNAL(readyRead()),             //信号与槽函数this,SLOT(serialPort_readyRead()));Times=0;portTime=0;lineEditData=1000;timer = new QTimer;timer->start(1);//connect(timer,&QTimer::timeout,this,&Widget::TimerEvent);connect(timer,SIGNAL(timeout()),this,SLOT(TimerEvent()));       //信号与槽函数
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_2_clicked()
{if(ui->pushButton_2->text()==QString("打开串口")){//设置串口名serial->setPortName(ui->comboBox->currentText());//设置波特率serial->setBaudRate(ui->comboBox_2->currentText().toInt());//设置数据位switch(ui->comboBox_3->currentText().toInt()){case 5:serial->setDataBits(QSerialPort::Data5);break;case 6:serial->setDataBits(QSerialPort::Data6);break;case 7:serial->setDataBits(QSerialPort::Data7);break;case 8:serial->setDataBits(QSerialPort::Data8);break;default:serial->setDataBits(QSerialPort::UnknownDataBits);break;}//设置奇偶校验位switch(ui->comboBox_4->currentIndex()){case 0:serial->setParity(QSerialPort::EvenParity);break;case 1:serial->setParity(QSerialPort::MarkParity);break;case 2:serial->setParity(QSerialPort::NoParity);break;case 3:serial->setParity(QSerialPort::OddParity);break;default:serial->setParity(QSerialPort::UnknownParity);break;}//设置停止位switch (ui->comboBox_5->currentIndex()){case 0:serial->setStopBits(QSerialPort::OneStop);break;case 1:serial->setStopBits(QSerialPort::OneAndHalfStop);break;case 2:serial->setStopBits(QSerialPort::TwoStop);break;default:serial->setStopBits(QSerialPort::UnknownStopBits);break;}//设置流控制serial->setFlowControl(QSerialPort::NoFlowControl);//打开串口if(!serial->open(QIODevice::ReadWrite)){QMessageBox::about(NULL,"提示","无法打开串口");return;}//下拉控件失能ui->comboBox->setEnabled(false);ui->comboBox_2->setEnabled(false);ui->comboBox_3->setEnabled(false);ui->comboBox_4->setEnabled(false);ui->comboBox_5->setEnabled(false);ui->pushButton->setEnabled(false);ui->checkBox_7->setEnabled(true);ui->pushButton_2->setText(tr("关闭串口"));ui->pushButton_7->setEnabled(true);}else{//关闭串口serial->close();//下拉按键使能ui->comboBox->setEnabled(true);ui->comboBox_2->setEnabled(true);ui->comboBox_3->setEnabled(true);ui->comboBox_4->setEnabled(true);ui->comboBox_5->setEnabled(true);ui->pushButton->setEnabled(true);ui->checkBox_7->setEnabled(false);ui->pushButton_2->setText(tr("打开串口"));//发送失能ui->pushButton_7->setEnabled(false);}
}void Widget::on_pushButton_clicked()                  //扫描串口
{int i,n;ui->comboBox->clear();portStringLine.clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())portStringLine +=info.portName();n=portStringLine.size();for(i=0;i<n;i++){serial->setPortName(portStringLine[i]);if(!serial->open(QIODevice::ReadWrite)){portStringLine[i]+="(不可用)";QVariant v(0);          //禁用ui->comboBox->setItemData(1, v, Qt::UserRole - 1);}else{QVariant v(1|32);       //可用ui->comboBox->setItemData(1, v, Qt::UserRole - 1);}serial->close();}ui->comboBox->addItems(portStringLine);
}void Widget::serialPort_readyRead()                  //串口接收
{int i,length;QString lasttext;if(ui->checkBox_3->checkState()!=Qt::Checked){lasttext=ui->textEdit->toPlainText();Receivetext = serial->readAll();ReceByte+=Receivetext.length();ui->label_10->setText(QString::number(ReceByte));if(ui->checkBox_2->checkState()==Qt::Checked){Receivetext=Receivetext.toLatin1().toHex();     //字符串转十六进制length=Receivetext.length();for(i=0;i<=length/2;i++){Receivetext.insert((2+3*i),' ');            //插入空格字符串}}elseReceivetext=Receivetext.toLatin1();lasttext=lasttext.append(Receivetext);ui->textEdit->setText(lasttext);}
}void Widget::on_pushButton_7_clicked()                          //串口发送
{QByteArray bytearray;Sendtext=ui->textEdit_2->toPlainText();if(ui->checkBox_6->checkState()==Qt::Checked)Sendtext += '\n';if(ui->checkBox_5->checkState()!=Qt::Checked)bytearray = Sendtext.toLatin1();elsebytearray = QByteArray::fromHex(Sendtext.toUtf8());     //十六进制转字符串serial->write(bytearray);//定长发送//serial->write((const char *)param_data,16);SendByte+=Sendtext.length();ui->label_9->setText(QString::number(SendByte));ui->textEdit_2->moveCursor(QTextCursor::End);
}void Widget::TimerEvent()                                       //定时事件,1ms
{int t=500;                                                  //扫描串口时间Times++;portTime++;if(Times>=lineEditData)                                     //定时发送{if(ui->checkBox_7->checkState()==Qt::Checked)Widget::on_pushButton_7_clicked();Times=0;}if(portTime==t)                                             //定时扫描串口{QStringList newPortStringList;newPortStringList.clear();foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())newPortStringList += info.portName();if(newPortStringList.size() != portStringLine.size()){portStringLine = newPortStringList;ui->comboBox->clear();ui->comboBox->addItems(portStringLine);}portTime=0;}
}void Widget::on_pushButton_8_clicked()              //清除计数
{SendByte=0;ReceByte=0;ui->label_9->setText(QString::number(SendByte));ui->label_10->setText(QString::number(ReceByte));
}void Widget::on_pushButton_4_clicked()              //清除接收区
{ui->textEdit->clear();
}void Widget::on_pushButton_6_clicked()              //清除发送区
{ui->textEdit_2->clear();
}void Widget::on_checkBox_clicked()                  //文本接收
{ui->checkBox->setCheckState(Qt::Checked);ui->checkBox_2->setCheckState(Qt::Unchecked);ui->checkBox_3->setCheckState(Qt::Unchecked);
}void Widget::on_checkBox_2_clicked()                //十六进制接收
{ui->checkBox->setCheckState(Qt::Unchecked);ui->checkBox_2->setCheckState(Qt::Checked);ui->checkBox_3->setCheckState(Qt::Unchecked);
}void Widget::on_checkBox_3_clicked()                //暂停接收
{ui->checkBox->setCheckState(Qt::Unchecked);ui->checkBox_2->setCheckState(Qt::Unchecked);ui->checkBox_3->setCheckState(Qt::Checked);
}void Widget::on_checkBox_4_clicked()                //文本发送
{ui->checkBox_4->setCheckState(Qt::Checked);ui->checkBox_5->setCheckState(Qt::Unchecked);
}void Widget::on_checkBox_5_clicked()                //十六进制发送
{ui->checkBox_4->setCheckState(Qt::Unchecked);ui->checkBox_5->setCheckState(Qt::Checked);
}void Widget::on_pushButton_5_clicked()              //打开文件
{QString fileName = QFileDialog::getOpenFileName(this);QFile file(fileName);     //新建QFile对象if(!file.open(QFile::ReadOnly|QFile::Text)){QMessageBox::warning(this,tr("多文档编辑器"),tr("无法读取文件 %1:\n%2").arg(fileName,file.errorString()));}QTextStream in(&file);    //新建文本流对象// 鼠标指针变为等待状态QApplication::setOverrideCursor(Qt::WaitCursor);//读取文件的全部文本内容,并添加到编辑器中ui->textEdit_2->setPlainText(in.readAll());//鼠标指针恢复为原来状态QApplication::restoreOverrideCursor();ui->textEdit->setVisible(true);
}void Widget::on_pushButton_3_clicked()              //保存文件
{QString fileName = QFileDialog::getSaveFileName(this);QFile file(fileName);if (!file.open(QFile::WriteOnly | QFile::Text)){// %1和%2分别对应后面arg两个参数,/n起换行的作用QMessageBox::warning(this, tr("多文档编辑器"),tr("无法写入文件 %1:/n %2").arg(fileName, file.errorString()));}QTextStream out(&file);// 鼠标指针变为等待状态QApplication::setOverrideCursor(Qt::WaitCursor);out << ui->textEdit->toPlainText();// 鼠标指针恢复原来的状态QApplication::restoreOverrideCursor();
}void Widget::on_lineEdit_editingFinished()          //输入定时时间
{if(ui->lineEdit->text().toInt()>0)lineEditData=ui->lineEdit->text().toInt();
}

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QtSerialPort>
#include <QSerialPortInfo>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();  int Times,portTime,lineEditData;
private:Ui::Widget *ui;QSerialPort *serial;                    //串口端口QTimer *timer;                          //定时器QString Sendtext,Receivetext;           //发送、接收缓存区long int SendByte,ReceByte;             //发送、接收字符数QStringList portStringLine;             //端口链表private slots:void serialPort_readyRead();            //串口接收void TimerEvent();                      //定时发送、更新串口void on_pushButton_clicked();           //扫描串口void on_pushButton_2_clicked();         //打开串口键按下void on_pushButton_7_clicked();         //串口发送void on_pushButton_8_clicked();         //清除计数void on_pushButton_4_clicked();         //清除接收区void on_pushButton_6_clicked();         //清除发送区void on_checkBox_clicked();             //文本接收void on_checkBox_2_clicked();           //十六进制接收void on_checkBox_3_clicked();           //暂停接收void on_checkBox_4_clicked();           //文本发送void on_checkBox_5_clicked();           //十六进制发送void on_pushButton_5_clicked();         //打开文件void on_pushButton_3_clicked();         //保存文件void on_lineEdit_editingFinished();     //输入定时时间
};
#endif // WIDGET_H

并在.pro文件中添加支持

QT       += serialport

3、更改样式表

/* 按键普通状态 */
QPushButton
{width: 336px;height: 48px;line-height: 48px;background: #4e6ef2;border-radius: 10px;box-shadow: 0 6px 16px 0 rgb(78 111 242 / 30%);font-size: 17px;font-weight: 800;border: 0;color: #fff;cursor: pointer;
}/* 按键按下状态 */QPushButton:pressed
{/*背景颜色*/  background-color:rgb(14 , 135 , 228);/*左内边距为3像素,让按下时字向右移动3像素*/  padding-left:3px;/*上内边距为3像素,让按下时字向下移动3像素*/  padding-top:3px;
}

相关文章:

  • 学懂C++(三十九):网络编程——深入详解 TCP 和 UDP 的区别和应用场景
  • Moodle与ONLYOFFICE集成如何实现智能教学管理
  • python中dataframe的iloc和loc的使用区别
  • 秋叶SD整合安装包更新了!8月最新版4.9【附下载】
  • Qt 0821作业
  • 用友crm客户关系管理help.php存在任意文件读取漏洞解析
  • 面试题目:(6)翻转二叉树
  • 机器学习十-欠拟合和过拟合
  • JavaScript - 事件监听
  • 批量自动校正图片、PDF文档方向工具
  • 稳石机器人 | 工业级AMR S1200L,专为多样化需求设计,柔性拓展更易用
  • L2G: A Simple Local-to-Global Knowledge Transfer Framework for WSSS
  • 深入理解MySQL索引:原理、数据结构与优化策略
  • 原子操作的概念
  • 通过建立系统用例模型和静态模型,搭建教学管理系统
  • css属性的继承、初识值、计算值、当前值、应用值
  • Javascripit类型转换比较那点事儿,双等号(==)
  • Java反射-动态类加载和重新加载
  • php面试题 汇集2
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 爱情 北京女病人
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 第十八天-企业应用架构模式-基本模式
  • 关于List、List?、ListObject的区别
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 基于遗传算法的优化问题求解
  • 今年的LC3大会没了?
  • 思考 CSS 架构
  • 原生Ajax
  • ​io --- 处理流的核心工具​
  • ​字​节​一​面​
  • #### go map 底层结构 ####
  • #pragma 指令
  • (3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)
  • (4) PIVOT 和 UPIVOT 的使用
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (小白学Java)Java简介和基本配置
  • (一)RocketMQ初步认识
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)关于pipe()的详细解析
  • .net core控制台应用程序初识
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .NET是什么
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @四年级家长,这条香港优才计划+华侨生联考捷径,一定要看!
  • []Telit UC864E 拨号上网
  • [20150707]外部表与rowid.txt
  • [2021 蓝帽杯] One Pointer PHP
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • [C++进阶篇]STL中vector的使用
  • [C语言]编译和链接
  • [Golang] go-kit 介绍和使用 (微服务实现工具)