C++ использование сигнальных слотов для QML

у меня есть небольшой класс, который работает неправильно, и я не могу понять, что с ним не так. Компилятор выдает сообщение:

main.cpp: error: undefined reference to 'CDetails::CDetails()'

Это снимок из кода:

//main.cpp
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QQmlContext>
#include <QDebug>

class CDetails : public QObject
{   Q_OBJECT
    public:
        CDetails() {}
        ~CDetails(void) {}


    public slots:
        void cppSlot(const QString &msg)
        {    qDebug() << "Called the C++ slot with message:" << msg;
        }
};

int main(int argc, char *argv[])
{   QGuiApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/testqml/main.qml"));
    viewer.showExpanded();

    CDetails *test = new CDetails();
    QObject::connect((QObject*)viewer.rootObject(),
                 SIGNAL(qmlSignal(QString)),test,
                 SLOT(cppSlot(QString)));
    return app.exec();
}

и в главном.в QML:

import QtQuick 2.0
Rectangle {
    id: guide
    width: 360
    height: 360
    signal qmlSignal(string msg)
    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
    property double scaleFactor: 1.0
    property string iconUrl: "image.png"
    MouseArea {
        anchors.fill: parent
        onClicked: {
            guide.qmlSignal("Hello from QML")
        }
    }
}

Update: Спасибо за предложение по конструктору. Теперь ошибка:

error: undefined reference to 'vtable for CDetails'

что здесь упущено? Все предложения приветствуются.

2 ответов


вам не хватает реализаций вашего конструктора и деструктора. Быстрое исправление:

class CDetails : public QObject
{   Q_OBJECT
public:
  CDetails() {}
  ~CDetails(void) {}
   ...
};

ошибка: неопределенная ссылка на "vtable для CDetails"

что здесь упущено? Все предложения приветствуются.

кажется, вам не хватает moc include перед основной функцией.

main.cpp

#include <QtGui/QGuiApplication>
#include <QQmlContext>
#include <QDebug>

class CDetails : public QObject
{   Q_OBJECT
    public:
        CDetails() {}
        ~CDetails(void) {}


    public slots:
        void cppSlot(const QString &msg)
        {    qDebug() << "Called the C++ slot with message:" << msg;
        }
};

#include "main.moc"

int main(int argc, char *argv[])
{   QGuiApplication app(argc, argv);
    QQuickView view;
    viewer.setMainQmlFile(QStringLiteral("qml/testqml/main.qml"));
    viewer.showExpanded();

    CDetails *test = new CDetails();
    QObject::connect((QObject*)viewer.rootObject(),
                 SIGNAL(qmlSignal(QString)),test,
                 SLOT(cppSlot(QString)));
    return app.exec();
}

главная.про

...
TEMPLATE = app
TARGET = main
QT += quick
SOURCES += main.cpp
...

обратите внимание, что вам также нужно будет добавить свои пользовательские строки, которые были там раньше, например, работа с Application viewer и др.

альтернативно, вы могли бы также отделите класс и main.cpp, что означает, что вы поместили бы объявление класса в отдельный заголовок, а затем определение в отдельный исходный файл.

главная.cpp будет включать только что установленный заголовок, и вам нужно будет убедиться, что новый заголовок и исходный файл добавлены в HEADERS an SOURCES переменные в файле проекта qmake, соответственно, чтобы пройти обработку moc.