gpt4 book ai didi

qt - 将信号连接到 QMetaProperty 的插槽

转载 作者:行者123 更新时间:2023-12-04 12:44:41 26 4
gpt4 key购买 nike

我不确定这样的事情是否可行,但我正在尝试根据已注册到 Qt 属性系统中的属性动态生成 GUI。我的假设是,由于我以这种方式使用 Q_PROPERTY() 注册了一个属性:

Q_PROPERTY(propertyType propertyName WRITE setPropertyName READ getPropertyName NOTIFY propertynameSignal)

我应该能够使用 connect() 函数检索用于连接的写入或读取函数的签名。这样做的目的是让一个对话框连接到这个对象以修改属性,但不必手写所有内容。这是可能的,是不是以错误的方式进行,还是应该对对话框进行硬编码?

编辑 1:
我将分享我拥有的一些代码(精简),希望能让我更清楚地了解我正在尝试做什么:

特定类的类声明:
class MyObject : public QObject
{
Q_OBJECT
Q_PROPERTY(bool someBool READ getBool WRITE setBool)
public:
bool someBool;

bool getBool();
void setBool(bool);
}

指向此对象的 QDialog 子类:
void MyDialog::generateUI()
{
const QMetaObject* metaObject = _MyObjectPtr->metaObject();
for (int i = 0; i < metaObject->propertyCount(); ++i)
{
QMetaProperty property = metaObject->property(i);
if (!strcmp(property.typeName(), "bool")
{
QCheckBox* checkBox = new QCheckBox(this);
bool state = metaObject->property(property->name()).toBool();
checkBox->setCheckState((state) ? Qt::Checked : Qt::Unchecked);

// Add checkBox to QDialog layout widgets here
}
}
}

原谅所有 My* 重命名,但我需要将我的实际类(class)/成员名称保密。

我可以确认 MyObjectPtr 指向的对象正在被正确读取,因为起始值反射(reflect)了我在更改它们时期望的值。问题是将它连接回那个对象。我可以更改复选框 GUI 端内的值,但这些值不会发送到 _MyObjectPtr 指向的实际对象。

最佳答案

要检索 QObject 方法(信号、槽等)的签名,您可以使用元对象 ( QMetaObject ) 信息。例如,以下代码(取自 Qt 文档)提取对象的所有方法签名:

const QMetaObject* metaObject = obj->metaObject();
QStringList methods;
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
methods << QString::fromLatin1(metaObject->method(i).signature());

要检查该方法是插槽还是信号,可以使用 QMetaMethod::methodType()功能。签名使用 QMetaMethod::signature() (引用上面的例子)。

QMetaObject reference

更新 在@HD_Mouse 更新了有关他基于对象属性创建动态 GUI 的想法的附加信息后,我想出了以下可以解决问题的代码:

添加成员变量,用于存储 GUI 组件和相应属性索引之间的映射:
class MyDialog : public QDialog
{
[..]
private:
/// Mapping between widget and the corresponding property index.
QMap<QObject *, int> m_propertyMap;
};

创建 GUI 组件时(复选框),将其更改信号连接到将处理相应属性更新的特殊插槽。
void MyDialog::generateUI()
{
const QMetaObject* metaObject = _MyObjectPtr->metaObject();
for (int i = 0; i < metaObject->propertyCount(); ++i)
{
QMetaProperty property = metaObject->property(i);
if (!strcmp(property.typeName(), "bool")
{
QCheckBox* checkBox = new QCheckBox(this);
bool state = metaObject->property(property->name()).toBool();
checkBox->setCheckState((state) ? Qt::Checked : Qt::Unchecked);

// Add checkBox to QDialog layout widgets here

// Store the property and widget mapping.
connect(checkBox, SIGNAL(stateChanged(int)),
this, SLOT(onCheckBoxChanged(int)));
m_propertyMap[checkBox] = i;
}
}
}

当一个复选框状态发生变化时,找到对应的属性(使用映射)并根据复选框状态进行更新:
void MyDialog::onCheckBoxChanged(int state)
{
QObject *checkBox = sender();
QMetaObject* metaObject = _MyObjectPtr->metaObject();
int propertyIndex = m_propertyMap.value(checkBox);
QMetaProperty property = metaObject->property(i);

// Update the property
_MyObjectPtr->setProperty(property.name(), bool(state == Qt::Checked));
}

关于qt - 将信号连接到 QMetaProperty 的插槽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18793735/

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