QT SLOT: указатель на ошибку функции-члена

В настоящее время я работаю над проектом Qt, и у меня есть некоторые проблемы со слотами. Я хочу передать указатель на функцию-член в качестве аргумента SLOT. Для этого я объявил SLOT в своем классе, но когда я это делаю, я получаю ошибку MOC. Я не знаю, возможно ли то, чего я хочу достичь.

Пример синтаксиса для класса MainFrame:

void slotAnswerReceived (QString answer, void (MainFrame::*ptr)(QString));

У меня нигде нет подключения, ничего не использует эту функцию, и единственная ошибка, которая у меня есть, находится в этой строке выше.

Спасибо всем за помощь. Я не могу найти какое-либо решение в Интернете (но я нашел эту статью, объясняющую SIGNAL и SLOT в глубину, если кому-то интересно).


person user3429997    schedule 24.03.2014    source источник
comment
Просто небольшой вопрос: почему вы хотите передать указатель в качестве аргумента?   -  person Thomas Ayoub    schedule 24.03.2014
comment
Какая у вас ошибка? Возможно, вы забыли вызвать Q_DECLARE_METATYPE/qRegisterMetatype для типа указателя вашей функции?   -  person Dmitry Sazonov    schedule 24.03.2014
comment
[debug/moc_MainFrame.cpp] Ошибка 1. Не слышал о Q_DECLARE_METATYPE (посмотрю). Я знаю, что могу опубликовать объявление этой функции, и она работает, но я не могу использовать ее как SLOT из-за этой ошибки. Я использую QTcpServer, и когда я получаю ответ, я также получаю этот указатель, который дает мне следующую функцию для вызова.   -  person user3429997    schedule 24.03.2014
comment
Пробовал ставить qRegisterMetaType‹MainFrame›(MainFrame); но он говорит, что ошибка компиляции: QMainWindow является частным.   -  person user3429997    schedule 24.03.2014


Ответы (1)


  1. Объявите typedef для этого типа указателя на член.

  2. Объявите и зарегистрируйте метатип для этого typedef.

  3. Используйте только typedef — помните, что moc использует сравнение строк для определения равенства типов, у него нет синтаксического анализатора выражения типа C++.

Далее следует пример. Во время вызова a.exec() в очереди событий есть два события QMetaCallEvent. Первый на c.callSlot, второй на a.quit. Они выполняются по порядку. Напомним, что вызов в очереди (будь то из-за invokeMethod или из-за активации сигнала) приводит к отправке QMetaCallEvent для каждого получателя.

#include <QCoreApplication>
#include <QDebug>
#include <QMetaObject>

class Class : public QObject {
   Q_OBJECT
public:
   typedef void (Class::*Method)(const QString &);
private:
   void method(const QString & text) { qDebug() << text; }
   Q_SLOT void callSlot(const QString & text, Class::Method method) {
      (this->*method)(text);
   }
   Q_SIGNAL void callSignal(const QString & text, Class::Method method);
public:
   Class() {
      connect(this, SIGNAL(callSignal(QString,Class::Method)),
              SLOT(callSlot(QString,Class::Method)),
              Qt::QueuedConnection);
      emit callSignal("Hello", &Class::method);
   }
};
Q_DECLARE_METATYPE(Class::Method)

int main(int argc, char *argv[])
{
   qRegisterMetaType<Class::Method>();
   QCoreApplication a(argc, argv);
   Class c;
   QMetaObject::invokeMethod(&a, "quit", Qt::QueuedConnection);
   return a.exec();
}

#include "main.moc"
person Kuba hasn't forgotten Monica    schedule 24.03.2014