QObject :: connect: невозможно поставить в очередь аргументы типа 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 *'

Так как мне заставить мой класс работать с подключениями в очереди?

4

Решение

Там нет никакого смысла, чтобы сигналы с const значения параметров. Единственная точка соприкосновения будет состоять в том, чтобы не допустить неправильного поведения и модификации значения реализацией, что подразумевает, что каким-то образом значение не должно изменяться (почему бы и нет — это деталь реализации, которая просочилась в интерфейс!). Код сигнала генерируется moc, и если такой код будет плохо себя вести, у вас уже будут большие проблемы.

Ваш сигнал должен иметь следующую декларацию:

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

Слот свободен для аргументов const. Внутренняя константность не является частью сигнатуры, если говорить о 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"
3

Другие решения

Оказывается, это то, что вам нужно:

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

Для целей очереди аргументов, const указатель равен обычному указателю, так как он копируется без изменений.

3

По вопросам рекламы [email protected]