在 C++ 中循环读取 QML 对象(CheckBox)属性:总是相同的值
Posted
技术标签:
【中文标题】在 C++ 中循环读取 QML 对象(CheckBox)属性:总是相同的值【英文标题】:Reading QML object (CheckBox) property in a loop in C++: always the same value 【发布时间】:2020-03-11 03:30:26 【问题描述】:我编写了一个简单的代码,在 C++ 循环中从我的 QML 中读取复选框的值。但是,我总是得到“未选中”的值,即使在我用鼠标切换复选框之后也是如此。
QML:
CheckBox
objectName: "simulatorCheckbox"
text: "text"
C++:
QObject *rootObject = engine.rootObjects().first();
QObject *simulatorCheckboxQ = rootObject->findChild<QObject*>("simulatorCheckbox");
if (!simulatorCheckboxQ)
std::cout << "simulatorCheckboxQ not found" << std::endl;
std::exit(1);
auto consume = [&simulatorCheckboxQ]()
while(true)
QVariant simulatorCheckboxState = simulatorCheckboxQ->property("checkedState");
int simulatorCheckboxStateInt = simulatorCheckboxState.toInt();
if (simulatorCheckboxStateInt==Qt::Unchecked)
std::cout << "UNchecked!" << std::endl;
else if (simulatorCheckboxStateInt==Qt::Checked)
std::cout << "checked!" << std::endl;
else if (simulatorCheckboxStateInt==Qt::PartiallyChecked)
std::cout << "PARTIALLY checked!" << std::endl;
//delay...
;
//run consume as thread
【问题讨论】:
为什么需要while循环? 【参考方案1】:你有两个不好的做法:
不要从 C++ 访问 QML 元素,因为这可能很危险。
你不应该使用while循环,还要考虑最后一个选项线程。
在这种情况下,GUI 不是线程安全的,因此从辅助线程访问此信息是危险的。在这种情况下,只需创建一个映射 CheckBox 更改的 QObject:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>
class CheckBoxMapper: public QObject
Q_OBJECT
Q_PROPERTY(Qt::CheckState state READ state WRITE setState NOTIFY stateChanged)
public:
using QObject::QObject;
Qt::CheckState state() const
return m_state;
public slots:
void setState(Qt::CheckState state)
if (m_state == state)
return;
m_state = state;
emit stateChanged(m_state);
signals:
void stateChanged(Qt::CheckState state);
private:
Qt::CheckState m_state;
;
int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
CheckBoxMapper checkboxMapper;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("checkboxMapper", &checkboxMapper);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl)
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
, Qt::QueuedConnection);
engine.load(url);
QObject::connect(&checkboxMapper, &CheckBoxMapper::stateChanged, [](Qt::CheckState state)
qDebug() << state;
);
return app.exec();
#include "main.moc"
main.qml
CheckBox
text: "text"
onCheckStateChanged: checkboxMapper.state = checkState
Component.onCompleted: checkboxMapper.state = checkState
【讨论】:
QML 属性是“线程安全的”吗?因为这里***.com/questions/9062189/… 说我可以从 C++ 中设置它们 @LucasZanella 不,它们不是线程安全的。因此,不幸的是,他们有许多采用不良做法的答案。 我收到pastebin.com/uY1MSHZs 我做错了吗? 我没有使用 qmake,而是使用 cmake。我清理了所有内容并重建了所有内容,但仍然出现这些错误。 *** 上关于这个的所有答案似乎都依赖于人们忘记放 Q_OBJECT,这里不是这样 唯一的区别是我没有在main2.cpp
的末尾添加#include "main2.moc"
,因为它抱怨这个文件不存在以上是关于在 C++ 中循环读取 QML 对象(CheckBox)属性:总是相同的值的主要内容,如果未能解决你的问题,请参考以下文章
如何在 QML 中访问 C++ 类对象,而不是在 QML 中创建单独的对象?