学习第一天:2024-3-9
文章目录
- Qt creator 快捷键
- 帮助文档
- 默认生成的main.cpp逐行解释
- 核心类
- 帮助文档的查阅方法-①
- 代码创建按钮
- 第一个
- 第二个
- 对窗口的其他设置
- 对象树
- 窗口坐标系
- 信号和槽(优点:松散耦合)
- 帮助文档的查阅方法-②
- 找信号函数的方法
- 找槽函数的方法
- 自定义信号和槽
- lambda表达式
- 练习
- Menu
- Tool
Qt creator 快捷键
运行:ctrl+r
帮助文档:F1 退出文档:ESC
自动对齐:ctrl+i
帮助文档
默认生成的main.cpp逐行解释
核心类
QObject 万类之祖
帮助文档的查阅方法-①
打开assistant.exe,左侧点索引,输入QPushButton,看到右侧显示如下内容。Header是头文件,qmake是在.pro文件中应该加入的内容,Inherits是该类继承自谁(即父类),Inherited by是该类的子类。
代码创建按钮
第一个
新建一个QWidget项目,起名为btxl。在btxl.cpp中加入头文件<QPushButton>
,btxl类构造函数中加入以下内容:
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
QPushButton * bt = new QPushButon;
}
这样就创建了一个按钮,但是ctrl+r运行不显示这个按钮,why?
你想起了main.cpp中btxl类实例化的w是要通过show函数来显示的,并且QPushButton的父类的父类就是QWidget,于是做出如下修改:
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
QPushButton * bt = new QPushButon;
bt->show();
}
这下好了,运行后出现两个窗口。你想:不不不,按钮是要在页面上的。
正确写法:
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
QPushButton * bt = new QPushButon;
//bt->show();
bt->setParent(this);
}
setParent相当于设置了一个层级关系(类似于unity的hierarchy)
你还想给这个按钮上写点文字:
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
QPushButton * bt = new QPushButon;
//bt->show();
bt->setParent(this);
bt->setText("hahaha");
}
第二个
这样窗口就很小。
对窗口的其他设置
对象树
只要new出来的对象设置了parent(方法为setParent),就能加到对象树中,关掉窗口后自动析构,无需手动free。这样一定程度上简化了内存回收机制。但请注意,仅仅从QObject派生是无法自动析构的,必须要setParent。
【测试一】
myButton类派生自QPushButton,析构函数输出一句话“myButton析构”。在关掉按钮的小窗口时并没有析构。
myButton *mbtn = new myButton();
mbtn->show();
【测试二】
myButton类派生自QPushButton,析构函数输出一句话“myButton析构”。在关掉按钮的小窗口时显示析构。
myButton *mbtn = new myButton();
mbtn->setParent(this);
【测试三】
Student类和Score类派生自QObject(万类之祖)。对象s设置了parent,而对象xiaoming没有设置parent。关闭窗口时,显示s析构而xiaoming未析构。
//创建对象
xiaoming = new Student;
s = new Score;
s->setParent(this);
窗口坐标系
信号和槽(优点:松散耦合)
需求:点一个按钮,关闭窗口。翻译一下就是:按钮被点击,导致窗口被关闭。这句话加粗的四个部分就是connect的四个参数。具体的:
参数1:信号发送者
参数2:发送的信号(函数地址)
参数3:信号接收者
参数4:对信号进行的反应函数(称为槽函数(slots),也传函数地址)
信号函数和槽函数的查找就需要帮助文档了。
帮助文档的查阅方法-②
找信号函数的方法
信号的发送者是bt,类型是QPushButton。查找
在页面中找signal字样。
发现QPushButton的信号函数就是从祖先那继承来的。
点开第一个,是它的直接父类,QAbstractButton。clicked就是我们要找的。
找槽函数的方法
信号的接收者是本页面,类型是btxl,继承自QWidget。
右侧第五个Public Slots就是槽函数。
点开:
我们需要的是第一个,click()
综上,实现方法是下面这句话:
connect(bt, &QPushButton::clicked, this, &btxl::close);
或
connect(bt, &QPushButton::clicked, this, &QWidget::close);
自定义信号和槽
注意:先连接,发送信号者再发出信号。
自定义的信号写在signals下,信号只需要声明,不需要实现
自定义的槽写在public slots下,槽需要声明也需要实现
触发信号的关键字:emit
lambda表达式
lambda表达式是c++的语法糖,所谓语法糖就是复杂语法的等价简化写法。定义匿名函数(无需函数名)。
最常见的用法是[=](){}
,例如:
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
QPushButton * bt2 = new QPushButton("点我", this);
connect(bt2, &QPushButton::clicked, this, [=](){ //第三个参数可省略,默认是this
bt2->setText("已经点过啦");
});
}
lambda表达式作为槽函数时,可以使一句connect连接多个槽函数。例如:
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
//创建对象
xiaoming = new Student;
s = new Score;
QPushButton * bt = new QPushButton("x", this);
connect(bt, &QPushButton::clicked, this, [=](){
this->close();
emit xiaoming->goodStudy(); //emit可省
});
connect(xiaoming, &Student::goodStudy, s, &Score::highScore);
}
练习
窗口上有一个按钮,按一下打开一个新窗口,再按一下关闭新窗口。
#include "btxl.h"
#include <QPushButton>
btxl::btxl(QWidget *parent)
: QWidget(parent)
{
int stat = 0;
QWidget *newpage = new QWidget;
QPushButton * bt = new QPushButton("打开新窗口", this);
bt->resize(100,50); //按钮的大小
connect(bt, &QPushButton::clicked, this, [=, &stat](){
if (stat == 1)
{
newpage->close();
bt->setText("打开新窗口");
stat = 0;
}
else
{
newpage->show();
bt->setText("关闭新窗口");
stat = 1;
}
qDebug() << stat;
});
}
btxl::~btxl()
{
}
Menu
ui->setupUi(this);
resize(600, 400);
QMenuBar *bar = menuBar();
setMenuBar(bar);
QMenu * fileMenu = bar->addMenu("文件");
fileMenu->addAction("新建");
fileMenu->addSeparator();
fileMenu->addAction("打开");
QMenu * editMenu = bar->addMenu("编辑");
editMenu->addAction("查找");