我正在开发一个使用QML中创建的用户界面的程序。程序的核心有两个线程:运行UI的主线程和处理所有其余工作的第二个线程。因此,程序只有一个用于与UI交互的类,另一个是后端过程。问题在于将插槽/信号从UI类连接到第二个线程上的第二个类。
代码如下: 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之间。
更具体地说,问题是在 main.cpp 中调用的 connect()函数似乎无法将给定信号与MainClass中的给定插槽链接起来:
QObject::connect(&qml, SIGNAL(onButtonClicked()), &work, SLOT(on_ButtonClicked()) );
答案 0 :(得分:2)
问题是您创建了两个QmlInterface
的实例:
QmlInterface qml;
qml.SetupUI();
和
CppInterface
{
id: cpp
}
您已经连接了第一个实例的信号,并且正在使用第二个实例发出信号。
因此,不是创建2个QmlInterface
而是创建一个,为了方便起见,您没有在QML中创建对象,而仅使用setContextProperty()
导出了在C ++中创建的对象:
// ...
#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();
}