Qt是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。

QT的优势:
1)跨平台,几乎支持所有的平台

2)接口简单,容易上手,学习QT框架对学习其他框架有参考意义。

3)一定程度上简化了内存回收机制

4)开发效率高,能够快速的构建应用程序。

5)有很好的社区氛围,市场份额在缓慢上升。

6)可以进行嵌入式开发。

1.入门

1.1main.cpp文件

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <QApplication>//包含应用程序头文件

//main函数,接收的参数
int main(int argc, char *argv[])
{
QApplication a(argc, argv);

MyWidget w;//创建应用对象

w.show(); //展示对象
resize(600,400); //重置窗口大小
return a.exec(); //执行
}

1.2QPushButton

1
2
3
4
5
6
//创建一个按钮
QPushButton* btn = new QPushButton;
//让按钮依附在窗口中
btn->setParent(this);
//设置文字
btn->setText("点我");

另一种创建方法

1
2
QPushButton* btn = new QPushButton("点我",this);
btn->move(100,100); //移动按钮到(100,100)

其他窗口方法

1
2
3
4
5
6
setWindowTitle("我是应用程序名"); //设置窗口标题

setFixedHeight(600);//设置固定高度
setFixedWidth(400); //设置固定宽度

setFixedSize(500,500); //宽 高 固定

1.3信号和槽

    信号:各种事件
    槽: 响应信号的动作
  当某个事件发生后,如某个按钮被点击了一下,它就会发出一个被点击的信号(signal)。
  某个对象接收到这个信号之后,就会做一些相关的处理动作(称为槽slot)。但是Qt对象不会无故收到某个信号,要想让一个对象收到另一个对象发出的信号,这时候需要建立连接(connect)
1
2
3
4
QPushButton * quitBtn = new QPushButton("关闭窗口",this);

//信号的发送者 发送的信号(函数的地址) 接收者 处理的槽函数(函数的地址)
connect(quitBtn,&QPushButton::clicked,this,&MyWidget::close);

1)sender:信号发送者

2)signal:信号

3)receiver:信号接收者

4)slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

1.4自定义信号和槽

定义信号发送方

1
2
3
4
5
6
7
8
9
10
11
#include <QObject>

class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = 0);

signals:
void hungry(); //不需要实现
};

定义信号接收方

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <QObject>
#include <QDebug>

class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = 0);
public slots:
void treat(){ //需要实现
qDebug() << "触发信号";
}
};

connect(tc,&Teacher::hungry,sd,&Student::treat);

触发信号

1
emit tc->hungry();

1.5解决槽的重载

1
2
3
4
5
6
7
void Student::treat(){
qDebug() << "test";
}

void Student::treat(QString foodName){
qDebug() << foodName;
}

解决方式

1
2
3
4
void (Teacher:: *teacherSinal)(QString) = &Teacher::hungry;
void (Student:: *studentSolt) (QString) = &Student::treat;

connect(tc,teacherSinal,sd,studentSolt);

QString转char

1
2
3
void Student::treat(QString foodName){
qDebug() << foodName.toUtf8().data();
}

1.6信号连接信号

点击按钮,触发信号

1
2
3
4
5
6
QPushButton* btn = new QPushButton("click",this);
connect(btn,&QPushButton::clicked,this,&MyWidget::ClassOver);

void (Teacher:: *teacherSinal)(QString) = &Teacher::hungry;
void (Student:: *studentSolt) (QString) = &Student::treat;
connect(tc,teacherSinal,sd,studentSolt);

信号连接信号

点击按钮的信号触发发送者的信号

1
2
3
4
5
void (Teacher:: *teacherSinal)(void) = &Teacher::hungry;
void (Student:: *studentSolt) (void) = &Student::treat;
connect(tc,teacherSinal,sd,studentSolt);

connect(btn,&QPushButton::clicked,tc,teacherSinal);

1.7Lambda 表达式

​ C++11中的Lambda表达式用于定义匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:

分为四个部分:[局部变量捕获列表]、(函数参数)、函数额外属性设置opt、函数返回值->retype、{函数主体}

1
2
3
4
5
6
7
8
[capture](parameters) opt ->retType
{
……;
}
//调用
[=](){

}();

局部变量引入方式

[ ],标识一个Lambda的开始。由于lambda表达式可以定义在某一个函数体A里边,所以lambda表达式有可能会去访问A函数中的局

部变量。中括号里边内容是描述了在lambda表达式里边可以使用的外部局部变量的列表:

    []
        表示lambda表达式不能访问外部函数体的任何局部变量

    [a]
        在函数体内部使用值传递的方式访问a变量

    [&b]
        在函数体内部使用引用传递的方式访问b变量

    [=]
        函数外的所有局部变量都通过值传递的方式使用, 函数体内使用的是副本

    [&]
        引用的方式使用lambda表达式外部的所有变量

    [=, &foo]
        foo使用引用方式, 其余是值传递的方式

    [&,foo]
        foo使用值传递方式, 其余是引用传递的方式
        
     [this]
         在函数内部可以使用类的成员函数和成员变量,=和&形式也都会默认引入
  由于引用方式捕获对象会有局部变量释放了而lambda函数还没有被调用的情况。如果执行lambda函数那么引用传递方式捕获进来的

  局部变量的值不可预知。

  所以在无特殊情况下建议使用[=](){}的形式

1.8opt

最常用的是mutable声明,这部分可以省略。外部函数局部变量通过值传递引进来时,其默认是const,所以不能修改这个局部变量的拷贝,加上mutable就可以

1
2
3
4
5
int c = 0;
[ c ] () mutable {
cout << c << endl;
c = 10;
}();

lamda表达式的返回值

1
2
3
4
5
6
// int --> 返回值的类型
int b = [c] () mutable -> int {
cout << c << endl;
c = 10;
return 100;
}();

1.9槽函数使用 Lambda 表达式

以QPushButton点击事件为例:

1
2
3
connect(btn,&QPushButton::clicked,[=](){
qDebug()<<"Clicked";
});