一.Qt学习:
文章目录
1.自定义信号和槽
Ⅰ.信号
- 自定义信号,只能写在signals下面
- 返回值是void,只用声明,不用实现
- 可以有参,可以重载
Ⅱ.槽
- 早期的Qt版本必须写在public slots下面,高级版本可以写在public或全局下
- 返回值是void,需要声明,也需要实现
- 可以有参,也可以重载
Ⅲ.案例(教师饿,学生请客)
1 ).触发函数自动触发
1.无参
-
创建teacher.h和student.h文件
-
在teacher.h文件中创建信号
-
signals: void hungry();
-
在student.h文件中创建槽
public slots: void treat(); };
-
在student.h文件中实现槽
#include <QDebug> void Student::treat(){ qDebug("我请客"); }
-
在widge.h文件中创建teacher和student的指针,声明触发函数
#include "teacher.h" #include "student.h" private: Ui::Widget *ui; //UI界面 Teacher * th; //声明teacher指针 Student * st; //声明声明student指针 void cleras(); //声明触发函数 };
-
①//在widget.cpp文件中实例化teacher和student对象
②连接信号和槽
③创建出发函数
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->th = new Teacher(this); //在widget.cpp文件中实例化teacher和student对象
this->st = new Student(this); //在widget.cpp文件中实例化teacher和student对象
connect( th, &Teacher::hungry, st, &Student::treat); 连接信号和槽
cleras(); //创建出发函数
}
void Widget::cleras(){ //触发函数
emit th->hungry();
}
2.有参
-
重载student.h中的treat()函数
public slots: void treat(); void treat(QString foodName); };
-
重载teacher.h中的hungryt()函数
signals: void hungry(); void hungry(QString foodName);
-
重写触发函数
void Widget::cleras(){ emit th->hungry("宫保鸡丁"); }
-
重载student.cpp中的treat()函数
void Student::treat(QString foodName){ qDebug() << "我请客,吃:"<<foodName.toUtf8().data();//将String型转换为char型 }
-
有参函数的信号与槽连接:声明函数指针->函数地址
void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry; void(Student:: *studentSlot)(QString) = &Student::treat; connect( th, teacherSignal, st, studentSlot);
2)按钮手动触发
-
定义一个按钮
#include <QPushButton> QPushButton * btn = new QPushButton("下课",this);
-
实现按钮和函数的连接
connect( btn, &QPushButton::clicked, this, &Widget::cleras);
-
构造student和teacher的指向无参地址的函数指针,按钮和信号的连接、信号与槽的连接。
void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry; void(Student:: *studentSlot2)(void) = &Student::treat; connect( btn, &QPushButton::clicked, th, teacherSignal2);//按钮和信号的连接 connect( th, teacherSignal2, st, studentSlot2); //信号与槽的连接
4. 断开连接
disconnect (zt,teacherSignal2,st,studentSlot2);
Ⅳ.拓展
-
信号可以连接信号
-
一个信号可以连接多个槽
-
一个槽也可以连接多个信号
-
信号和槽函数的参数类型,必须要一一对应
-
信号的参数个数可以多于槽的参数个数,但槽的参数个数不可以多于信号的参数个数
-
QPushButton::clicked是Boolean型,只有一个参数,可以连接void型函数,但不能连接String型函数(参数类型不一致)
-
Qt4版本以前的信号和槽的连接方式
-
利用Qt4信号槽,连接无参版本
connect ( zt,SIGNAL(hungry()), st, SLOT(treat()));
-
优点:参数直观
-
缺点:类型不做检测
原因:底层将函数名转换为字符串
SIGNAL(“hungry”) SLOT(“treat”)
-
Qt5以上,支持Qt4的版本写法,反之不支持
-
2.Lambda表达式
C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:
[capture] (parameters)mutable ->return-type{
statement
} //[函数对象参数] (操作符重载函数参数)mutable ->返回值{函数体}
Ⅰ.函数对象参数
-
[],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:
-
空。没有使用任何函数对象参数。
-
=。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
-
&。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
-
this。函数体内可以使用Lambda所在类中的成员变量。
-
a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
-
&a。将a按引用进行传递。
-
a, &b。将a按值进行传递,b按引用进行传递。
-
=,&a, &b。除a和b按引用进行传递外,其他参数都按值进行传递。
-
&, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。
Ⅱ.操作符重载函数参数
- 标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。
Ⅲ.可修改标示符
- mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
QPushButton * myBtn = new QPushButton (this);
QPushButton * myBtn2 = new QPushButton (this);
myBtn2->move(100,100);
int m = 10;
connect(myBtn,&QPushButton::clicked,this,[m] ()mutable { m = 100 + 10; qDebug() << m; });
connect(myBtn2,&QPushButton::clicked,this,[=] () { qDebug() << m; });
qDebug() << m;
Ⅳ.函数返回值
- ->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。
Ⅴ.函数体
- {},标识函数的实现,这部分不能省略,但函数体可以为空。
3.QMainWindow
QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个铆接部件(dock widge ts)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。
Ⅰ.菜单栏(一个)
-
创建菜单栏,并将其加入到菜单栏中
#include <QMenuBar> QMenuBar * bar = menuBar(); setMenuBar(bar);
-
向菜单栏中加入两个内容
QMenu * fileMenu = bar->addMenu("文件"); QMenu * editMenu = bar->addMenu("编辑");
-
向菜单栏的内容中加入下拉列表
QAction * new1 = fileMenu->addAction("新建"); QAction * old = fileMenu->addAction("打开");
-
菜单栏中的内容加入分割线
fileMenu->addSeparator();
Ⅱ.工具栏(多个)
-
创建工具栏
#include <QToolBar> QToolBar * toolBar = new QToolBar(this);
-
设置默认区域
addToolBar(Qt::LeftToolBarArea,toolBar);
-
设置浮动
toolBar->setFloatable(false);
-
设置是否可以移动
toolBar->setMovable(false);
-
设置工具栏中属性
toolBar->addAction(new1); toolBar->addAction(old);
-
设置分割线
toolBar->addSeparator();
-
将按钮加入到工具栏中
#include <QPushButton> QPushButton * btn = new QPushButton("asd", this); toolBar->addWidget(btn);
Ⅲ.状态栏(一个)
-
创建状态栏,并放到窗口中。
#include <QStatusBar> QStatusBar * stBar = statusBar(); setStatusBar(stBar);
Ⅳ.标签控件(左下角和右下角)
-
创建标签控件(默认显示左下角)
#include <QLabel> QLabel * label = new QLabel("提示信息",this); stBar->addWidget(label);
-
右下角显示
QLabel * label2 = new QLabel("右侧提示信息",this); stBar->addPermanentWidget(label2);
Ⅴ.铆接部件/浮动窗口(多个)
-
新建铆接部件,是指到窗口中,并指定位置
#include <QDockWidget> QDockWidget * dockWidget = new QDockWidget("浮动",this); addDockWidget(Qt::BottomDockWidgetArea,dockWidget);
-
设置后期停靠区域
dockWidget->setAllowedAreas( Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
Ⅵ.中心部件(一个)
-
新建中心部件,放到窗口中
#include <QTextEdit> QTextEdit * edit = new QTextEdit(this); setCentralWidget(edit);
4.资源文件
-
新建资源文件夹,然后添加前缀,再添加文件
-
添加的文件需要放在此次创建的大文件下,才可以被引用
-
使用添加Qt资源 “:+ 前缀名 +文件名 ”
ui->actionNew->setIcon(gIcon ( " : / Image/Luffy.png" ) ); ui->actionopen->setIcon(QIcon ( " : / Image/LuffyQ.png" ) );
5.对话框
-
连接ui界面的操作
connect(ui->actionnew,&QAction::triggered,[=](){ // QDialog dlg(this); // dlg.exec(); // qDebug()<<"模态对话框已弹出"; QDialog * dlg2 = new QDialog(this); dlg2->resize(600,400); dlg2->show(); dlg2->setAttribute(Qt::WA_DeleteOnClose); qDebug()<<"非模态对话框已弹出"; });
-
模态对话框(不可以操作其他窗口)
QDialog dlg(this); //创建窗口,new防止打开后直接关闭,将在栈上改放到堆上 dlg.exec(); //执行
-
非模态对话框(可以操作其他窗口)
QDialog * dlg2 = new QDialog(this); //创建窗口 dlg2->resize(600,400); dlg2->show(); //展示 dlg2->setAttribute(Qt::WA_DeleteOnClose); //关闭后回收