目录

  • 前言
  • Windows上搭建开发环境
  • C++基础
  • 什么是C++
  • 什么是面向对象,什么又是面向过程
  • c++的灵魂:c++的类
  • 对象:类的实例化
  • 怎么访问类的成员
  • 类的函数成员
  • 类的访问修饰符
  • 函数的重载
  • 构造函数和析构函数
  • 类的继承
  • 虚函数和纯虚函数
  • 制作一个简单的QT界面
  • 创建工程
  • UI界面制作
  • 信号和槽
  • 自动关联
  • 手动关联
  • 给界面添加图片
  • 添加资源
  • 添加图片
  • Label 添加图片
  • 界面布局
  • 水平布局
  • 垂直布局
  • 栅格布局
  • 界面切换


前言

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

android qt 程序开发 安卓qt开发_android qt 程序开发

Windows上搭建开发环境

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

android qt 程序开发 安卓qt开发_析构函数_02


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

android qt 程序开发 安卓qt开发_信号和槽_03


android qt 程序开发 安卓qt开发_QT_04


选择完后一直点下一步,安装完成后如图

android qt 程序开发 安卓qt开发_析构函数_05

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

android qt 程序开发 安卓qt开发_析构函数_06

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

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 还是非常有意义的。

创建工程

步骤一:

android qt 程序开发 安卓qt开发_android qt 程序开发_07

步骤二:

填写工程名字,不要有中文路径:

android qt 程序开发 安卓qt开发_析构函数_08

步骤三:填写类名:

android qt 程序开发 安卓qt开发_QT_09

创建成功后如下图

android qt 程序开发 安卓qt开发_析构函数_10

工程目录下的.pro 工程文件分析:

android qt 程序开发 安卓qt开发_android qt 程序开发_11

点击forms,然后双击ui 文件,就可以进入ui 编辑器。

android qt 程序开发 安卓qt开发_android qt 程序开发_12

ui 编辑器面板介绍:

android qt 程序开发 安卓qt开发_信号和槽_13

UI界面制作

android qt 程序开发 安卓qt开发_android qt 程序开发_14

android qt 程序开发 安卓qt开发_QT_15

信号和槽

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

自动关联

使用Qt 信号和槽的自动关联,可加快开发速度,一般用于同一个窗体之间的控件关联,槽函数格式非常

关键,格式为:

void on_<窗口部件名称>_<信号名称>();

自动关联步骤:

步骤一:手动选择相应的控件,然后右键->转到槽。

android qt 程序开发 安卓qt开发_android qt 程序开发_16

选择信号类型:

android qt 程序开发 安卓qt开发_QT_17

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

android qt 程序开发 安卓qt开发_android qt 程序开发_18

保存,点击构建,运行:

android qt 程序开发 安卓qt开发_信号和槽_19

每次点击,按钮都会发信号,对应的槽函数就会执行,结果如图:

android qt 程序开发 安卓qt开发_信号和槽_20

手动关联

信号和槽机制是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 中自定义一个信号和一个槽函数

android qt 程序开发 安卓qt开发_QT_21

并在widget.cpp 实现槽函数:

android qt 程序开发 安卓qt开发_android qt 程序开发_22

然后在widget.cpp 中绑定信号和槽:

android qt 程序开发 安卓qt开发_析构函数_23

在widget.ui 中创建按钮,并转到槽,自动关联的槽函数如图

android qt 程序开发 安卓qt开发_QT_24

发射信号

android qt 程序开发 安卓qt开发_android qt 程序开发_25

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

android qt 程序开发 安卓qt开发_信号和槽_26

部分核心代码如下:
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("按下");
}

给界面添加图片

添加资源

选中项目名称,右键单击—>选择添加新文件

android qt 程序开发 安卓qt开发_QT_27

在弹出窗口中选择Qt—>Qt Resource File ,选择Choose

android qt 程序开发 安卓qt开发_信号和槽_28

填写写资源名称,

android qt 程序开发 安卓qt开发_QT_29

例如填写picture 后,在工程下的Resources 会出现picture.qrc 文件,成功后如图。

双击picture.qrc,点击“添加前缀”。

android qt 程序开发 安卓qt开发_android qt 程序开发_30

指定路径,这里笔者填的“/”此路径可根据需要自定义:

android qt 程序开发 安卓qt开发_析构函数_31

添加图片

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

android qt 程序开发 安卓qt开发_android qt 程序开发_32

再次点击“添加”,点击“添加文件”,

android qt 程序开发 安卓qt开发_QT_33

选中图片,点击“打开”,进入资源编辑器

android qt 程序开发 安卓qt开发_android qt 程序开发_34

在资源编辑器中会看到添加的图片,然后保存。

android qt 程序开发 安卓qt开发_android qt 程序开发_35

以此点开Resources 下的各个文件夹,即可看到添加的图片,此时图片已经添加到工程。

android qt 程序开发 安卓qt开发_信号和槽_36

Label 添加图片

在ui 文件添加QLabel 组件,右击->选择改变样式表,

android qt 程序开发 安卓qt开发_析构函数_37

弹出对话框,选择添加资源->border image,

android qt 程序开发 安卓qt开发_android qt 程序开发_38

选择要添加的图片,如图

android qt 程序开发 安卓qt开发_析构函数_39

点击OK,apply,OK,即可完成添加,如图

android qt 程序开发 安卓qt开发_析构函数_40

界面布局

android qt 程序开发 安卓qt开发_信号和槽_41

水平布局

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

android qt 程序开发 安卓qt开发_QT_42

垂直布局

Vertical Layout 垂直方向布局,组件自动在垂直方向上分布,操作方法和水平布局一致,在布局之后组件垂直排列。

我们点击打破布局按钮,重新选择要布局的组件,然后点击垂直布局按钮,如图

android qt 程序开发 安卓qt开发_析构函数_43

栅格布局

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

android qt 程序开发 安卓qt开发_信号和槽_44


我们发现布局之后各个组件都是紧挨着的,这时候可以用“弹簧”控件来控制组件位置。

Horizontal Spacer 一个用于水平分隔的空格

android qt 程序开发 安卓qt开发_信号和槽_45

android qt 程序开发 安卓qt开发_信号和槽_46


完成后如图

android qt 程序开发 安卓qt开发_android qt 程序开发_47


Vertical Spacer 一个用于垂直分隔的空格,拖拽组件如图

android qt 程序开发 安卓qt开发_信号和槽_48


选中点击垂直布局,完成后如图

android qt 程序开发 安卓qt开发_QT_49

界面切换

本节通过实验介绍通过创建窗口对象的方式实现界面切换:

android qt 程序开发 安卓qt开发_android qt 程序开发_50


步骤一:

在主界面ui 文件添加pushButton 按钮,

android qt 程序开发 安卓qt开发_QT_51


然后新建一个窗口,工程下创建新的Qt 设计师界面类,如图

android qt 程序开发 安卓qt开发_QT_52


我们选择Widget,用户可以根据需要选择,然后输入类名windowRun。

android qt 程序开发 安卓qt开发_信号和槽_53


创建完成后如图

android qt 程序开发 安卓qt开发_QT_54


步骤二:关联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();关闭
}

运行程序后,点击按钮后即可跳转到第二个界面。

android qt 程序开发 安卓qt开发_信号和槽_55


android qt 程序开发 安卓qt开发_android qt 程序开发_56