如何识别插槽中发出的信号?
how to recognize which signal emitted in slot?
我将两个信号连接到同一个插槽。像这样:
check = new QCheckBox();
connect(check, SIGNAL(clicked()), this, SLOT(MySlot()));
connect(check, SIGNAL(toggled(bool)),this,SLOT(MySlot()));
我不想定义其他插槽。在 MySlot
中是否可以识别哪个信号回调插槽?
我怎样才能做到这一点?
您或许可以使用与发件人关联的 QMetaObject
/QMetaMethod
数据来获取您想要的内容(未经测试)...
void MyClass::MySlot ()
{
auto index = senderSignalIndex();
if (index == sender()->indexOfSignal("clicked()")) {
/*
* Got here as the result of a clicked() signal.
*/
} else if (index == sender()->indexOfSignal("toggled(bool)")) {
/*
* Got here as the result of a toggled(bool) signal.
*/
}
}
但是,如果您使用的是 Qt5,我建议您使用新的 signal/slot 语法和 lambdas...
check = new QCheckBox();
connect(check, &QCheckBox::clicked,
[this]()
{
MySlot(false);
});
connect(check, &QCheckBox::toggled,
[this](bool toggled)
{
MySlot(true, toggled);
});
连同对 MySlot
签名的更改...
/**
* @param from_toggled_signal If true this call was triggered by a
* QCheckBox::toggled signal, otherwise it's
* the result of a QCheckBox::clicked signal.
*
* @param toggle_value If from_toggled_signal is true then this was the
* value passed to QCheckBox::toggled, otherwise unused.
*/
void MyClass::MySlot (bool from_toggled_signal, bool toggle_value = false)
{
.
.
.
}
可以使用 lambda 动态定义新槽 :)
class MyClass : public QWidget {
QSomeLayout m_layout{this};
QCheckBox m_check;
enum Signal { Clicked, Toggled };
Q_SLOT void mySlot(Signal);
public:
MyClass( ... ) : ... {
m_layout.addWidget(&m_check);
connect(&m_check, &QCheckBox::clicked, this, [this]{ mySlot(Clicked); });
connect(&m_check, &QCheckBox::toggled, this, [this]{ mySlot(Toggled); });
}
};
如果有帮助,您还可以将自己的上下文添加到信号中。例如,我有一项服务可以为多个 windows 下载用户头像。我需要 window 只加载它感兴趣的用户,所以我会传入用户的 ID 作为上下文。类似于:
void UserService::downloadAvatar(const QString& url, const int context = 0) {
...// Make the http request, on finished:
emit onAvatarDownloaded(context, responseBody);
}
我将两个信号连接到同一个插槽。像这样:
check = new QCheckBox();
connect(check, SIGNAL(clicked()), this, SLOT(MySlot()));
connect(check, SIGNAL(toggled(bool)),this,SLOT(MySlot()));
我不想定义其他插槽。在 MySlot
中是否可以识别哪个信号回调插槽?
我怎样才能做到这一点?
您或许可以使用与发件人关联的 QMetaObject
/QMetaMethod
数据来获取您想要的内容(未经测试)...
void MyClass::MySlot ()
{
auto index = senderSignalIndex();
if (index == sender()->indexOfSignal("clicked()")) {
/*
* Got here as the result of a clicked() signal.
*/
} else if (index == sender()->indexOfSignal("toggled(bool)")) {
/*
* Got here as the result of a toggled(bool) signal.
*/
}
}
但是,如果您使用的是 Qt5,我建议您使用新的 signal/slot 语法和 lambdas...
check = new QCheckBox();
connect(check, &QCheckBox::clicked,
[this]()
{
MySlot(false);
});
connect(check, &QCheckBox::toggled,
[this](bool toggled)
{
MySlot(true, toggled);
});
连同对 MySlot
签名的更改...
/**
* @param from_toggled_signal If true this call was triggered by a
* QCheckBox::toggled signal, otherwise it's
* the result of a QCheckBox::clicked signal.
*
* @param toggle_value If from_toggled_signal is true then this was the
* value passed to QCheckBox::toggled, otherwise unused.
*/
void MyClass::MySlot (bool from_toggled_signal, bool toggle_value = false)
{
.
.
.
}
可以使用 lambda 动态定义新槽 :)
class MyClass : public QWidget {
QSomeLayout m_layout{this};
QCheckBox m_check;
enum Signal { Clicked, Toggled };
Q_SLOT void mySlot(Signal);
public:
MyClass( ... ) : ... {
m_layout.addWidget(&m_check);
connect(&m_check, &QCheckBox::clicked, this, [this]{ mySlot(Clicked); });
connect(&m_check, &QCheckBox::toggled, this, [this]{ mySlot(Toggled); });
}
};
如果有帮助,您还可以将自己的上下文添加到信号中。例如,我有一项服务可以为多个 windows 下载用户头像。我需要 window 只加载它感兴趣的用户,所以我会传入用户的 ID 作为上下文。类似于:
void UserService::downloadAvatar(const QString& url, const int context = 0) {
...// Make the http request, on finished:
emit onAvatarDownloaded(context, responseBody);
}