【QT】——1_QT学习笔记

news2024/9/22 5:36:20

一、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),' ');            //插入空格字符串
            }
        }
        else
            Receivetext=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();
    else
        bytearray = 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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2057770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS Code中基于MSTest编写和运行测试

MS Test&#xff08;Microsoft Test Framework&#xff09;是微软提供的一个用于.NET应用程序的单元测试框架。以下是一个使用MS Test进行单元测试的示例&#xff0c;该示例将涵盖测试的基本步骤和概念。 项目搭建 在VS Code中开发C#时&#xff0c;创建solution&#xff08;解…

AI绘画Stable Diffusion画全身图总是人脸扭曲?ADetailer插件实现一键解决!商业级AI人物生成教程

大家好&#xff0c;我是灵魂画师向阳 你是否遇到过SD生成的人物脸部扭曲、甚至令人恶心的情况&#xff1f;也曾感到束手无策&#xff1f;别担心&#xff0c;这份教程专为你而来。 在使用SD生成人物全身照时&#xff0c;你可能经常发现人物的脸部会出现扭曲问题。这是因为人物…

整体思想以及取模

前言&#xff1a;一开始由于失误&#xff0c;误以为分数相加取模不能&#xff0c;但是其实是可以取模的 这个题目如果按照一般方法&#xff0c;到达每个节点再进行概率统计&#xff0c;但是不知道为什么只过了百分之十五的测试集 题目地址 附上没过关的代码 #include<bits…

如何在IIS中为typecho博客启用HTTPS访问

在上篇文章中&#xff0c;介绍了如何安装typecho博客系统&#xff0c;默认是没有启用https访问的&#xff0c;这篇文章介绍如何 在IIS中开启 https访问。 开启https访问需要两个步骤&#xff1a; 1、申请 一个ssl证书&#xff0c;我这里以阿里云上面的申请流程为例。其它云服务…

[Linux网络】基本网络命令socket编写TCP应用层实现简易计算器

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; 前言&#xff1a;我们在上篇博客中学习了使用socket套接字完成了UDP的网络编程&#xff0c;今天我们继续使用套接字完成TCP的学习。 首先我们先来了解一些网络指令&#xff0c;让大家可以在实现网络编程后查看一些与网…

勇闯机器学习(第五关--中文文本特征提取)

以下内容皆为原创&#xff0c;制作实属不易&#xff0c;请点点关注和赞赞❥(^_^) 第一关&#xff1a;机器学习概念和流程http://t.csdnimg.cn/IuHh4第二关&#xff1a;数据集的使用http://t.csdnimg.cn/2jsdi第三关&#xff1a;特征工程-字典特征提取http://t.csdnimg.cn/ZpMt…

[数据集][目标检测]铁轨缺陷检测数据集VOC+YOLO格式4020张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4020 标注数量(xml文件个数)&#xff1a;4020 标注数量(txt文件个数)&#xff1a;4020 标注…

高性能web服务器2——Nginx概述

Nginx 概述 Nginx 是一款广泛使用的高性能 Web 和反向代理服务器&#xff0c;以其出色的并发处理能力和低内存消耗而闻名。自 2004 年首次发布以来&#xff0c;Nginx 已经成为许多企业和组织的首选 Web 服务器和负载均衡解决方案。本文将对 Nginx 进行一个全面的概述&#xff…

探索Qotom Q51251OPS迷你电脑:功能与广泛应用

Qotom Q51251 OPS&#xff08;开放可插拔规范&#xff09;迷你电脑是一款设计紧凑且功能强大的设备&#xff0c;旨在满足不同领域的多样化需求。基于英特尔Core i5-12450H Alder Lake H处理器&#xff0c;这款设备不仅具备出色的计算性能&#xff0c;还提供了丰富的连接选项&am…

电路板中的MARK点

什么是mark点&#xff0c;什么情况下有mark点 Mark点的种类 局部mark点&#xff1a;针对那些 引脚数量众多 引脚间距非常紧凑的元器件 比如说QFT封装 BGA封装 MARK点的作用 不论是 拼版还是全局mark 一般都会放上2-3个点 第三个mark点一般用于比较大的电路板或者是比较大的拼…

接口加密解决方案,Python的各种加密实现!

01、前言 在现代软件开发中&#xff0c;接口测试已经成为了不可或缺的一部分。随着互联网的普及&#xff0c;越来越多的应用程序都采用了接口作为数据传输的方式。接口测试的目的是确保接口的正确性、稳定性和安全性&#xff0c;从而保障系统的正常运行。 在接口测试中&…

TXT 记录解析怎么做?

在当今数字化的时代&#xff0c;网络技术的应用越来越广泛&#xff0c;而域名系统&#xff08;DNS&#xff09;则是网络通信中至关重要的一部分。TXT 记录作为 DNS 中的一种记录类型&#xff0c;有着特定的用途和解析方法。 那么&#xff0c;TXT 记录解析究竟该怎么做呢&#…

学习node.js 七 http 模块

目录 http模块 创建http服务器 反向代理 代码实现 邮件服务 案例实现&#xff1a; 动静分离 代码实现 http模块 “http” 模块是 Node.js 中用于创建和处理 HTTP 服务器和客户端的核心模块。它使得构建基于 HTTP 协议的应用程序变得更加简单和灵活。 创建 Web 服务…

高性能企业WEB服务器

一&#xff1a;nginx的编译安装&#xff1a; 1.1官方源下载地址&#xff1a; https://nginx.org/en/download.html 1.1.1下载编译所需要的软件&#xff1a; [rootnginx nginx-1.24.0]# dnf install gcc pcre-devel zlib-devel openssl-devel -y 编译&#xff1a; 验证版本及编…

DHU 二维数组 阵列

输出范例给的不工整 思路及代码 写的不优雅 分为三部分 枚举输出 n 1-11 规律求出 n > 12 的矩阵 输出需要的矩阵&#xff0c;把每一行存成一个字符串&#xff0c;方便左右对齐 #include<iostream> #include<cmath> #include<iomanip> #include&l…

C++ 设计模式(4. 建造者模式)

建造者模式&#xff08;也被成为生成器模式&#xff09;&#xff0c;是一种创建型设计模式&#xff0c;软件开发过程中有的时候需要创建很复杂的对象&#xff0c;而建造者模式的主要思想是将对象的构建过程分为多个步骤&#xff0c;并为每个步骤定义一个抽象的接口。具体的构建…

计算机毕业设计 公寓出租系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

消防认证-火灾显示盘GB 17429-2011

一、消防认证 消防认证是指消防产品符合国家相关技术要求和标准&#xff0c;且通过了国家认证认可监督管理委员会审批&#xff0c;获得消防认证资质的认证机构颁发的证书&#xff0c;消防产品具有完好的防火功能&#xff0c;是住房和城乡建设领域验收的重要指标。 二、认证依据…

软考高项—项目采购管理总结

采购管理包括规划采购管理、实施采购和控制采购3个过程。 管理领域管理过程定义作用频率项目采购管理规划采购管理记录项目采购决策、明确采购方法&#xff0c;及识别潜在卖方的过程。确定是否从项目外部获取货物和服务&#xff0c;如果是&#xff0c;则还要确定将在什么时间、…