出于解决方案的目的,我创建了一个重复我遇到的相同问题的 TestApp。
我正在将我的软件从 Qt 4.8 移植到 Qt 5.1。
我的第一个程序是多线程的,如果类是线程安全的,它可以与 QML 顺利运行。但现在我收到这条消息:
QObject::connect: No such slot TestApp::run() in ..\ThreadingTest\main.cpp:21
QQmlEngine: Illegal attempt to connect to TestApp(0x29cfb8) that is in a different thread than the QML engine QQmlEngine(0x2f3e0f8).
这是重现错误的代码:
主.cpp:
#include <QtGui/QGuiApplication>
#include <QQmlContext>
#include <QThread>
#include "qtquick2applicationviewer.h"
#include "testapp.h"
int main(int argc, char *argv[])
{
int out;
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
TestApp * testapp = new TestApp();
QThread * testappThread;
testappThread = new QThread();
QObject::connect(testappThread, SIGNAL(started()), testapp, SLOT(run()));
testapp->moveToThread(testappThread);
testappThread->start();
viewer.rootContext()->setContextProperty("TestApp", testapp);
viewer.setMainQmlFile(QStringLiteral("qml/ThreadingTest/main.qml"));
viewer.showExpanded();
out = app.exec();
testappThread->quit();
testappThread->wait();
delete testapp;
delete testappThread;
return out;
}
测试应用程序.h:
#ifndef TESTAPP_H
#define TESTAPP_H
#include <QObject>
#include <QString>
#include <QTimer>
#include <QReadWriteLock>
#define HELLOWORLD "Hello World !"
extern QReadWriteLock HelloWorldLock;
class TestApp : public QObject
{
Q_OBJECT
Q_PROPERTY(QString HelloWorld READ getHelloWorld WRITE setHelloWorld NOTIFY HelloWorldChanged)
public:
explicit TestApp(QObject *parent = 0);
virtual ~TestApp();
QString getHelloWorld();
void setHelloWorld(QString);
public slots:
void run();
void toggleHelloWorld();
signals:
void HelloWorldChanged();
private:
QString m_HelloWorld;
QTimer * m_Timer;
};
#endif // TESTAPP_H
测试应用程序.cpp:
#include "testapp.h"
QReadWriteLock HelloWorldLock(QReadWriteLock::Recursive);
TestApp::TestApp(QObject *parent) :
QObject(parent)
{
HelloWorldLock.lockForWrite();
m_HelloWorld = HELLOWORLD;
HelloWorldLock.unlock();
m_Timer = new QTimer(this);
connect(m_Timer, SIGNAL(timeout()), this, SLOT(toggleHelloWorld()));
}
TestApp::~TestApp() {
m_Timer->stop();
delete m_Timer;
}
QString TestApp::getHelloWorld() {
HelloWorldLock.lockForRead();
QString out = m_HelloWorld;
HelloWorldLock.unlock();
return out;
}
void TestApp::setHelloWorld(QString text) {
HelloWorldLock.lockForWrite();
m_HelloWorld = text;
HelloWorldLock.unlock();
emit HelloWorldChanged();
}
void TestApp::run() {
m_Timer->start(1000);
}
void TestApp::toggleHelloWorld() {
HelloWorldLock.lockForWrite();
if(m_HelloWorld == "") {
m_HelloWorld = HELLOWORLD;
}
else {
m_HelloWorld = "";
}
HelloWorldLock.unlock();
emit HelloWorldChanged();
}
main.qml:
import QtQuick 2.0
Rectangle {
width: 360
height: 360
Text {
text: TestApp.HelloWorld
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
我的程序非常复杂(有很多属性和类与接口共享),我不想创建一个接口类来连接我的属性......你有什么建议来解决这个问题吗?