绑定的 c++ 值在 QML 中未更新
Bound c++ value not updating in QML
我在 c++ 中将.ini文件读取为整数,然后通过绑定在 QML 中使用它。在运行时,可以更改.ini文件中的值,这会导致 c++ 整数也随之更改。我发现尽管整数在 c++ 中确实发生了变化(通过 qDebug(( 验证(,但 QML 中的绑定值并没有改变,尽管发出了所需的 changed(( 信号。我的应用程序结构摘录如下所示:
主.cpp:
//Establish the QQmlApplication engine, set context properties for the two c++ files and load the QML file.
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("MainCpp"), new MainCpp());
engine.rootContext()->setContextProperty(QStringLiteral("Config"), new Config());
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
maincppp.h:
public:
explicit MainCpp(QObject *parent = nullptr);
Q_PROPERTY(int someValue READ someValue NOTIFY someValueChanged)
int someValue(){return m_someValue;}
signals:
void someValueChanged();
private:
int m_someValue;
配置.h:
public:
explicit Config(QObject *parent = nullptr);
Q_PROPERTY(int someOtherValue READ someOtherValue NOTIFY someOtheralueChanged)
int someOtherValue(){return m_someOtherValue;}
signals:
void someOtherValueChanged();
public:
void loadSettings();
public:
int m_someOtherValue;
QString m_File;
配置.cpp:
Config::Config(QObject *parent) : QObject(parent)
{
m_File = "/some/path/to/settings/file/config.ini";
loadSettings();
}
void Config::loadSettings()
{
QSettings settings(m_File, QSettings::IniFormat);
settings.beginGroup("GROUP_NAME");
m_someOtherValue = settings.value("someOtherValueConfig", "").toInt();
settings.endGroup();
}
mainCPP.cpp:
MainCpp::MainCpp(QObject *parent = nullptr) : QObject(parent)
{
Config configPointer;
m_someValue = configPointer.someOtherValue();
emit someValueChanged();
}
main.qml:
Window {
width: 800
height: 480
Text {
id: someText
text: Config.someOtherValue //This does NOT update on changes to m_someOtherValue on the c++ side
//text: MainCpp.someValue //This DOES update on change to m_someValue on the c++ side
}
}
在 maincpp 中调用以下代码.cpp以更新.ini文件:
void MainCpp::update(int var)
{
Config configPointer;
QSettings settings("/some/path/to/settings/file/config.ini", QSettings::IniFormat);
settings.setValue("GROUP_NAME/someOtherValueConfig", var);
configPointer.m_someOtherValue = var;
m_someValue = configPointer.someOtherValue;
emit configPointer.someOtherValueChanged();
emit someValueChanged();
}
我添加了"emit someOtherValueChanged(("信号无济于事。如前所述,我知道m_someOtherValue已经改变,因为我使用 qDebug(( 查询它。如果m_someValue发生变化,为什么QML不观察m_someOtherValue的变化?
导致该行为是因为您有 3 个 Config 对象:
- 主.cpp
engine.rootContext()->setContextProperty(QStringLiteral("Config"), new Config());
- MainCpp 构造函数:
MainCpp::MainCpp(QObject *parent = nullptr) : QObject(parent)
{
Config configPointer;
[...]
- 更新方法:
void MainCpp::update(int var)
{
Config configPointer;
也就是说,如果更改了其中一些对象,则不会更改其他对象,因为它们是不同的。
一个可能的解决方案是使 Config 成为单例,因此所有对象在整个应用程序中都是相同的。
配置.h
#ifndef CONFIG_H
#define CONFIG_H
#include <QObject>
#include <QSettings>
class Config : public QObject
{
static Config* instance;
Q_OBJECT
Q_PROPERTY(int someOtherValue READ someOtherValue NOTIFY someOtherValueChanged)
explicit Config(QObject *parent = nullptr);
public:
static Config *getInstance();
int someOtherValue(){return m_someOtherValue;}
[...]
};
#endif // CONFIG_H
配置.cpp
#include "config.h"
Config* Config::instance = 0;
Config::Config(QObject *parent):QObject(parent){
m_File = "/some/path/to/settings/file/config.ini";
loadSettings();
}
Config *Config::getInstance(){
if (instance == 0)
instance = new Config;
return instance;
}
void Config::loadSettings(){
[...]
}
然后通过 getInstance ((:
主CPP.cpp
#include "maincpp.h"
MainCpp::MainCpp(QObject *parent):QObject(parent){
Config *configPointer = Config::getInstance();
m_someValue = configPointer->someOtherValue();
emit someValueChanged();
}
void MainCpp::update(int var)
{
Config *configPointer = Config::getInstance();
QSettings settings("/some/path/to/settings/file/config.ini", QSettings::IniFormat);
settings.setValue("GROUP_NAME/someOtherValueConfig", var);
configPointer->m_someOtherValue = var;
m_someValue = configPointer->someOtherValue();
emit configPointer->someOtherValueChanged();
emit someValueChanged();
}
要在QML中使用它,您必须在qmlRegisterSingletonType()
的帮助下注册:
主.cpp
#include "maincpp.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
static QObject *singletonTypeProvider(QQmlEngine *, QJSEngine *)
{
return Config::getInstance();
}
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterSingletonType<Config>("Config", 1, 0, "Config", singletonTypeProvider);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty(QStringLiteral("MainCpp"), new MainCpp());
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
在 qml 中,您必须导入模块并使用对象:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import Config 1.0
Window {
width: 800
height: 480
visible: true
ColumnLayout{
Text {
id: someText
text: Config.someOtherValue
}
Text {
id: anotherText
text: MainCpp.someValue
}
Slider {
value: 0.5
maximumValue: 100
onValueChanged: MainCpp.update(value)
}
}
}
完整的示例可以在以下链接中找到。
相关文章:
- 有没有办法有效地更新QML中的CAN数据?
- Qml 未收到基类成员变量的更新值
- 从C++更新 QML 文本
- 绑定的 c++ 值在 QML 中未更新
- 从高度动态的C 数据模型中更新QML:计时器与属性绑定
- 从C 推动QML ChartView更新
- QT QML 中的 OpenGL,无法更新屏幕上的图像
- 如何向QML显示不断更新的c++数据
- 使用更新功能扩展QML图像类型
- 是从C 中更新QML梯度值的最佳方法
- 在Qt/QML中的每一帧更新图像时运行时崩溃
- 如何在ListModel中添加元素后更新QML ListView
- QML 绑定未更新
- 在具有多个视图的 QML 中查看、编辑和更新数据(来自C++),而数据保留在C++(订阅数据)中
- 取决于C++函数的 QML 强制绑定更新
- 异步更新QML上的多个QQuickPaintedItem
- QML图像在源更改后未更新
- 如何在QML中更新基于加载器的底部控件
- 在向模型添加新数据后,QML TreeView没有在运行时更新
- (更新)QT QML 5.6 - 什么原因导致此警告"QApplication was not created in the main() thread"?