01-QT入门
QT学习方法:
1. qt命名非常规范,不同的类中功能类似的函数名称相同。比如show、setParent、move、resize、setFixedSize等。
2. 英文名称与中文翻译对应:resize重置窗口大小、setFixedSize固定窗口大小等。
一. 新建项目
类名:自定义的类名,继承自以下三种基类。
QMainWindow:自带工具栏、菜单栏等。
QDialog:对话框。
QWidget:QMainWindow和QDialog的父类,空窗体。
创建界面:勾选后就可以拖拽控件。
二. 项目文件内容介绍:
1. .h文件:Q_OBJECT:有这个宏就可以使用信号和槽机制。
2. .cpp文件:
1. #include <QApplication> //包含应用程序类,这样才能创建.exe文件;
QApplication a(argc, argv);创建应用程序对象;
return a.exec(); //程序会被阻塞到这一句,使得应用程序进入 消息/事件循环机制;相当于先写a.exec();然后再return一个值。
2. myWidget w; //创建自定义类的对象 w; w.show(); //调用show方法,显示。
3. pro文件:
1. QT += core gui //使用的qt模块。
2. greaterThan(QT_MAJOR_VERSION, 4) : QT += widgets //widget模块在大于4的版本中独立于gui模块。增加此句判断版本,如果版本大于4,那么增加此模块。
3. TARGET = first //应用程序名字,有此处决定;而不是QApplication a(argc, argv);的命名。
4. TEMPLATE = app //创建应用程序模板。表示我们创建的是应用程序,而不是库。
5. SOURCES / HEADERS:包含的源文件和头文件。
三. QT creator使用
1. Ctrl + / //注释
2. Ctrl + r //运行
3. Ctrl + i //格式对齐
4. Ctrl + 单击鼠标右键 //跳转到声明或定义
5. F4 //在cpp和h文件之间切换。
6. F1 //帮助手册
单独使用帮助文档的方法:创建D:\Qt\Qt5.9.3\5.9.3\mingw53_32\bin\assistant.exe的快捷方式,然后将快捷方式剪切到桌面。不能直接复制帮助手册。
四. 按钮
可以在自定义类的构造函数中编写代码进行测试,构造函数会自动被调用。
1. 方式一:手动设置父对象;调用show方法,会默认以顶层方式显示按钮;
setParent方法会设定按钮的父对象,但是与继承关系不同。
QPushButton *btn = new QPushButton;
// btn->show();
btn->setParent(this);
btn->setText("按钮");
2. 方式二:构造函数传入按钮名及父对象;this参数可以不写,但需要手动设置父对象或者调用show方法。
QPushButton *btn = new QPushButton("button", this);
3. 重置与固定(窗口与按钮)大小:*窗口可以不使用this调用方法,直接写函数名即可。
this->resize(600, 400); //resize(600, 400);
this->setFixedSize(400, 400); //setFixedSize(400, 400);
btn->resize(100, 50);
btn->setFixedSize(100, 50);
4. 修改窗口标题:默认为项目名称;当然此处的this也可以省略不写。
this->setWindowTitle("window");
五. 对象树
1. 是什么:
1. 树形结构,记录着父类对象与子类对象的对应关系;
2. 只有QObject类派生出来的类,才具备对象树功能。
3. 当主动关闭子类对象后,也会从父对象的children列表中删除,保证每个对象只被析构一次。
2. 作用:
1. 进入父对象的坐标系统。
2. 简化了内存回收机制,当销毁父类对象的时候,首先销毁子类对象(递归)。也就是说,我们使用new创建出来的对象不用手动delete进行删除。
3. 不同点:不同于继承关系。
六. 信号和槽
1. 是什么:
1. 信号:某个对象发出的特征/状态
2. 槽:某个对象产生的一个行为
2. 实现方式:
1. 信号:声明在signals下,只需要声明,不需要实现。
2. 槽:声明在slots下,需要实现,一个成员函数。
3. 连接:当对象A发出A信号时,对象B的槽函数就会被调用。
connect(&对象A, &A的信号, &对象B, &B的槽);
4. 点击按钮关闭窗口(系统自带的信号和槽):在写信号和槽的时候,可以先打出“&”,然后就会自动提示出信号和槽函数。
connect(btn, &QPushButton::clicked, this, &myWidget::close);
5. 自定义的信号和槽:Base class:继承就会提供构造函数,可以设置父对象。
1. 信号没有返回值类型,可以有参数,也可以重载。
2. 槽是一个普通成员函数,所以可以是任意函数,是虚函数都可以,可以有返回值(但是一般并不使用,也没有意义),可以有参数,也可以重载。
创建A、B类,继承QWidget
A.h
signals:
//信号没有返回值类型,可以有参数,也可以重载
void single();
B.h
public slots:
//槽 普通成员函数 需要实现
void sayHi();
B.cpp
void Man:: sayHi(){
qDebug() << "hello A";
}
mywidget.h
//头文件中添加两个成员变量
A *a;
B *b;
mywidget.cpp
g = new Woman(this);
b = new Man(this);
connect(g, &Woman::single, b, &Man::sayHi);
emit g->single(); //g->single();
emit:告知编译器发送一个信号,宏定义为空。直接调用g->single();也是可以的。
6. 点击按钮发出信号,执行槽函数:点击按钮是信号,在本类中添加一个槽函数用来发出信号,以触发另一个槽函数。即使用两个connect进行连接。
7. 信号和槽的对应关系
1. 一个信号可以连接多个槽
2. 一个槽可以连接多个信号
8. 带参数的信号和槽:发出信号时,信号的参数会自动被槽函数的参数接收。
规则:槽函数的参数个数可以少于信号的,但是只要是有参数的,必须顺次与信号的参数类型一致。
9. 信号和槽有重载时的连接处理
方法1:当信号和槽有重载版本的时候,需要声明函数指针,明确告诉编译器连接的是哪一个版本。
注意:如注释部分所示,QT编译会报错。
1. 函数类型转换时需要添加作用域,可以理解为权限问题,使其拥有相同的权限。
2. QT中类型转换后的函数名不需要取地址。
void (A::*sig_int)(int) = &A::single;
void (B::*slots_int)(int) = &B::sayHi;
connect(a, sig_int, b, slots_int);
connect(a2, sig_int, b, slots_int);
//void (*sig_int)(int) = &A::single;
//void (*slots_int)(int) = &B::sayHi;
//connect(a, &sig_int, b, &slots_int);
//connect(a2, &sig_int, b, &slots_int);
方法2:QT4版本信号槽重载时的连接处理写法:宏函数括号中的函数转换为字符串。
优点:简便直观
缺点:如果参数不对应,编译阶段不告警,运行阶段才告警。给程序留下潜在隐患。
connect(g, SIGNAL(single(int)), b, SLOT(sayHi(int)));
方法3:QT的语法允许使用lambda表达式作为槽函数与信号连接起来;第三个参数可以省略。
connect(btn, &QPushButton::clicked, [=](){
this->close();
});
评价:以便使用lambda表达式,之后是方法1,发放2使用较少。
10. 断开信号和槽的连接:体现QT信号和槽机制松散耦合的特征。
disconnect(g, SIGNAL(single(int)), b, SLOT(sayHi(int)));
上一篇: 老微博的新选择