Создать базовый интерфейс Qt с QML - PullRequest
0 голосов
/ 18 ноября 2018

Я работаю над программой, которая использует пользовательский интерфейс, созданный в QML.Программа в своей основе состоит из двух потоков: основного потока, в котором работает пользовательский интерфейс, и второго потока, который будет обрабатывать всю остальную работу.Так что однажды у программы есть класс для взаимодействия с пользовательским интерфейсом и второй класс, который является внутренним процессом.Проблема заключается в подключении слотов / сигналов из класса пользовательского интерфейса ко второму классу во втором потоке.

Код следующий: main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "QmlInterface.h"
#include "MainClass.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<QmlInterface>("CppInterface",1,0,"CppInterface");

    /* Ui Stuff */
    QmlInterface qml;
    qml.SetupUI();

    /* Main class */
    MainClass work;
    QObject::connect(&qml, SIGNAL(onButtonClicked()), &work, SLOT(on_ButtonClicked()) );

    return app.exec();
}

QmlInterface.h

#ifndef QMLINTERFACE_H
#define QMLINTERFACE_H

#include <QObject>
#include <QDebug>
#include <QQmlApplicationEngine>

class QmlInterface : public QObject
{
    Q_OBJECT
public:
    explicit QmlInterface();
    virtual ~QmlInterface();
    void SetupUI();

public slots:
    Q_INVOKABLE void buttonClicked();
signals:
    void onButtonClicked();
private:
    QQmlApplicationEngine *engine;
};

#endif // QMLINTERFACE_H

QmlInterface.cpp

#include "QmlInterface.h"

QmlInterface::QmlInterface()
{

}

QmlInterface::~QmlInterface()
{

}

void QmlInterface::SetupUI()
{
    engine = new QQmlApplicationEngine;
    engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine->rootObjects().isEmpty())
    {
        qDebug() << "Failed to load UI";
    }
}

void QmlInterface::buttonClicked()
{
    qDebug() << "Button clicked! Signal to be emited!";
    emit onButtonClicked();
}

MainClass.h

#ifndef MAINCLASS_H
#define MAINCLASS_H

#include <QThread>
#include <QtDebug>

class MainClass : public QThread
{
    Q_OBJECT
public:
    MainClass();
    virtual ~MainClass() {}

public slots:
    void on_ButtonClicked();

private:
    void run();
};

#endif // MAINCLASS_H

MainClass.cpp

#include "MainClass.h"

MainClass::MainClass()
{

}

void MainClass::on_ButtonClicked()
{
    qDebug() << "Button click received in main class!";

}

void MainClass::run()
{
    while(1)
    {
        QThread::sleep(1);
    }
}

И наконец main.qml

import QtQuick 2.11
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Window 2.1

import CppInterface 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    CppInterface
    {
        id: cpp
    }

    Button
    {
        text: "Click me"
        onPressed: {
            cpp.buttonClicked();
        }
    }

}

Работает соединение между QML и QmlInterfaceотлично!Проблема заключается в соединении между QmlInterface и MainClass.

Точнее говоря, проблема в том, что функция connect () , вызываемая в main.cpp , кажется, невозможность связать данный сигнал с данным слотом из MainClass:

QObject::connect(&qml, SIGNAL(onButtonClicked()), &work, SLOT(on_ButtonClicked()) );

1 Ответ

0 голосов
/ 18 ноября 2018

Проблема в том, что вы создали 2 экземпляра QmlInterface:

QmlInterface qml;
qml.SetupUI();

и

CppInterface
{
    id: cpp
}

И вы подключили сигнал первого экземпляра, и выизлучение сигнала с использованием второго экземпляра.

Таким образом, вместо создания 2 QmlInterface просто создайте его, для удобства вы не создаете объект в QML и экспортируете только объект, созданный в C ++, используя setContextProperty():

// ...
#include <QQmlContext>
// ...
void QmlInterface::SetupUI()
{
    engine = new QQmlApplicationEngine;
    engine->load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine->rootObjects().isEmpty())
        qDebug() << "Failed to load UI";
    else
        // export
        engine->rootContext()->setContextProperty("cpp", this);
}

*. Qml

import QtQuick 2.11
import QtQuick.Controls 2.1
import QtQuick.Window 2.1

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Button
    {
        text: "Click me"
        onPressed: cpp.buttonClicked();
    }
}

С другой стороны, нет необходимости регистрироваться как тип для QmlInterface, поэтому вы можете удалить его:

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    /* Ui Stuff */
    QmlInterface qml;
    qml.SetupUI();

    /* Main class */
    MainClass work;
    QObject::connect(&qml, &QmlInterface::onButtonClicked, &work, &MainClass::on_ButtonClicked );

    return app.exec();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...