QtCreator直接转到槽
- 在QtCreator中添加槽很简单,直接在设计界面中右键Button选择
转到槽
,再选择信号即可

右键Button

选择信号
VS手动添加槽函数
- 实际上,完成上述操作,QtCreator会自动给对应界面的头文件的类中添加槽函数声明,并在.cpp文件中添加函数体

QtCreator自动在头文件中添加槽函数

QtCreator自动在.cpp文件中添加函数体
- 在VS中不会自动完成这些操作,手动完成即可。先在头文件中类的
private slots
作用域中添加槽函数声明

在头文件中声明槽函数

添加实现
- 随后打开ui界面,添加一个PushButton控件,按下F4,拖动Button拉出
配置连接
选项界面

配置连接界面
- 点击右侧的编辑会弹出新窗口,点击上侧的加号,手动添加需要响应的槽函数,即之前声明的
on_toolButton_5_clicked()
,点击OK
。这里虽然函数名是toolButton,按钮是PushButton,但是名字和实际功能没有关系,用这个名字是因为我之前已经添加了几个toolButton的槽函数,这里写文章记录为了方便直接复制函数名
- 此时回到
配置连接
界面,右侧就会出现添加的槽函数。左侧选择信号,右侧选择槽,点击OK

右侧多出了手动添加的槽
- 保存后关闭设计界面,给槽函数添加需要实现的功能,运行后点击按钮即可执行槽函数
通过代码手动连接信号槽
- 通过代码完成效率更高,无需打开设计师界面即可完成所需功能
- 在需要操作的界面的构造函数中添加控件,然后使用connect函数连接已声明和实现的槽函数即可
dlg::dlg(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::dlg)
{
ui->setupUi(this);
QPushButton* btn = new QPushButton();
btn->setText("run slot");
connect(btn, &QPushButton::clicked, this, &dlg::slot);
}
void dlg::slot()
{
QLabel* label = new QLabel();
label->setText("show");
label->show();
}
// Qt4的写法,用SIGNAL()和SLOT()两个宏将信号和槽转为const char*
QMetaObject::Connection connect(const QObject *, const char *,
const QObject *, const char *,
Qt::ConnectionType);
// QMetaMethod是Qt中一个能获取函数详细信息的类,也是Qt4的写法
QMetaObject::Connection connect(const QObject *, const QMetaMethod &,
const QObject *, const QMetaMethod &,
Qt::ConnectionType);
// 省略接受者,实际将this设为接受者
QMetaObject::Connection connect(const QObject *, const char *,
const char *,
Qt::ConnectionType) const;
// Qt5写法,信号和槽可以是成员函数指针
QMetaObject::Connection connect(const QObject *, PointerToMemberFunction,
const QObject *, PointerToMemberFunction,
Qt::ConnectionType)
// 省略接受者,不需要this,第三个参数也可以是一个lambda,或者static函数、全局函数
QMetaObject::Connection connect(const QObject *, PointerToMemberFunction,
Functor);
通过自定义信号为槽函数传参
- 通常使用的信号由Qt控件自带,而槽函数的参数必须比信号的参数少,原生信号没有参数(实际上QPushButton::clicked有一个参数,但不能自己指定),因此槽函数也不能指定参数
connect(btn, &QPushButton::clicked, this, &dlg::slot); // slot不能有参数
- 要实现传参,需要自定义信号。信号在头文件signals作用域中声明,没有返回值,也不需要在源文件中实现(实际上为了通过编译,moc会自动添加函数体)
class dlg : public QMainWindow
{
Q_OBJECT
public:
explicit dlg(QWidget* parent = 0);
~dlg();
private:
Ui::Form* ui;
QPushButton* btn;
signals:
void send(int n); // 自定义信号
private slots:
void rcv(int n); // 用于接受自定义信号的槽函数
void clk(); // 连接给btn的无参数槽函数
};
- 连接自定义信号后,使用emit即可触发所有连接到此信号的槽函数
connect(this, &dlg::send, this, &dlg::rcv);
emit send(3); // 触发槽函数
void widget::rcv(int n)
{
btn->setText(QString::number(n));
}
- 因此如果希望使用原生信号,又想传参给槽函数,只要在无参的槽函数中发送信号,即可触发有参数版本的槽函数
connect(btn, &QPushButton::clicked, this, &dlg::clk);
void dlg::clk()
{
emit send(4); // 传递参数4
}
- 信号槽不是GUI提供的,在Qt控制台程序中也可以使用,只需要让类继承QObject即可
父子窗口来回切换
- 在父窗口中设置一个按钮,点击将隐藏父窗口,创建并显示一个子窗口。在子窗口设置一个返回按钮,点击将关闭子窗口,并重新显示隐藏的父窗口
// file "parent.h"
#include "child.h"
class parent {
...
private slots:
void clickBtn();
void reshow();
};
// file "parent.cpp"
void parent::clickBtn()
{
this->hide();
child* w = new child;
connect(w, &child::reshowSignal, this, &parent::reshow);
w->show();
}
void parent::reshow()
{
this->show();
}
// file "child.h"
#include "parent.h"
class child {
...
signals:
void reshowSignal();
private slots:
void goBack();
};
// file "child.cpp"
void child::goBack()
{
emit reshowSignal();
this->close();
}
网友评论