Qml 注册类型的构造函数中的发射信号不起作用
Emit Signal in Constructor of Qml Registered Type doesn't Work
我正在为我的应用程序设置资源管理器 class。为了管理资源的所有状态,如果它没有成功捕获资源,我需要从构造函数发出一个信号。
事实上,我想从通过 qmlRegisterType 注册 qml 的 QObject Derived Class 的构造函数发出信号。
这是我在 Linux runnng MySql 和 Qt 5.12.2 上测试过的代码。但是发射信号不起作用。
myresoureces.cpp----我的Class管理资源
MyResource::MyResource(QObject *parent) : QObject(parent)
{
if(!openResource()) {
// qDebug() << "Check Permission of FileSystem For Example.";
emit openResourceFailed("Check Permission of FileSystem For Example.");
}
}
bool MyResource::openResource()
{
// on situation opening resource failed
return false;
}
main.qml ----在qml中的用法
// ...
import My.Company.Core 1.0
// ...
MyResource {
onOpenResourceFailed: {
msgDialog.title = "Open Resource Failed!"
msgDialog.text = error
msgDialog.open()
}
}
MessageDialog {
id: msgDialog
}
// ...
main.cpp ---- 我在哪里注册 class
qmlRegisterType<MyResource>("My.Company.Core", 1, 0, "MyResource");
我希望消息对话框打开,但什么也没发生。
信号将调用在信号发射时连接的方法,在您的情况下,构造函数未连接到任何插槽,因此数据将丢失,一个可能的解决方案是使用 QTimer::singleShot(0, ...)
创建后立即发出:
MyResource::MyResource(QObject *parent=nullptr) : QObject(parent){
if(!openResource()) {
QTimer::singleShot(0, this, [this](){
emit openResourceFailed("Check Permission of FileSystem For Example.");
});
}
}
另一种替代解决方案是使用 QQmlParserStatus 作为接口并在 componentComplete()
方法中发出信号:
*.h
#ifndef MYRESOURCE_H
#define MYRESOURCE_H
#include <QObject>
#include <QQmlParserStatus>
class MyResource: public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
public:
MyResource(QObject *parent=nullptr);
void classBegin();
void componentComplete();
signals:
void openResourceFailed(const QString & error);
private:
bool openResource();
};
#endif // MYRESOURCE_H
*.cpp
#include "myresource.h"
MyResource::MyResource(QObject *parent) : QObject(parent){}
void MyResource::classBegin(){}
void MyResource::componentComplete(){
if(!openResource()) {
emit openResourceFailed("Check Permission of FileSystem For Example.");
}
}
bool MyResource::openResource(){
// on situation opening resource failed
return false;
}
我正在为我的应用程序设置资源管理器 class。为了管理资源的所有状态,如果它没有成功捕获资源,我需要从构造函数发出一个信号。
事实上,我想从通过 qmlRegisterType 注册 qml 的 QObject Derived Class 的构造函数发出信号。
这是我在 Linux runnng MySql 和 Qt 5.12.2 上测试过的代码。但是发射信号不起作用。
myresoureces.cpp----我的Class管理资源
MyResource::MyResource(QObject *parent) : QObject(parent)
{
if(!openResource()) {
// qDebug() << "Check Permission of FileSystem For Example.";
emit openResourceFailed("Check Permission of FileSystem For Example.");
}
}
bool MyResource::openResource()
{
// on situation opening resource failed
return false;
}
main.qml ----在qml中的用法
// ...
import My.Company.Core 1.0
// ...
MyResource {
onOpenResourceFailed: {
msgDialog.title = "Open Resource Failed!"
msgDialog.text = error
msgDialog.open()
}
}
MessageDialog {
id: msgDialog
}
// ...
main.cpp ---- 我在哪里注册 class
qmlRegisterType<MyResource>("My.Company.Core", 1, 0, "MyResource");
我希望消息对话框打开,但什么也没发生。
信号将调用在信号发射时连接的方法,在您的情况下,构造函数未连接到任何插槽,因此数据将丢失,一个可能的解决方案是使用 QTimer::singleShot(0, ...)
创建后立即发出:
MyResource::MyResource(QObject *parent=nullptr) : QObject(parent){
if(!openResource()) {
QTimer::singleShot(0, this, [this](){
emit openResourceFailed("Check Permission of FileSystem For Example.");
});
}
}
另一种替代解决方案是使用 QQmlParserStatus 作为接口并在 componentComplete()
方法中发出信号:
*.h
#ifndef MYRESOURCE_H
#define MYRESOURCE_H
#include <QObject>
#include <QQmlParserStatus>
class MyResource: public QObject, public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
public:
MyResource(QObject *parent=nullptr);
void classBegin();
void componentComplete();
signals:
void openResourceFailed(const QString & error);
private:
bool openResource();
};
#endif // MYRESOURCE_H
*.cpp
#include "myresource.h"
MyResource::MyResource(QObject *parent) : QObject(parent){}
void MyResource::classBegin(){}
void MyResource::componentComplete(){
if(!openResource()) {
emit openResourceFailed("Check Permission of FileSystem For Example.");
}
}
bool MyResource::openResource(){
// on situation opening resource failed
return false;
}