一、QT创建一个工程
二、项目介绍
1、.pro文件
2、帮助文档
比如:我们查看QPushButton按钮控件
3、Qt的main函数介绍
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
//QApplication 应用程序类 初始化我们的应用程序
QApplication a(argc, argv);
//创建一个窗口控件
Widget w;
//显示一个窗口 hide隐藏窗口
//窗口默认是隐藏的
w.show();
//a.exec() 主事件循环(带阻塞 等待用户操作界面)
return a.exec();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
class Widget : public QWidget
{
Q_OBJECT//让Widget支持信号和槽机制
public:
Widget(QWidget *parent = 0);
~Widget();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//界面的设计是在 窗口控件的构造函数中设计
}
Widget::~Widget()
{
}
4、Qt的第一个程序
1、设置主窗口标题的函数
2、窗口简单设置
#include "widget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//this 代表当前窗口
//设置标题
this->setWindowTitle("第一个窗口");
//固定窗口,不可拖动
//this->setFixedSize(800,600);
this->resize(800,600);
//在窗口上放一个按钮
//创建一个button控件
//parent父对象为this 表明 主窗口 将来接管button
//因为我希望将button放到当前窗口中 this代表当前窗口
QPushButton *push = new QPushButton("戳我呀",this);
//默认控件会显示到主窗口的左上方
//移动按钮
QPushButton *push1 = new QPushButton("戳我呀",this);
push1->move(400,300);
}
5、对象树
在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。
当父对象析构的时候,这个列表中所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类。)
当然,我们也可以自己删除子对象,他们会自动从其父对象列表中删除。
建议:从堆区申请空间,而不是从栈区。
QWidget window;
QPushButton quit("Quit", &window);
如栈顺序:先入window,后入quit。弹栈先调用quit的析构 就会将quit从windos的孩子列表删除,然后windwos调用析构,由于孩子列表中没有对象,就不会再次去释放quit。
QPushButton quit("Quit");
QWidget window;
quit.setParent(&window);
入栈顺序:先入 quit 后window 。先调用window析构—>查看window的孩子列表 调用quit的析构。然后quit出栈 也会调用quit的析构。所以quit被调用了两次析构。
在 Qt 中,尽量在构造的时候就指定 parent 对象,并且大胆在堆上创建。
6、Qt的坐标体系
坐标体系:以左上角为原点(0,0),X向右增加,Y向下增加。
7、信号和槽机制
案例:单击button关闭窗口。
1、查看QpushButton的信号
2、查看this中的槽函数
建立:信号和槽函数的关系使用connect
connect(信号的发起者,信号,接收者,操作);
widget的构造函数中:
#include "widget.h"
#include <QPushButton>
#include <QString>
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//this 代表当前窗口
//设置标题
this->setWindowTitle("信号");
//设置窗口大小
this->resize(800,600);
//创建一个按钮
QPushButton *button = new QPushButton("关闭",this);
//需求:单击button关闭窗口
//信号的发起者button发出信号,主窗口this关闭(槽函数)
connect(button,&QPushButton::clicked,this,&QWidget::close);
//lambada表达式
QPushButton *button1 = new QPushButton("戳我呀",this);
button1->move(400,300);
connect(button1,&QPushButton::clicked,[=]{
//获取按钮上的文本
QString text = button1->text();
qDebug()<<text <<endl;
//设置按钮的文本
button1->setText("戳你咋地");
});
}
运行结果:
7、自定义信号槽
需求:
老师 -----> 饿了信号 学生----->请老师吃饭
设计两个类:老师类 学生类
添加类的步骤:
注意:
1、定义信号的规则:在signals的下方
返回值类型为void,只需声明不用实现,可以有参数,可以重载
2、定义槽函数的规则:public slots:
返回值类型为void 需要声明 需要实现 可以有参数 可以重载
3、用户可以使用emit发出信号
emit tea-> hungry();
案例:
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
#include<QString>
class student : public QObject
{
Q_OBJECT
public:
explicit student(QObject *parent = 0);
signals:
public slots:
//返回值类型为void 需要声明 需要实现 可以有参数 可以重载
void treat();
void treat(QString foodName);
};
#endif // STUDENT_H
student.cpp
#include "student.h"
#include<QDebug>
student::student(QObject *parent) : QObject(parent)
{
}
void student::treat()
{
qDebug() <<"请老师吃饭" << endl;
}
void student::treat(QString foodName)
{
qDebug() << "请老师吃饭了" <<foodName << endl;
}
teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
#include<QString>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = 0);
signals:
//定义信号的规则:返回值类型void 只需声明 不用实现 可以有参数 可以重载
void hungry();
void hungry(QString foodName);
public slots:
};
#endif // TEACHER_H
teacher.cpp
#include "teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
widget构造函数:
#include "widget.h"
#include <QPushButton>
#include <QString>
#include<QDebug>
#include "student.h"
#include "teacher.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//this 代表当前窗口
//设置标题
this->setWindowTitle("信号");
//设置窗口大小
this->resize(800,600);
//实例化一个老师
Teacher *tea = new Teacher(this);
//实例化一个学生
student *stu = new student(this);
//connect建立老师和学生的关系
//void(Teacher::*p1)() = &Teacher::hungry;
//void(student:: *p2)() = &student::treat;
//connect(tea,p1,stu,p2);
//connect建立老师和学生的关系
void(Teacher::*p1)(QString foodName) = &Teacher::hungry;
void(student:: *p2)(QString foodName) = &student::treat;
connect(tea,p1,stu,p2);
QPushButton *btn = new QPushButton("下课", this);
connect(btn,&QPushButton::clicked,[=](){
//emit tea->hungry();
emit tea->hungry("锅包肉");
});
}
Widget::~Widget()
{
}
运行结果:
总结:
1、一个信号可以和多个槽相连
如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
2、多个信号可以连接到一个槽
只要任意一个信号发出,这个槽就会被调用。
3、一个信号可以连接到另外的一个信号
当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
4、槽可以被取消链接
这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
5、Qt4版本的信号槽写法
connect(tea,SIGNAL(hungry()), stu, SLOT(treat()))
6、Qt5版本的信号槽写法
connect(tea, &Teacher::hungry, stu, &Student::treat)
8、窗口切换
swidget.h
#ifndef SWIDGET_H
#define SWIDGET_H
#include <QWidget>
class SWidget : public QWidget
{
Q_OBJECT
public:
explicit SWidget(QWidget *parent = 0);
signals:
void back();//回退信号
public slots:
};
#endif // SWIDGET_H
swidget.cpp
#include "swidget.h"
#include<QPushButton>
SWidget::SWidget(QWidget *parent) : QWidget(parent)
{
//设置窗口大小
this->resize(800,600);
//设置窗口名称
this->setWindowTitle("查询窗口");
//定义以个回退按钮
QPushButton *btn = new QPushButton("back",this);
connect(btn,&QPushButton::clicked,[=](){
emit this->back();
});
}
wieget.cpp
#include "widget.h"
#include "swidget.h"
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->resize(800,600);
this->setWindowTitle("登录");
SWidget *s = new SWidget();
QPushButton *btn = new QPushButton("下一页",this);
connect(btn,&QPushButton::clicked,[=](){
this->hide();
s->show();
});
connect(s,&SWidget::back,[=](){
s->hide();
this->show();
});
}
Widget::~Widget()
{
}
运行结果: