7

我有这样的课:

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

那么如何让我的班级使用排队连接?

4

2 回答 2

7

原来这是你需要的:

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

出于排队参数的目的,const指针等于普通指针,因为它被复制而不是更改。

于 2017-02-10T16:05:43.613 回答
3

const带有值参数的信号没有任何意义。constness 的唯一要点是防止实现行为不端和修改值,这意味着不应以某种方式修改值(为什么不呢?这是您泄漏到接口中的实现细节!)。信号的代码是由 moc 生成的,如果这样的代码行为不端,你已经遇到了更大的问题。

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

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

该插槽可以自由使用 const 参数。就 Qt 而言,最里面的常量不是签名的一部分——它被有效地剥离了。

您不需要注册类型。当您使用新connect语法让 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"
于 2017-02-10T16:12:05.410 回答