2017-02-10 33 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指針等於正常的指針,因爲它是被複制沒有改變。

相關問題