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 *'
Итак, как заставить мой класс работать с подключениями в очереди?
2 ответа:
Нет никакого смысла в сигналах с параметрами значения
const
. Единственная точка постоянства - это предотвратить неправильное поведение реализации и изменение значения, подразумевая, что каким-то образом значение не должно быть изменено (почему бы и нет? это деталь реализации, которую вы просачиваете в интерфейс!). Код сигнала генерируется 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"