2017-02-10 67 views
4

的论点我有这样的类:的QObject ::连接:不能排队MyClass类型* const的

#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().) 

注册我的阶级是这样它的声明后:

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 *' 

那么,如何让我的排队连接类的工作?

回答

3

使用const值参数信号没有任何意义。常量的唯一要点就是防止实现行为不当和修改价值,意味着不应该修改该值(为什么不呢?这是一个实现细节,你泄露到接口!)。信号的代码是由moc生成的,如果这样的代码行为不当,你已经遇到了更大的问题。

你的信号应具有以下声明:

Q_SIGNAL void progress(const ProcessHandle* self, int value); 

的槽无有常量参数。就Qt而言,最内层的常量不是签名的一部分 - 它被有效地去掉了。

您不需要注册类型。当您通过使用新的connect语法让连接访问类型时,它会自动完成。

例子:

// https://github.com/KubaO/stackoverflown/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" 
+0

的目的是保持在目标插槽的指针参数'const',因为你不应该将其更改为不同的地址。 –

3

原来这就是你需要:

qRegisterMetaType<ProcessHandle*>("ProcessHandle*"); 
qRegisterMetaType<ProcessHandle*>("ProcessHandle*const"); 

对于排队参数的目的,const指针等于正常的指针,因为它是被复制没有改变。

相关问题