我的目标是使用(Windows)计算机上可用的串行端口填充组合框。我为QSerialPortInfo创建了一个包装器,我想将其作为QML根上下文属性发布。我使用QtQuick2应用程序模板作为起点。
#include <QList>
#include <QObject>
class QuickSerialPortInformer : public QObject
{
Q_OBJECT
Q_PROPERTY(QList<QString> portselectionmodel READ portselectionmodel CONST)
public:
static const QuickSerialPortInformer *getInstance();
QList<QString> portselectionmodel() const;
protected:
QuickSerialPortInformer();
private:
static const QuickSerialPortInformer *Instance;
};
#endif // QUICKSERIALPORTINFORMER_H
我注册了这样的对象:
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
/* here */ engine.rootContext()->setContextProperty("serialPortInformer", QuickSerialPortInformer::getInstance());
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
属性返回的QList<QString>
应作为组合框的模型。我的猜测是QList<QString>
转换为JavaScript array
字符串,然后转换回ComboBox
模型属性所需的C ++部分。毕竟,该属性接受JavaScript中定义的字符串数组。但是,似乎在将QuickSerialPortInformer
的属性分配给model
的{{1}}时,不会进行此类编组操作。正如评论中指出的,只有一些C ++类型可以用作QtQuick视图的模型。其中一个是ComboBox
,我现在正在使用它。
QStringList
我的问题是qml上下文中ComboBox {
id: portSelector
model: serialPortInformer.portselectionmodel
}
未知。我怀疑用于注册对象的上下文对于我使用SerialPortInformer
执行的脚本是不可见的。我试图颠倒engine.load()
和load()
的顺序无济于事。我错过了什么?
根据评论和文档中的建议将setContextProperty()
重命名为SerialPortInformer
后,会出现另一个问题。 serialPortInformer
是QML中值serialPortInformer
的{{1}},而不是预期的对象。
我能够解决&#34; boolean&#34; -mystery到我能够使我的用例工作的程度。答案是我的boolean
正在返回指向true
的指针。一旦我删除了SerialPortInformer::getInstance()
- 限定符const
类型为object并公开了所需的属性。我能想到为什么首先编译的唯一原因是使用非const
构造函数调用了方法的serialPortInformer
重载。所以我的自我记录是:永远不要在QML上下文中注册指向常量const QVariant &
的指针
答案 0 :(得分:1)
由于您只想阅读QStringList
,只需将QStringList
作为Q_INVOKABLE方法的返回类型。此外,我没有看到您创建一个QuickSerialPortInformer
的对象,您可能在原始代码中创建了该对象。总结你的代码应该是这样的,
#include <QList>
#include <QObject>
class QuickSerialPortInformer : public QObject
{
Q_OBJECT
Q_INVOKABLE QStringList portselectionmodel();
....
};
<强>的main.cpp 强>
int main(int argc, char *argv[])
{
...
QuickSerialPortInformer portInformer;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("serialPortInformer",&portInformer);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
答案 1 :(得分:0)
首先,按照以下方式(see documentation)实施Q_PROPERTY
:
Q_PROPERTY(QStringList portSelectionModel READ portSelectionModel WRITE setPortSelectionModel NOTIFY portSelectionModelChanged)
不确定为什么你的单身人士不工作,但试着像这样实施:
public:
static QuickSerialPortInformer& Instance()
{
static QuickSerialPortInformer instance;
return instance;
}
~QuickSerialPortInformer()=default;
private:
QuickSerialPortInformer()=default;
QuickSerialPortInformer(QuickSerialPortInformer const&)=delete;
void operator = (QuickSerialPortInformer const&)=delete;
在你的main.cpp上:
QQmlContext* quickSerialPortInformerCtx = engine.rootContext();
quickSerialPortInformerCtx->setContextProperty("quickserialportinformer", &QuickSerialPortInformer::Instance());
在你的qml上:
ComboBox {
model: quickserialportinformer.portSelectionModel
}
它应该有用,我之前使用过这个实现。