绑定的C++值在QML中不更新
我从一个.ini文件中读取到C++中的整数,然后通过绑定使用在QML中。在运行时,可以改变.ini文件中的值,这也会改变C++整数。我发现,尽管通过QDEUTG验证的C++确实改变了整数,但是QML中的绑定值不会改变,尽管发出了所需的更改信号。我的应用程序结构摘录如下所示: main.cpp:绑定的C++值在QML中不更新,c++,qt,qml,C++,Qt,Qml,我从一个.ini文件中读取到C++中的整数,然后通过绑定使用在QML中。在运行时,可以改变.ini文件中的值,这也会改变C++整数。我发现,尽管通过QDEUTG验证的C++确实改变了整数,但是QML中的绑定值不会改变,尽管发出了所需的更改信号。我的应用程序结构摘录如下所示: main.cpp: //Establish the QQmlApplication engine, set context properties for the two c++ files and load the QML
//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")));
maincpp.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;
config.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个配置对象引起的: main.cpp 主CPP构造函数: 更新方法: 也就是说,如果更改,其中一些对象不会更改其他对象,因为它们是不同的 一个可能的解决方案是将Config设置为单例,这样在整个应用程序中所有对象都是相同的 配置.h 然后通过getInstance访问该对象: maincpp.cpp 要在QML中使用它,必须在qmlRegisterSingletonType的帮助下注册: main.cpp
完整的示例可以在以下内容中找到。您说:.ini文件中的值可以更改,我问您是如何更改的?将SomeVotherValue更改为SomeOtherValue更改,键入。我手动修改了.ini,但没有看到这两个值中的任何一个发生更改,更好地解释自己。它会根据用户的输入以编程方式更改。我已经通过qDebug和在运行时查看.ini文件验证了此函数是否按预期工作。然后,我们需要一个,如果您不放置它,它不会重现您的错误。一如既往,非常感谢。我以前没有使用过单例,所以我将详细介绍您的解决方案,在我的应用程序中实现它,并相应地更新此帖子和标记。效果非常好,再次感谢!我今天确实学到了一些东西:但要小心单身人士!它们可能使许多事情变得容易,但通常在开始时很容易,最终导致难以重构的混乱局面。他们可能是你的朋友,但也可能是你伪装的最可怕的敌人。你会在网上找到很多关于单身的优点,甚至更多关于单身的缺点。显然,你必须小心,这是一个起点,每到最后检查它是否是你想要的,鉴于信息显示谁找我是最简单的选择,如果我有更多的信息,可以给其他选择,感谢您的意见@derM:P@eyllanesc:这不是批评你。我认为,特别是在Qt的环境中,很多东西已经是单例的,而其他的东西不会产生问题,因此,它们是一些问题的有效解决方案。只是人们经常发现独生子女很快就会滥用它,最终陷入混乱。个人而言,比起使用上下文属性,我更喜欢使用伪QML单体来发布C++模型,因为它防止阴影。
engine.rootContext()->setContextProperty(QStringLiteral("Config"), new Config());
MainCpp::MainCpp(QObject *parent = nullptr) : QObject(parent)
{
Config configPointer;
[...]
void MainCpp::update(int var)
{
Config configPointer;
#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
#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(){
[...]
}
#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();
}
#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();
}
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)
}
}
}