QT应用开发基础

Posted 行稳方能走远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT应用开发基础相关的知识,希望对你有一定的参考价值。

前言

在嵌入式上,我们少不了界面的开发,一种是用安卓,一种是用 QT,那么安卓对 CPU 的性能要求比较高,不是所有的 CPU 都可以运行,但是 QT 对 CPU 要求不高,甚至可以在单片机上来运行,而且 QT 是一个非常优秀的跨平台工具,一套代码我们可以在多个平台上来运行,比如 Windows,android,Linux 等,换一套编译器即可更换不同的平台。所以非常的方便和有趣。因为QT 开发需要 C++基础,不过不用担心,QT 上用的 C++并不多,大部分都是C语言的知识。

在这里插入图片描述

Windows上搭建开发环境

Qtcreator 下载地址:http://download.qt.io/new_archive/qt/5.11/,进入选择版本号界面,本教程使用的是5.11.1,也推荐读者选择此版本。进入如图 界面后,选择安装包,我们在windows 下学习Qt,所以选择qt-opensource-windows-x86-5.11.1.exe,点击即可下载。

在这里插入图片描述
下载后右键点击exe 文件,选择以管理员身份运行。注册账号,点击下一步(或next),选择安装路径。选择下一步,勾选需要用到的组件,本阶段教程需要勾选以下七个选项:
在这里插入图片描述
在这里插入图片描述
选择完后一直点下一步,安装完成后如图
在这里插入图片描述

C++基础

什么是C++

c++是 c 语言的升级版,在 c 的基础上增加了很多功能。是一种高级语言,常见后缀:cpp,c++,cc 等。

g++编译:gcc 是一个通用命令,它会根据不同的参数调用不同的编译器或链接器,GCC 为了让操作简单推出 g++命令用来编译 C++。

C++命名空间:中大型软件项目在多人合作开发时会出现变量或函数的命名冲突,C++ 引入了命名空间来解决变量重复定义。声明命名空间 std:using namespace std,后续如果有未指定命名空间的符号,那么默认使用 std,cin、cout ,endl 都位于命名空间 std。

#include <iostream>
namespace A{
        int num = 1;
}
namespace B{
        int num = 2;
}
int main(int argc, const char *argv[])
{
        int m = A::num;
        std::cout << m << std::endl;
        m = B::num;
        std::cout << m << std::endl;
        return 0;
}

在这里插入图片描述

什么是面向对象,什么又是面向过程

c 语言就是面向过程的,c++就是面向对象的,面向对象特点:封装,继承,多态。
举例:a+b
直接计算 a+b 就是面向过程。
面向对象就是给 a+b 穿上了一层衣服。不是直接计算 a+b。

c++的灵魂:c++的类

类大家可以把他看成c 语言结构体的升级版。类的成员不仅可以是变量,也可以是函数,类可以看做
是一种数据类型,这种数据类型是一个包含成员变量和成员函数的集合。比如:

class student
{
	public:
	//成员函数
	char name[64];
	int age;
	//成员函数
	void do(){
		Cout << “function” <<endl;
	}
};

对象:类的实例化

直接定义:

student my; // student 就是类my 就是对象

在堆里面定义:

student *my = new student;

删除对象:

delete my; 目的是释放堆里面的内存
my = NULL; 变成空指针,杜绝成为野指针。

怎么访问类的成员

int main(){
	student my;
	student *my1 = new student;
	my.age = 18;
	my1->age =19;
	
	cout << my.age << endl;
	cout << my1->age << endl;
}

访问方法和C 语言结构体是一样的,普通变量通过. 指针通过->

类的函数成员

因为类里面的成员不仅可以是变量,也可以是函数。
第一步:在类里面声明
第二步:实现这个函数。我们可以直接在类里面写,也可以写在类的外面。
直接写在类的里面

class student
{
	public:
	char name[64];
	int age;
	void test(){
		cout << 123 << endl;
	};
};

写到类的外面

class student
{
	public:
	char name[64];
	int age;
	void test();
};

	void student::test(){ //student:表示属于这个类里面的函数,不加的话会被识别成普通函数。
	cout << 123 << endl;
	};
};

访问函数和访问变量是一样的。

类的访问修饰符

类的访问修饰符就是对类的成员进行权限管理。

public:表示函数和变量是公开的,任何人都可以访问。
private:表示函数和变量只能在自己的类里面自己访问自己,不能通过对象来访问。

能不能强行访问?可以的,娆一个弯,通过访问函数(函数里面携带变量的值)间接访问变量

protected:表示函数和变量只能在自己的类里面自己访问自己,但是可以被派生类来访问的。

函数的重载

类函数的重载特性就是说我们可以在类里面定义同名的函数,但是参数不同的函数。

class student
{
	public:
		char name[64];
		int age;
		void test();
		void test(int a);
	private:
		int haha;
};

重载函数在调用的时候,会根据参数的类型,然后去匹配相应的函数进行调用。

构造函数和析构函数

析构函数:假如我们定义了析构函数,当对象被删除或者生命周期结束的时候,就会触发析构函数。

构造函数:假如我们定义了构造函数,对象创建的时候就会触发这个构造函数(和析构函数正好相反)。

我们要怎么定义析构函数和构造函数?
1.析构函数和构造函数的名字必须和类名一模一样。
2.析构函数要在前面加上一个~
举例:

class student
{
	public:
		student();//构造函数 对象被创建的时候触发
		~student();//析构函数 main函数return 0后触发析构函数
		char name[64];
		int age;
		void test();
		void test(int a);
	private:
		int haha;
};

student::student(){
	cout << "hello" << endl;
	}
	student::~student(){
	cout << "bye" << endl;
}

构造函数是可以被重载的。
析构函数不能被重载。

类的继承

类的继承允许我们在新的类里面继承父类的public 还有protected 部分,private 是不能被继承的。
当我们觉得这个类不好的时候,可以使用类的继承,添加我们需要的功能。
格式:

class 儿子:public 爸爸{
	public........
	Protected:
}

例子:

class mystudent:public student
{
	public:
	int grade;
};

如何在子类里面去访问父类的成员?
也是通过.和->来访问的。

虚函数和纯虚函数

虚函数:有实际定义的,允许派生类对他进行覆盖式的替换(父类内容被子类替换),virtual 来修饰。

纯虚函数:没有实际定义的虚函数就是纯虚函数。

举例:

virtual void test(); //虚函数
virtual void testa(){} //纯虚函数,里面没有任何代码

怎么定义一个虚函数?
用virtual 来修饰,虚函数是用在类的继承上的。

虚函数的优点?
可以预留接口,实现分工合作。像JAVA里面的重写。

制作一个简单的QT界面

qt 的移植性非常的强。一套代码我们不用改太多,直接通用所有的平台。
不久的将来,qt 会被用到MCU 上,学习QT 还是非常有意义的。

创建工程

步骤一:
在这里插入图片描述

步骤二:
填写工程名字,不要有中文路径:
在这里插入图片描述

步骤三:填写类名:
在这里插入图片描述

创建成功后如下图
在这里插入图片描述

工程目录下的.pro 工程文件分析:
在这里插入图片描述

点击forms,然后双击ui 文件,就可以进入ui 编辑器。
在这里插入图片描述

ui 编辑器面板介绍:
在这里插入图片描述

UI界面制作

在这里插入图片描述

在这里插入图片描述

信号和槽

信号就是指控件发出的特定的信号。槽就是槽函数的意思,信号和槽都位于类中,不是C++标准代码。我们可以把槽函数绑定在某一个控件的信号上。当需要调用外部函数时,发送一个信号,此时与该信号相关联的槽便会被调用,槽其实就是一个函数,槽与信号的关联要由程序员来完成,关联方法有自动关联和手动关联。

自动关联

使用Qt 信号和槽的自动关联,可加快开发速度,一般用于同一个窗体之间的控件关联,槽函数格式非常
关键,格式为:
void on_<窗口部件名称>_<信号名称>();
自动关联步骤:
步骤一:手动选择相应的控件,然后右键->转到槽。
在这里插入图片描述

选择信号类型:
在这里插入图片描述

自动关联会在.h 文件声明槽函数。槽函数只能声明到private slots 或者public slots 下面。按住Ctrl+鼠标左键,跳转到.cpp 文件对应的函数功能实现部分。填写功能代码,我们在槽函数内用qDebug 打印信息。
在这里插入图片描述

保存,点击构建,运行:
在这里插入图片描述

每次点击,按钮都会发信号,对应的槽函数就会执行,结果如图:
在这里插入图片描述

手动关联

信号和槽机制是QT 的核心机制,要精通QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是QT 的核心特性,也是QT 区别于其它工具包的重要地方。此外如果遇到不懂的函数或类,可以先选中,然后按F1 键,即可查看介绍。
虽然Qt 有自动关联功能,但涉及到多个窗体和复杂事件的时候,只能使用手动关联,手动关联使用connect 这个函数。

connect(const QObject *sender, const char *signal,const QObject *receiver, const char *member,Qt::ConnectionType = Qt::AutoConnection);
通常只传递前四个参数,参数含义:
sender:发送对象;
singal:发送对象里面的一个信号,格式一般为SIGNAL(信号);
receiver:接收对象;
member:接收对象里面的槽函数,格式一般为SLOT(信号)。
ConnectionType:设置信号和槽的同步异步,一般使用默认值Qt::AutoConnection,可不填。

connect(A,SIGNAL(B),C,SLOT(D));
当对象A 发出B 信号时候,就
会触发对象C 的槽函数D

signals 是QT 的关键字,而非C/C++ 的。signals 关键字指出进入了信号声明区,随后即可声明自己
的信号。
slots 槽是普通的C++ 成员函数,当与其关联的信号被发射时,这个槽函数就会被调用。槽函数有
的参数个数和类型,在对应的信号函数中必须一一对应,即信号函数的参数个数必须多于或等于槽函数的
个数。
emit Qt 定义的一个宏,作用是发射信号,与此信号关联的槽函数就会被调用。

例程:我们在widget.h 中自定义一个信号和一个槽函数
在这里插入图片描述

并在widget.cpp 实现槽函数:
在这里插入图片描述

然后在widget.cpp 中绑定信号和槽:
在这里插入图片描述

在widget.ui 中创建按钮,并转到槽,自动关联的槽函数如图
在这里插入图片描述

发射信号
在这里插入图片描述

这样,点击按钮,就会发射自定义的信号my_Signal(),与my_Signal()相关联的this 对象槽函数my_Solt就会被调用,槽函数就会输出打印信息,如图
在这里插入图片描述

部分核心代码如下:
Widget.h:

class student
{
    public:
             student();
             ~student();
             char name[64];
             int age;
             void test();
             void test(int a);


#include <QWidget>
        namespace Ui {
                class Widget;
        }
                class Widget : public QWidget
        {
                Q_OBJECT
public:
                        explicit Widget(QWidget *parent = 0);
                        ~Widget();

signals:
                        void my_Signal(void); //自定义的信号

private slots:
                        void on_pushButton_clicked();
                        void my_Solt(void); //自定义的槽函数

private:
                        Ui::Widget *ui;
};      

Widget.cpp:

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
{
        ui->setupUi(this);
        connect(this,SIGNAL(my_Signal()),this,SLOT(my_Solt()));
}
Widget::~Widget()
{
        delete ui; 
}
void Widget::on_pushButton_clicked()
{
        emit my_Signal();
}
void Widget::my_Solt(void)
{
        qDebug("按下");
}

给界面添加图片

添加资源

选中项目名称,右键单击—>选择添加新文件
在这里插入图片描述

在弹出窗口中选择Qt—>Qt Resource File ,选择Choose
在这里插入图片描述

填写写资源名称,
在这里插入图片描述

例如填写picture 后,在工程下的Resources 会出现picture.qrc 文件,成功后如图。
双击picture.qrc,点击“添加前缀”。
在这里插入图片描述

指定路径,这里笔者填的“/”此路径可根据需要自定义:
在这里插入图片描述

添加图片

我们首先将要添加的图片复制到工程目录下。
右击picture.qrc,选择Open With -> 资源编辑器,出现资源管理界面,点击下面的添加->添加前缀,
下方前缀栏填写的是“/ ”,这个路径可以根据需要自定义,然后保存。

在这里插入图片描述

再次点击“添加”,点击“添加文件”,
在这里插入图片描述

选中图片,点击“打开”,进入资源编辑器
在这里插入图片描述

在资源编辑器中会看到添加的图片,然后保存。
在这里插入图片描述

以此点开Resources 下的各个文件夹,即可看到添加的图片,此时图片已经添加到工程。
在这里插入图片描述

Label 添加图片

在ui 文件添加QLabel 组件,右击->选择改变样式表,
在这里插入图片描述

弹出对话框,选择添加资源->border image,
在这里插入图片描述

选择要添加的图片,如图
在这里插入图片描述

点击OK,apply,OK,即可完成添加,如图
在这里插入图片描述

界面布局

在这里插入图片描述

水平布局

Horizontal Layout 水平方向布局,组件自动在水平方向上分布
使用时先选中组件,然后点击水平布局即可完成,可看到组件变为水平排列。如图

在这里插入图片描述

垂直布局

Vertical Layout 垂直方向布局,组件自动在垂直方向上分布,操作方法和水平布局一致,在布局之后组件垂直排列。
我们点击打破布局按钮,重新选择要布局的组件,然后点击垂直布局按钮,如图
在这里插入图片描述

栅格布局

Grid Layout 网格状布局,网状布局大小改变时,每个网格的大小都改变

在这里插入图片描述
我们发现布局之后各个组件都是紧挨着的,这时候可以用“弹簧”控件来控制组件位置。
Horizontal Spacer 一个用于水平分隔的空格
在这里插入图片描述

在这里插入图片描述
完成后如图
在这里插入图片描述
Vertical Spacer 一个用于垂直分隔的空格,拖拽组件如图
在这里插入图片描述
选中点击垂直布局,完成后如图
在这里插入图片描述

界面切换

本节通过实验介绍通过创建窗口对象的方式实现界面切换:
在这里插入图片描述
步骤一:
在主界面ui 文件添加pushButton 按钮,
在这里插入图片描述
然后新建一个窗口,工程下创建新的Qt 设计师界面类,如图
在这里插入图片描述
我们选择Widget,用户可以根据需要选择,然后输入类名windowRun。
在这里插入图片描述
创建完成后如图
在这里插入图片描述
步骤二:关联ui 界面的pushButton 的clicked()信号和槽函数runSolt(),部分代码:

{
	ui->setupUi(this);
	connect(ui->pushButton,SIGNAL(clicked()),SLOT(runSlot()));//关联信号槽
}

步骤三:创建windowRun 类对象win,设置大小,显示。

void Example::runSlot(void)
{
	qDebug ("Run slots");
	//显示新窗口
	win = new windowRun();
	//设置win 窗口尺寸与此窗口尺寸相同
	win->setGeometry(this->geometry());
	//显示
	win->show();//win->close();关闭
}

运行程序后,点击按钮后即可跳转到第二个界面。
在这里插入图片描述
在这里插入图片描述

以上是关于QT应用开发基础的主要内容,如果未能解决你的问题,请参考以下文章

QT软件开发之入门基础--1.5开发第一个QT程序

QT开发(四十六)——QT数据库编程基础

qt creator源码全方面分析(2-0)

Qt+ECharts开发笔记:ECharts的饼图介绍基础使用和Qt封装百分比图Demo

QT软件开发之入门基础-搭建开发环境

Qt与FFmpeg联合开发指南——编码:完善功能和基础封装