网站建设举措,网站建设专,工厂网站建设公司,wordpress文章seo方法一、QT简介1、Qt是一个1991年由Qt Company开发的 跨平台 C 图形用户界面应用程序开发框架。 框架#xff1a;一堆能够实现特殊功能的类和函数。2、它既可以开发GUI程序#xff0c;也可用于开发非GUI程序#xff0c;比如控制台工具和服务器。GUI#xff08;Graphica…一、QT简介1、Qt是一个1991年由Qt Company开发的 跨平台 C 图形用户界面应用程序开发框架。 框架一堆能够实现特殊功能的类和函数。2、它既可以开发GUI程序也可用于开发非GUI程序比如控制台工具和服务器。GUIGraphical User Interface中文名图形用户接口是指采用图形方式显示的计算机操作用户界面qt是c写的3、Qt是面向对象的框架使用特殊的代码生成扩展称为元对象编译器(Meta Object Compiler, moc)以及一些宏Qt很容易扩展并且允许真正地组件编程。4、Qt包括多达500个以上的C类还提供基于模板的collectionsserializationfileI/O devicedirectory managementdate/time类。甚至还包括正则表达式的处理功能。5、编译可以在不同的系统上运行。6、Qt包含几种图形界面工具 --了解Qt DesignerQt设计器。用来可视化地设计应用程序界面。Qmake使用此工具可以由简单的、与平台无关的工程文件pro文件来生成编译所需的Makefile。Qt Assistant关于Qt的帮助文件。类似于MSDN。可以快速地发现你所需要的帮助。moc元对象编译器。uic用户界面编译器。在程序编译时被自动调用通过ui_*.h文件生成应用程序界面。MinGWMinimalist GNU for Windows是Windows下的一个轻量级开发工具集通常与Qt一起使用来开发 Windows应用程序。 Windows 中使用的 GCC 编译器 //Qt 中的 gcc 编译器其实是 MinGW 下的编译器二、第一个QT项目1.创建QT项目1.打开QTCreator2.Application---QT Widgets Application---choose3.名称项目名(不能有中文和特殊字符)---创建路径项目保存位置---下一步4.选择构建套件默认---下一步5.类信息5.1基类QMainWindow窗口类选择QDialog对话框类QWidget控件类5.2界面文件勾选创建ui文件可视化设计界面基类说明QMainWindow基于主窗口类的程序一般用于较为复杂的应用程序除了中央客户区界面还可以包括菜单栏、工具栏、状态栏以及多个可停靠的工具对话框等等。QWidget最简单最基本的窗体程序里面可以放置多个控件实现程序功能。QDialog基于对话框的程序对话框一般用于弹窗也可以用于主界面显示。对话框是从 QWidget 继承而来的并丰富了一些功能如模态显示和返回值等。2.查看编码保证 QT的文件能在Windows 和Linux下都能正常打开以及避免由于Windows下和Linux下编码不同而产生的中文字符乱码的问题需统一代码中的字符编码。为了达到这个目的需设置 QtCreator的默认编码为UTF-83.查看qt版本4.查看使用的编译器5.Qt Creator生成和运行程序绿箭头 编译并运行小锤子 编译不运行执行makefile文件锤子上的绿箭头有小虫子的绿箭头编译调试debug从编译生成到运行不需要自己敲命令一个按钮搞定这就是集成开发环境的好处项目右键执行qmake 叫做构建项目会生成makefile文件6.项目介绍1、pro文件1pro文件通常我们视他为qt项目的配置文件//.pro文件 QT core gui//项目指定的模块 core 核心模块 提供非图形类 gui 图形界面类 network 网络 模块 sq] 数据库模块 greaterThan(QT_MAJOR_VERSION, 4): QT widgets #组件模块 //条件语句检査当前的Qt主版本是否大于4 //在 Qt5 及以后的版本引入了新的小部件(widgets)特性widgets 模块包含了用于创建经典的桌面 GUI 应用程序的类例如 Qwidget、QPushButton 等。如果Qt的主版本号大于4那么会将 widgets 模块添加 到项目中。使用这种条件语句可以确保代码的兼容性在不同的 Qt 版本下使用相应的模块 CONFIG c11 //配置项目使用 C11 标准进行编译。这允许使用 C11 中的新特性 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES QT_DEPRECATED_WARNINGS //QT_DEPRECATED_WARNINGS 宏当使用已被标记为弃用的 Qt 特性时编译器会发出相应的警告。这有助 于开发者了解使用了过时的 API并促使其将代码更新到新的 API 上以保证代码的可维护性和未来的兼容 性。 # You can also make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 # disables all the APIs deprecated before Qt 6.0.0 //这是一个注释掉的配置。如果取消注释将禁止使用 Qt6.0.0 之前的所有已弃用的 API任何使用这些 API 的代码将无法编译强制开发者使用最新的 API保证代码的质量和与最新 Qt 版本的兼容性 SOURCES \ main.cpp \ mainwindow.cpp //工程中包含的源文件 HEADERS \ mainwindow.h //工程中包含的头文件 FORMS \ mainwindow.ui //工程中包含的界面文件 # Default rules for deployment. qnx: target.path /tmp/$${TARGET}/bin //对于 QNX 操作系统设置了目标文件的部署路径为 /tmp/$${TARGET}/bin。$${TARGET} 是一个变量 会在构建时被替换为目标名称。 //与 Linux 相比QNX 的实时性更强。Linux 虽然也可以用于一些实时性要求不是特别高的工业控制等场 景但在对时间要求极为严格的应用中QNX的性能优势更加明显。例如在某些需要微秒级响应的工业自动 化任务中QNX 能够更好地满足要求。 //与 windows 相比QNX 更加专注于嵌入式和实时应用。windows 主要用于桌面计算机和服务器等领域 而 QNX 的优势在于能够在资源有限的嵌入式设备中高效运行并且提供可靠的实时服务 else: unix:!android: target.path /opt/$${TARGET}/bin //对于其他的 Unix 系统(除了 Android)将目标文件部署到 /opt/$${TARGET}/bin 路径 !isEmpty(target.path): INSTALLS target //如果 target.path 不为空将 target 加入到 INSTALLS 列表中。这意味着在构建时生成的可执行文 件会被安装到 target.path 所指定的路径确保部署过程的正确执行2)main函数包含main函数定义应用程序的对象和主窗体对象显示主窗体程序运行2、文件介绍#include mainwindow.h #include QApplication int main(int argc, char *argv[]) { //QApplication qt的应用对象必须创建QApplication对象否则是不存在应用的 QApplication a(argc, argv); //创建我们自己定义的第一个窗口的对象 MainWindow w; //显示这个窗口对象 w.show(); //执行这个QApplication对象应用对象执行完毕main才执行完毕 return a.exec(); //1.启动事件循环exec() 方法启动 Qt 的事件循环开始处理用户输入、窗口系统事件、定时器事件等 //2.阻塞执行调用 exec() 后程序会阻塞在这里直到事件循环结束 //3.返回值返回一个整数值通常用作程序的退出代码 作为main函数的返回值 }#ifndef MAINWINDOW_H #define MAINWINDOW_H #include QMainWindow //声明Ui::MainWindow类 namespace Ui { class MainWindow; } //QT没有命名空间虽然没有命名空间但是QT所有的定义前面都有Q所以我们在Qt开发时定义的标识符前面不要以Q开头 //我们自己定义的MainWindow类继承了QT的QMainWindow类所以MainWindow类具备了窗口的所以属性。 //在框架中开发时我们经常会继承框架中类然后添加自己需要的功能。 class MainWindow : public QMainWindow { //QT中的大部分类都具备元对象属性元对象就是具备QT中的特殊属性的类 //只要我们定义的类继承了具备元对象属性的QT的类就得在类的私有访问权限中写Q_OBJECT宏。 //我们怎么知道一个类是否具备元对象属性呢查看这个类的基类中有没有QObject类。如果有就具备元对象属性。 Q_OBJECT public: //explicit避免隐式转换 /* QT的内存管理机制 把所有的对象构建成一颗树形结构当树的很节点被释放时会把它素所有的子节点都释放。 如果一个对象不指定父节点那么它的释放将有我们通过代码来实现。 一般情况下都用主窗口作为根节点。 这里的参数是QWidget类型说明想作为MainWindow的父节点需要派生自QWidget的类对象。 QWidget 控件 在屏幕上能看到的东西都叫控件 */ MainWindow(QWidget *parent nullptr); ~MainWindow(); private: //Ui::MainWindow不是我们定义的class MainWindow类 //Ui::MainWindow是QT根据MainWindow.ui文件自动生成的类。使用的工具叫QTDesigner。 Ui::MainWindow* ui;//ui指针将指向界面文件对象 }; #endif // MAINWINDOW_H#include MainWindow.h #include ui_MainWindow.h MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),//初始化父类 ui(new Ui::MainWindow)//创建一个界面文件的对象 { //创建界面文件对象中所有的控件对象 ui-setupUi(this); } MainWindow::~MainWindow() { delete ui;//释放界面文件对象 }三、基础控件什么叫控件在屏幕上能看到的东西都叫控件。这个定义并不是很准确为了建立第一印象。1.QLabel-标签可以在窗口中显示文字和图片的控件MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),//初始化父类 ui(new Ui::MainWindow)//创建一个界面文件的对象 { //创建界面文件对象中所有的控件对象 ui-setupUi(this); //我们想对控件进行任何操作一定是在ui-setupUi(this);这一行执行完毕之后。 //所有的界面文件中的控件都是ui的成员变量变量名就是控件名 ui-label-setText(hello world!);//设置label显示的文本 }2.QLineEdit-单行输入框编辑一行文本的控件输入框的暗文显示。输入框的提示字。输入框的最大长度。3.QPushButton-按钮4.布局控件在布局中尺寸由布局自动控制我们可以通过设置控件的最大最小尺寸来限制布局对控件尺寸的自动分配。1线性布局把控件排成一条横线或者一条竖线水平布局 horizontalLayout垂直布局 verticalLayout2网格布局横纵都有的排列布局是可以嵌套的。设置控件在布局中的最大和最小的尺寸限制布局对控件自动调整。常见错误error: cannot open output file debug\test1007.exe: Permission denied这个错误是因为之前运行过一个窗口在第二次运行之前修改代码了。此时需要关闭第一个窗口。练习1项目中最好给整个窗口先设置一个布局。做出登录界面和注册界面的UI文件。输入框灰字属性placeholderText输入框暗文属性echoMode passwordMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui-setupUi(this); //设置提示字 ui-lineEdit_account-setPlaceholderText(请输入账号); ui-lineEdit_password-setPlaceholderText(请输入密码); //设置密码圆点 ui-lineEdit_password-setEchoMode(QLineEdit::Password); }四、信号与槽1.作用是QT提供的一种解耦的机制。QT希望控件之间是相互独立的这样才更有利于功能的扩展。耦耦合模块之间的关系模块之间的相互调用耦合性高不好又不可能不耦合。信号与槽底层基于观察者模式 降低耦合性2.原理3.使用示例信号和槽机制是qt的核心机制当一个对象的状态发生变化时通过信号的方式通知其他对象其他对象通过执行相应的槽函数来响应该信号。信号与槽是QT提供的任意两个QObject对象之间的通信机制常用来完成界面操作的响应。定义槽函数槽是一个函数普通函数可以怎么用槽函数也可以怎么用。在访问权限的后面加上slots关键字slots是QT专有的关键字不是C语法。slots修饰的就是槽函数。例如当我们点击QPushButton的时候QPushButton就会发出一个信号。我们需要定义一个槽来接收一个信号在槽中编写按钮要触发的逻辑。public slots://槽函数 void slot_btn(); void MainWindow::slot_btn() { //修改文本内容 ui-label_hello-setText(hello); } //连接 connect(ui-pushButton_click,//信号的发送者 QPushButton::clicked,//信号-》一种动作标志或者请求 this,//信号的接收者 MainWindow::slot_btn);//响应的槽函数连接信号与槽connect( );//负责将信号与槽连接起来 参数1发出信号的对象 参数2信号 QPushButton点击是会发出clicked信号 参数3接收信号的对象 参数4槽 参数5处理模式:默认为自动连接一般不用默认参数有关多线程的参数暂时使用默认实参的就可以enum ConnectionType { AutoConnection,//自动连接 DirectConnection,//直接连接 QueuedConnection,//队列连接 BlockingQueuedConnection,//阻塞队列连接 UniqueConnection 0x80//唯一链接 };1.参数解析提取发送者sender、信号signal、接收者receiver、槽slot、连接类型默认Qt::AutoConnection。对旧语法SIGNAL/SLOT宏将信号 / 槽名转换为元对象索引通过QMetaObject::indexOfSignal/Slot新语法直接使用函数指针无需字符串解析。2.连接存储发送者sender维护一个连接映射表如QObjectPrivate::ConnectionList保存信号索引到接收者及槽的关联多对多关系支持一个信号连接多个槽。每个连接记录接收者指针、槽的元方法QMetaMethod、连接类型用于线程调度。3.线程调度逻辑根据连接类型Qt::DirectConnection 信号发射时立即同步调用槽同线程内直接执行跨线程可能引发线程安全问题如 UI 线程直接操作工作线程对象。Qt::QueuedConnection 将槽调用包装为事件QMetaCallEvent投递到接收者所在线程的事件循环异步执行跨线程安全通过事件队列序列化调用。Qt::AutoConnection 自动判断线程同线程则用Direct异线程则用Queued是默认且最常用的连接类型。Qt::BlockingQueuedConnection 类似Queued但发送者线程阻塞直至槽执行完毕需确保发送者与接收者不在同一线程否则死锁。4.唯一性检查Qt::UniqueConnection若设置该标志connect会先检查是否已存在相同的信号 - 槽连接基于发送者、信号、接收者、槽的唯一性避免重复连接。4.Lambda表达式信号与槽的连接方式三种方式demo、#include mainwindow.h #include ui_mainwindow.h #include QDebug MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui-setupUi(this); // 传统Qt是连接方式 // 传统Qt4连接方式为 信号发送者信号信号接受者处理函数 connect(ui-pushButton_qt4,SIGNAL(clicked()),this,SLOT(qT4_slot())); //Qt5连接方式 //其实这么写的方式和Qt4没有啥却别只是在Qt4 中引用了信号槽在简单的使用时没有问题 //但是在庞大的工程中信号和槽仅仅是宏替换在编译的时候没有安全监测 //Qt5的新方法在编译的时候就会有监测如果我们手误操作失误就会出现问题 connect(uipushButton_qt5,QPushButton::clicked,this,MainWindow::qT5_slot); //Qt5 Lambda表达式 //这里需要注意 Lambda表达式是C11 的内容所以需要再Pro项目文件中加入 CONFIG C11 connect(ui-pushButton_lambda,QPushButton::clicked, [this](){ //qDebug()lambda 表达式; ui-pushButton_lambda-setText(lambda 表达式); }); } void MainWindow::slot_qt4() { ui-label-setText(qt4); } void MainWindow::slot_qt5() { ui-label-setText(qt5); } MainWindow::~MainWindow() { delete ui; }一传统Qt是连接方式// 传统Qt4连接方式为 信号发送者信号信号接受者处理函数 connect(ui-pushButton_qt4,SIGNAL(clicked(bool)), this,SLOT(qT4_slot()));二Qt5连接方式/*其实这么写的方式和Qt4没有啥区别只是在Qt4 中引用了信号槽 在简单的使用时没有问题但是在庞大的工程中信号和槽仅仅是宏替换在编译的时候没有安全监测 Qt5的新方法在编译的时候就会有监测如果我们手误操作失误就会出现问题*/ connect(ui-pushButton_qt5,QPushButton::clicked, this,MainWindow::qT5_slot);三Qt5 Lambda表达式注意 Lambda表达式是C 11 的内容所以需要再Pro项目文件中加入 CONFIG C11 connect(ui-pushButton_lambda,QPushButton::clicked, []( ) { qDebug()Lambad; } ); [],标识一个Lambda的开始这部分必须存在。函数对象参数时传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用到哪些定义到Lambda前Lambda所在作用范围内可见的局部变量包括Lambda所在类的this。 函数对象参数有以下形式 空。没有使用任何函数对象参数 。函数体内可以使用Lambda所在作用范围内所有可见的局部变量是值传递的方式。 。函数体内可以使用Lambda所在作用范围内所有可见的局部变量是以引用传递方式。 this。函数体内可以使用Lambda所在类中的成员变量以值传递方式。 connect(ui-pushButton_lambda,QPushButton::clicked, [this](){ //qDebug()lambda 表达式; ui-label-setText(lambda 表达式); });练习2定义两个label点击按钮一个显示hello 一个显示world --两个槽函数两个connect练习2.2实现灯 1开关功能一个按钮文字显示 on/off 一个label显示 灯开/关 点击一次按钮label切换显示 灯开 和 灯关bool flag;按钮的显示 on off练习2.3记录按钮的点击次数从0开始点一次增加一次label显示整数ui-label-setNum(1);5. 获取当前发送信号的对象两个按钮对应一个标签label点击第一个按钮显示hello点击第二个按钮标签显示world只写一个槽函数QObject * sender QObject::sender();示例#include mainwindow.h #include ui_mainwindow.h MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui-setupUi(this); //连接 connect(ui-pushButton_hello, QPushButton::clicked, this, MainWindow::slot_sender); connect(ui-pushButton_world, QPushButton::clicked, this, MainWindow::slot_sender); } MainWindow::~MainWindow() { delete ui; } void MainWindow::slot_sender() { //获取当前发送信号得对象 QObject* obj QObject::sender(); //判断是哪个按钮 if(obj ui-pushButton_hello) { ui-label-setText(hello); } else if(obj ui-pushButton_world) { ui-label-setText(world); } }6.QObjectQObject类 1是所有qt类的基类父类 2实现了信号与槽的机制 3提供了处理机制父子对象的内存管理机制每一个对象都有一个父对象由父对象来负责子对象的内存管理。它的最主要特征是关于对象间无缝通信的机制信号与槽6.1 QObject 内存管理机制1. 以对象树的形式组织起来当为一个对象创建子对象时子对象会自动地添加到父对象的children()列表中父对象拥有子对象的所有权比如父对象可以在自己的析构函数中删除它的孩子对象6.2QT项目中使用的类基本分为两种一种为自定义的C的类 另一种则为QObject类。6.3获取谁在发送信号QObject* s QObject::sender();6.4Qt内存回收机制总结1)当一个QObject对象在堆上创建的时候Qt 会同时为其创建一个对象树里面对象无顺序2)任何对象树中的 QObject对象 delete 的时候如果这个对象有 parent则自动将其从 parent 的children列表中删除如果有孩子则自动 delete 每一个孩子。3)Qt 保证没有QObject会被 delete 两次4)在 Qt 中尽量在构造的时候就指定 parent 对象并且大胆在堆上创建五、QString类输出调试信息 使用QDebug类包含头文件#include QDebug说明想使用printf一样使用qDebug函数输出调试信息#include QDebug int conter 9; qDebug(connect ok %d\n,conter);像使用cout一样使用输出调试信息#include QDebug qDebug()hello;1.拼接//1.字符串拼接 定义字符串用QString QString s1 QString s1 hello; QString s2 world; s1s2;2.追加 appends1.append( hey); qDebug()s1;3.判断字符串是否为空QString s ; s.isEmpty(); 示例 if(!s.isEmpty()) { s.append(0); ui-label_choose-setText(s); }4.字符串清空 s.clear()s1.clear(); qDebug()s1;5.格式化char buf[100]; sprintf(buf,%s %d,哈哈,100); //替换 1替换成第一个arg中的参数 2替换第二个arg中的参数 s1 QString(%1 was born in %2).arg(小明).arg(1900);6.数字转字符串QString s QString().setNum(16); //QString s QString::number(num); QString s1 QString(%1).arg(16);7.字符串转换toInt() toDouble() toFloat() toLong() toLongLong()QString s5 123; bool ok; int n s5.toInt(ok,10); if(ok) { qDebug()n; } QString s6 7b; bool ok; int hex s6.toInt(ok,16);//转换成十六进制 if(ok)//转换是否成功 转换成功 返回值为true { qDebug()hex; } int dec s6.toInt(ok);//参数2位默认10进制 qDebug()dec;8.比较 QString s7 hello; QString s8 helo; if(s7 s8) qDebug()s7s8; else qDebug()not;示例#include QCoreApplication //调试信息类 #include QDebug #include string using namespace std; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); //1.创建字符串 QString str hello; qDebug()str; //2.拼接字符串 QString str2 world; //成员函数append 运算符重载 str.append(str2); qDebug()str;//helloworld str str2; qDebug()str;//helloworldworld //3.清空字符串 str.clear(); qDebug()str; //4.判断字符串是否为空 if(str.isEmpty()) { qDebug()请输入账号; } //5.格式化字符串 int num 100; QString str3 study; //替换 第一个arg中的值 替换到 %1 study 100 QString str4 QString(id:%1 name: %2).arg(str3).arg(num); qDebug()str4;//id:study name: 100 //6.字符串 转成数字 QString str5 123; // 123 bool ok; int res str5.toInt(ok,16); if(ok)//转换成功 qDebug()res; //7.数字转 字符串 100 //方式1 QString str6 QString(%1).arg(num); qDebug()str6;//100 //方式2静态方法 str6 QString::number(num); qDebug()str6;//100 //方式3:成员函数 str6 QString().setNum(100); qDebug()str6;//100 //8.字符串比较 ! QString name admin; QString userName tom; if(name userName) qDebug()登录成功; else qDebug()登录失败; return a.exec(); }练习3给登录界面中的登录按钮添加信号与槽点击按钮实现输出相应的内容。设计登录界面密码设定为密文最大六位输入用户名和密码后点击登录按钮将输入的内容与程序预留的用户名(admin)和密码(123456)比对在当前界面使用Label显示登录结果。ui-lineEdit-setMaxLength(6); //获取输入得内容 ui-lineEdit-text(); qDebug()”登录失败”;