QObject::connect: 无法对 MyClass*const 类型的参数进行排队
QObject::connect: Cannot queue arguments of type MyClass*const
我有这样的 class:
#include <QObject>
namespace taservices
{
class ProcessHandle : public QObject
{
Q_OBJECT
public:
ProcessHandle(const void* const processContextPointer, const QString& process_id = "", QObject *parent = 0);
ProcessHandle();
signals:
void progress(const ProcessHandle* const self, const int value);
private:
static void registerAsMetaType();
}
我有一个信号:
void progress(const ProcessHandle* const self, const int value);
我想通过 QueuedConnedtion 连接它。我不断收到此消息:
QObject::connect: Cannot queue arguments of type 'ProcessHandle*const'
(Make sure 'ProcessHandle*const' is registered using qRegisterMetaType().)
我在声明后像这样注册我的 class:
Q_DECLARE_METATYPE(taservices::ProcessHandle*);
我还添加了这个从构造函数调用的静态方法:
void ProcessHandle::registerAsMetaType()
{
static bool called = false;
if(!called) {
called = true;
qRegisterMetaType<ProcessHandle*>("taservices::ProcessHandle*");
}
}
我也尝试注册 const
指针:
qRegisterMetaType<ProcessHandle*const>("taservices::ProcessHandle*const");
它导致以下错误:
error C2440: 'return' : cannot convert from 'taservices::ProcessHandle *const *' to 'void *'
那么如何让我的 class 使用排队连接?
原来这就是你需要的:
qRegisterMetaType<ProcessHandle*>("ProcessHandle*");
qRegisterMetaType<ProcessHandle*>("ProcessHandle*const");
出于排队参数的目的,const
指针等于普通指针,因为它正在被复制而不是被改变。
带有 const
值参数的信号毫无意义。 constness 的唯一要点是防止实现行为不当和修改值,这意味着不应以某种方式修改该值(为什么不呢?这是您泄漏到接口中的实现细节!)。信号的代码是由 moc 生成的,如果这样的代码行为不当,你已经遇到了更大的问题。
您的信号应具有以下声明:
Q_SIGNAL void progress(const ProcessHandle* self, int value);
插槽可以自由使用 const 参数。就 Qt 而言,最内层的 constness 不是签名的一部分 - 它被有效地剥离了。
您不需要注册类型。当您使用新的 connect
语法让连接访问类型时,它会自动完成。
示例:
// https://github.com/KubaO/Whosebugn/tree/master/questions/const-slot-arg-42163294
#include <QtCore>
struct ProcessHandle {};
struct Object : QObject {
int counter = 0;
Q_SIGNAL void newValue(const ProcessHandle*, int val);
Q_SLOT void useValue(const ProcessHandle* const ph, const int val) {
qDebug() << ph << val;
Q_ASSERT(ph == nullptr && val == 42);
++counter;
}
Q_OBJECT
};
int main(int argc, char ** argv) {
QCoreApplication app{argc, argv};
Object obj;
QObject::connect(&obj, &Object::newValue, &obj, &Object::useValue, Qt::QueuedConnection);
QObject::connect(&obj, &Object::newValue, &app, &QCoreApplication::quit, Qt::QueuedConnection);
emit obj.newValue(nullptr, 42);
app.exec();
Q_ASSERT(obj.counter == 1);
}
#include "main.moc"
我有这样的 class:
#include <QObject>
namespace taservices
{
class ProcessHandle : public QObject
{
Q_OBJECT
public:
ProcessHandle(const void* const processContextPointer, const QString& process_id = "", QObject *parent = 0);
ProcessHandle();
signals:
void progress(const ProcessHandle* const self, const int value);
private:
static void registerAsMetaType();
}
我有一个信号:
void progress(const ProcessHandle* const self, const int value);
我想通过 QueuedConnedtion 连接它。我不断收到此消息:
QObject::connect: Cannot queue arguments of type 'ProcessHandle*const'
(Make sure 'ProcessHandle*const' is registered using qRegisterMetaType().)
我在声明后像这样注册我的 class:
Q_DECLARE_METATYPE(taservices::ProcessHandle*);
我还添加了这个从构造函数调用的静态方法:
void ProcessHandle::registerAsMetaType()
{
static bool called = false;
if(!called) {
called = true;
qRegisterMetaType<ProcessHandle*>("taservices::ProcessHandle*");
}
}
我也尝试注册 const
指针:
qRegisterMetaType<ProcessHandle*const>("taservices::ProcessHandle*const");
它导致以下错误:
error C2440: 'return' : cannot convert from 'taservices::ProcessHandle *const *' to 'void *'
那么如何让我的 class 使用排队连接?
原来这就是你需要的:
qRegisterMetaType<ProcessHandle*>("ProcessHandle*");
qRegisterMetaType<ProcessHandle*>("ProcessHandle*const");
出于排队参数的目的,const
指针等于普通指针,因为它正在被复制而不是被改变。
带有 const
值参数的信号毫无意义。 constness 的唯一要点是防止实现行为不当和修改值,这意味着不应以某种方式修改该值(为什么不呢?这是您泄漏到接口中的实现细节!)。信号的代码是由 moc 生成的,如果这样的代码行为不当,你已经遇到了更大的问题。
您的信号应具有以下声明:
Q_SIGNAL void progress(const ProcessHandle* self, int value);
插槽可以自由使用 const 参数。就 Qt 而言,最内层的 constness 不是签名的一部分 - 它被有效地剥离了。
您不需要注册类型。当您使用新的 connect
语法让连接访问类型时,它会自动完成。
示例:
// https://github.com/KubaO/Whosebugn/tree/master/questions/const-slot-arg-42163294
#include <QtCore>
struct ProcessHandle {};
struct Object : QObject {
int counter = 0;
Q_SIGNAL void newValue(const ProcessHandle*, int val);
Q_SLOT void useValue(const ProcessHandle* const ph, const int val) {
qDebug() << ph << val;
Q_ASSERT(ph == nullptr && val == 42);
++counter;
}
Q_OBJECT
};
int main(int argc, char ** argv) {
QCoreApplication app{argc, argv};
Object obj;
QObject::connect(&obj, &Object::newValue, &obj, &Object::useValue, Qt::QueuedConnection);
QObject::connect(&obj, &Object::newValue, &app, &QCoreApplication::quit, Qt::QueuedConnection);
emit obj.newValue(nullptr, 42);
app.exec();
Q_ASSERT(obj.counter == 1);
}
#include "main.moc"