QT回顾(一)
(1)命名规范及快捷键、QT基本模块
类名 : 首字母大写,单词与单词之间的首字母大写
函数名: 变量名称 首字母小写,单词和单词之间首字母大写
快捷键:
- 注释:ctrl+/
- 运行:ctrl+r
- 编译:ctrl+b
- 字体缩放:ctrl+鼠标滚轮
- 查找:ctrl+f
- 整行移动:ctrl+shift+↑或↓
- 帮助文档:F1
- 自动对齐:ctrl+i
- 同名之间的.h和.cpp切换 :F4
qt模块组成图如下:
(2)创建一个QT程序
- 创建QT项目的注意事项:
- 点击创建项目后,选择项目路径以及 给项目起名称
- 名称 - 不能有中文 ,不能有空格
- 路径 - 不能有中文路径
- 默认创建有窗口类,myWidget,基类有三种选择: QWidget 、QMainWindow、QDialog
- main函数:
5.1 QApplication a 应用程序对象,有且仅有一个
5.2 myWidget w;实例化窗口对象
5.3 w.show()调用show函数 显示窗口
5.4 return a.exec() 让应用程序对象进入消息循环机制中,代码阻塞到当前行
#include "widget.h"
#include <QApplication>//应用程序对象的头文件
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
(3)按钮控件常用API
- 创建 QPushButton * btn = new QPushButton
- 设置父亲 setParent(this)
- 设置文本 setText(“文字”)
- 设置位置 move(宽,高)
- 重新指定窗口大小 resize
- 设置窗口标题 setWindowTitle
- 设置窗口固定大小 setFixedSize
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//创建一个按钮
QPushButton*btn = new QPushButton;
// btn->show();
btn->setParent(this);
btn->setText("第一个按钮");
//创建第二个按钮
QPushButton*btn2=new QPushButton("第二个按钮",this);
//移动btn2按钮
btn2->move(100,100);
//重置窗口大小
resize(600,400);
//设置固定窗口大小
setFixedSize(600,400);
//设置窗口标题
setWindowTitle("第一个窗口");
//创建一个自己的按钮对象
myPushButton*mybtn=new myPushButton;
mybtn->setText("我自己的按钮");
mybtn->move(200,0);
mybtn->setParent(this);//设置到对象树中
}
(4)对象树和坐标系
-
当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中。
-
一定程度上简化了内存回收机制
对象树图如下:
- Qt中的坐标系 左上角为 0 , 0 点 (x以右为正方向 ,y以下为正方向)
(5)信号和槽
- connect函数的介绍:
- 参数1 信号的发送者
- 参数2 发送的信号(函数地址)
- 参数3 信号的接受者
- 参数4 处理的槽函数 (函数的地址)
示例实现:点击按钮 关闭窗口的案例
//connect(mybtn,&QPushButton::clicked,this,&QWidget::close);
connect(mybtn,&myPushButton::clicked,this,&Widget::close);
(6)自定义信号和槽
-
自定义信号注意事项
- 自定义信号,写到signals下
- 返回值void 只需要声明,不需要事先
- 可以有参数,可以有重载
-
自定义槽函数的注意事项
- 返回值void,需要声明,也需要实现
- 可以有参数,可以发生重载
- 写到 public slot下 或者public 或者全局函数
-
触发自定义的信号
- emit 自定义信号
-
示例实现:
下课后,老师触发饿了信号,学生响应信号,请客吃饭
Teacher类中:
signals:
//自定义信号,写到signals下
//返回值void 只需要声明,不需要事先
//可以有参数,可以有重载
void hungry();
Student类中:
public slots:
//返回值void,需要声明,也需要实现
//可以有参数,可以发生重载
void treat();
Student类的函数实现:
void Student::treat(){
qDebug()<<"请客吃饭";
}
Widget类的函数实现:
void Widget::classIsOver(){
//触发emit
emit tea->hungry();
}
Widget类的构造函数中:
//创建一个老师对象
this->tea=new Teacher(this);
//创建一个学生对象
this->stu=new Student(this);
//信号和槽
connect(tea,&Teacher::hungry,stu,&Student::treat);
//调用下课函数
classIsOver();
(7)当自定义信号和槽出现重载
-
1、当自定义信号和槽出现重载时如果用回(6)中的方法操作就会出现报错,因此为了解决这样错误我们需要利用函数指针明确指向函数的地址,因为connect中的发送信号与槽函数都是地址,什么是指向地址的呢,也就只有指针指向地址而已
-
函数指针指向函数地址
void(Student::*studentSlot)(QString)=&Student::treat;
void(Teacher::*teacherSingal)(QString)=&Teacher::hungry; -
接着信号和槽连接
connect(tea,teacherSingal,stu,studentSlot); -
同样示例实现:
Teacher类中:
signals:
//自定义信号,写到signals下
//返回值void 只需要声明,不需要事先
//可以有参数,可以有重载
void hungry();
void hungry(QString foodName);
Student类中:
public slots:
//返回值void,需要声明,也需要实现
//可以有参数,可以发生重载
void treat();
void treat(QString foodName);
Student类的函数实现:
void Student::treat(){
qDebug()<<"请客吃饭";
}
void Student::treat(QString foodName){
qDebug()<<"请老师吃饭,老师吃的是"<<foodName;
}
Widget类的函数实现:
void Widget::classIsOver(){
//触发emit
// emit tea->hungry();
emit tea->hungry("宫保鸡丁");
}
Widget类的构造函数中:
//创建一个老师对象
this->tea=new Teacher(this);
//创建一个学生对象
this->stu=new Student(this);
void(Student::*studentSlot)(QString)=&Student::treat;
void(Teacher::*teacherSingal)(QString)=&Teacher::hungry;
connect(tea,teacherSingal,stu,studentSlot);
// //调用下课函数
classIsOver();
运行后出现食物会加双引号:
要想去除这双引号就要将
- QString 转成 char*
- ToUtf8() 转为 QByteArray
- Data() 转为 Char *
qDebug()<<"请老师吃饭,老师吃的是"<<foodName.toUtf8().data();
- 2、信号可以连接信号、断开信号 disconnect
void(Student::*studentSlot2)(void)=&Student::treat;
void(Teacher::*teacherSingal2)(void)=&Teacher::hungry;
connect(tea,teacherSingal2,stu,studentSlot2);
//信号连接信号
connect(btn,&QPushButton::clicked,tea,teacherSingal2);
// 断开信号
disconnect(tea,teacherSingal2,stu,studentSlot2);
(8)信号与槽的拓展以及低版本写法
- 信号可以连接信号
- 一个信号可以连接多个槽函数
- 多个信号可以连接同一个槽函数
- 信号和槽函数的参数 必须类型一一对应
- 信号和槽的参数个数 是不是要一致?信号的参数个数 可以多余槽函数的参数个数
- 信号槽可以断开连接 disconnect
connect( 信号的发送者, 发送的信号SIGNAL( 信号) ,信号接受者, 槽函数SLOT(槽函数) )
-
优点 参数直观
-
缺点 编译器不会检测参数类型
信号和槽总结图如下:
(9)lambda表达式
[]标识符 匿名函数
= 值传递 & 引用传递
() 参数 {} 实现体
mutable 修饰 值传递变量 ,可以修改拷贝出的数据,改变不了本体
返回值 ->int {}
示例实现:
//利用lambda表达式实现点击按钮,关闭窗口
QPushButton*btn2=new QPushButton;
btn2->setText("关闭");
btn2->move(400,0);
btn2->setParent(this);
connect(btn2,&QPushButton::clicked,this,[=](){
btn2->setText("aa");
});