(7)Qt中的自定义槽(函数)

目录

槽函数定义的规则

关联信号与槽错误的示例

类成员函数函数做槽函数使用

静态类成员函数做槽函数使用

全局函数做槽函数使用

lambda表达式做槽函数使用

使用lambda表达式的注意事项

 注意事项一:

注意事项二:


槽函数定义的规则

1.槽函数返回值类型为void

2.槽函数的参数不能多于信号的参数(只能小于等于信号的参数个数)

关联信号与槽错误的示例

 按钮被点击触发一个点击信号,从而导致死循环,之后会导致程序中断。

m_btn = new QPushButton("Button", this);
//错误的示例
connect(m_btn, &QPushButton::clicked, m_btn, &QPushButton::click);

类成员函数函数做槽函数使用

类中做槽函数的成员函数一般写在public slots下,Qt5以及以上版本可以不写public slots。

#include <QApplication>
#include <QWidget>
#include <QDebug>
#include <QPushButton>
#include <QMessageBox>

//去掉控制台
#pragma comment(linker,"/subsystem:windows /entry:mainCRTStartup")

class Widget : public QWidget
{
	Q_OBJECT							// 使用信号与槽机制必须包含此宏
public:
	Widget(QWidget* parent = nullptr)
		:QWidget(parent)
	{
		setWindowTitle("自定义槽");		// 设置窗口标题
		resize(640, 480);				// 设置窗口大小

		m_btn = new QPushButton("成员函数", this);
		//使用信号与槽关联类成员函数
		connect(m_btn, &QPushButton::pressed, this, &Widget::onPressSlot);	
	}
	~Widget()
	{
	}
public slots:
	void onPressSlot()
	{
		QMessageBox::information(this, "提示", 
			"类成员函数作为槽函数使用", QMessageBox::Ok);
	}
private:
	QPushButton* m_btn = nullptr;
};

int main(int argc, char* argv[]) {

	QApplication a(argc, argv);
	Widget w;
	w.show();

	return a.exec();
}
#include "main.moc"

 

静态类成员函数做槽函数使用

class Widget : public QWidget
{
	Q_OBJECT							// 使用信号与槽机制必须包含此宏
public:
	Widget(QWidget* parent = nullptr)
		:QWidget(parent)
	{
		setWindowTitle("自定义槽");		// 设置窗口标题
		resize(640, 480);				// 设置窗口大小

		m_btn = new QPushButton("成员函数", this);
		//使用信号与槽关联静态类成员函数
		connect(m_btn, &QPushButton::pressed, this, &Widget::onPressSlot1);
		
	}
	~Widget()
	{

	}
public slots:
	static void onPressSlot1()
	{
		QMessageBox::information(nullptr, "提示",
			"静态类成员函数作为槽函数使用", QMessageBox::Ok);
	}
private:
	QPushButton* m_btn = nullptr;
};

 

全局函数做槽函数使用

void globalSlot()
{
	QMessageBox::information(nullptr, "提示",
		"全局函数作为槽函数使用", QMessageBox::Ok);
}

class Widget : public QWidget
{
	Q_OBJECT							// 使用信号与槽机制必须包含此宏
public:
	Widget(QWidget* parent = nullptr)
		:QWidget(parent)
	{
		setWindowTitle("自定义槽");		// 设置窗口标题
		resize(640, 480);				// 设置窗口大小

		m_btn = new QPushButton("全局函数", this);
		//使用信号与槽关联全局函数
		connect(m_btn, &QPushButton::pressed, this, globalSlot);
		
	}
	~Widget()
	{

	}
public slots:
private:
	QPushButton* m_btn = nullptr;
};

 

lambda表达式做槽函数使用

class Widget : public QWidget
{
	Q_OBJECT							// 使用信号与槽机制必须包含此宏
public:
	Widget(QWidget* parent = nullptr)
		:QWidget(parent)
	{
		setWindowTitle("自定义槽");		// 设置窗口标题
		resize(640, 480);				// 设置窗口大小

		m_btn = new QPushButton("lambda", this);
		//lambda表达式做槽函数使用
		connect(m_btn, &QPushButton::pressed, this, []() {
			QMessageBox::information(nullptr, "提示",
				"lambda表达式作为槽函数使用", QMessageBox::Ok);
		});
	}
	~Widget()
	{

	}
public slots:
private:
	QPushButton* m_btn = nullptr;
};

使用lambda表达式的注意事项

这样使用是没有问题的,但是如果想让cnt的值每点击一次就++,就需要使用引用捕获的方式。

m_btn = new QPushButton("Button", this);
int cnt = 0;
connect(m_btn, &QPushButton::pressed, m_btn, [=]() {
	m_btn->setText(QString::number(cnt));
});

 注意事项一:

使用引用捕获的方式捕获cnt会导致错误,因为cnt是一个栈区变量,构造函数结束内存会被销毁。

m_btn = new QPushButton("Button", this);
int cnt = 0;
connect(m_btn, &QPushButton::pressed, m_btn, [=,&cnt]() {
	m_btn->setText(QString::number(cnt++));
});

使用mutable的方式解决上述问题

m_btn = new QPushButton("Button", this);
int cnt = 0;
connect(m_btn, &QPushButton::pressed, m_btn, [=]() mutable{
	m_btn->setText(QString::number(cnt++));
});

使用静态变量解决上述问题

m_btn = new QPushButton("Button", this);
static int cnt = 0;
connect(m_btn, &QPushButton::pressed, m_btn, [=](){
	m_btn->setText(QString::number(cnt++));
});

注意事项二:

 当m_btn是类成员变量时,使用引用捕获的方式捕获是没有错误的。

m_btn = new QPushButton("Button", this);
static int cnt = 0;
connect(m_btn, &QPushButton::pressed, m_btn, [&](){
	m_btn->setText(QString::number(cnt++));
});

当m_btn是局部变量的时候,使用引用捕获的方式会直接导致程序中断。因为此时的m_btn为栈区内存,构造函数结束之后内存被释放。因此,尽量避免使用引用捕获的方式去捕获。

auto m_btn = new QPushButton("Button", this);
static int cnt = 0;
connect(m_btn, &QPushButton::pressed, m_btn, [&](){
	m_btn->setText(QString::number(cnt++));
});

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石小浪♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值