gpt4 book ai didi

c++ - 绑定(bind)的 c++ 值未在 QML 中更新

转载 作者:行者123 更新时间:2023-11-28 04:51:46 25 4
gpt4 key购买 nike

我从 .ini 文件中读入 C++ 中的一个整数,然后通过绑定(bind)在 QML 中使用它。在运行时,可以更改 .ini 文件中的值,这会导致 c++ 整数也发生更改。我发现尽管整数在 c++ 中确实发生了变化(通过 qDebug() 验证),但 QML 中的绑定(bind)值没有变化,尽管发出了所需的 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")));

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::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();
}

主.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 对象:

  1. main.cpp

engine.rootContext()->setContextProperty(QStringLiteral("Config"), new Config());
  1. MainCpp 构造函数:

MainCpp::MainCpp(QObject *parent = nullptr) : QObject(parent)
{
Config configPointer;
[...]
  1. 更新方法:

void MainCpp::update(int var)
{
Config configPointer;

也就是说,如果更改其中一些不会更改其他对象,因为它们是不同的。

一个可能的解决方案是使 Config 成为单例,这样所有对象在整个应用程序中都是相同的。

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

config.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()访问对象:

ma​​incpp.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() 进行注册:

main.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)
}
}
}

完整的例子可以在下面的link中找到.

关于c++ - 绑定(bind)的 c++ 值未在 QML 中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48069595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com