Использование QtCreator 5.3 для проекта Qt Quick UI, как связать ресурс кнопки QML с вызовом функции C++

Это мой первый пост на StackOverflow, поэтому прошу извинить меня за возможные ошибки форматирования.

Я создаю проект пользовательского интерфейса Qt Quick с использованием Qt Quick Controls 1.1, и у меня есть простая кнопка в моем коде QML, которую я хотел бы вызвать в своем классе действий C++. Я вижу несколько примеров этого с более ранними версиями Qt, но они, похоже, не работают в 5.3. Я выбрал Qt Quick Controls 1.1 в настройках проекта. Я знаю, что это не должно быть слишком сложно сделать, но я не могу найти примеры с использованием QtCreator 5.3.

Вот мой файл main.qml:

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1

ApplicationWindow {
    id: parentWnd
    visible: true
    width: 640
    height: 480

    Action {
        id: actionSend
        onTriggered: console.log("SEND")
    }

    Button {
        id: send
        text: "Send Request"
        action: actionSend
        signal sendSignal()
    }
}

Вот мой main.cpp:

#include <QApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;

    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

Вот класс действий, в котором я хотел бы, чтобы кнопка QML вызывала «doSend»:

#include<QDebug>
#include<QObject>

class Action : public QObject
{
    Q_OBJECT
public:
    Action();
public slots:
    void doSend();
};

Наконец, вот мой файл проекта:

TEMPLATE = app

QT += qml quick widgets

SOURCES += main.cpp \
    action.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Default rules for deployment.
include(deployment.pri)

HEADERS += \
    action.h

Когда я запускаю это, я вижу кнопку и вижу запись «ОТПРАВИТЬ» в консоль, поэтому я знаю, что действие QML настроено правильно. Любая помощь в том, как сделать вызов Action в моем классе действий, будет очень признательна!


person Steve    schedule 03.07.2014    source источник


Ответы (1)


Есть три проблемы, с которыми вы сталкиваетесь здесь.

Во-первых, у вас нет зарегистрировал ваш Action класс с помощью QML в main.cpp:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    qmlRegisterType<Action>("StevesModule", 1, 0, "Action");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

Во-вторых, Action является Тип QML в модуле Qt Quick Controls. Он ничего не знает о вашем классе Action в C++. Если вы хотите использовать свой класс Action вместо типа Action Qt Quick Controls, вы должны импортировать его в свой файл QML:

import StevesModule 1.0

В-третьих, вы нигде не вызываете слот doSend(). Это можно сделать в обработчике onClicked кнопки:

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import StevesModule 1.0

ApplicationWindow {
    id: parentWnd
    visible: true
    width: 640
    height: 480

    Action {
        id: actionSend
    }

    Button {
        id: send
        text: "Send Request"
        onClicked: actionSend.doSend()
    }
}
person Mitch    schedule 03.07.2014
comment
Спасибо Митч, я на самом деле только что нашел более простой способ сделать то, что мне нужно, что я объясню в ответ. Я голосую за вас, потому что ваше решение также верно, и я извлек из него уроки. Спасибо! - person Steve; 03.07.2014
comment
Видимо, мне нужно просто добавить комментарий. Вот что я сделал, что тоже работает. Я нашел другой способ сделать то же самое — сделать класс C++ доступным для корневого контекста движка приложения, например так: engine.rootContext()->setContextProperty(MyAction, new Action()); Затем в файле qml я могу сделать: Action {id: actionSend onTriggered: MyObject.doSend()} - person Steve; 03.07.2014
comment
Извини, Митч, видимо, у меня недостаточно очков репутации, чтобы проголосовать за тебя. - person Steve; 03.07.2014
comment
Не волнуйтесь. :) Подход setContextProperty хорош, когда у вас есть один объект, а подход qmlRegisterType хорош, когда вы хотите создать множество элементов из QML. - person Mitch; 04.07.2014