gpt4 book ai didi

c++ - 使用宏创建 QObject 派生类

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:52 25 4
gpt4 key购买 nike

我正在尝试简化(即摆脱大量样板代码)QObject 包装类的创建,这些包装类转发其他 QObject 派生类的属性访问。

从小处着手,我只是尝试使用一个属性:

// Sy_test.h - The wrapped class
class Sy_test : public QObject
{
Q_OBJECT
Q_PROPERTY( bool prop READ getProp WRITE setProp NOTIFY propChanged )

public:
Sy_test( QObject* parent = nullptr ) :
QObject{ parent },
prop_{ false } {}

bool getProp() const { return prop_; }

public slots:
void setProp( bool value )
{
if ( value != prop_ ) {
prop_ = value;
emit propChanged( prop_ );
}
}

signals:
void propChanged( bool value );

private:
bool prop_;
};

// Sy_proxy.h - The wrapper generator
#define SY_PROXYPROPERTY( Type, Name, Getter, Setter, Notifier )\
private:\
Q_PROPERTY( Type Name READ Getter WRITE Setter NOTIFY Notifier )\
\
public:\
Type Getter() const { return target_->Getter(); }\
\
public slots:\
void Setter( Type value ) { target_->Setter( value ); }\
\
signals:\
void Notifier( Type value );\
\
private:\
void setConnection()\
{\
connect( target_, &std::remove_pointer< decltype( target_ ) >::type::Notifier,\
this, &std::remove_pointer< decltype( this ) >::type::Notifier );\
}

#define SY_PROXY( ProxyName, TargetType, Prop1 )\
class ProxyName : public QObject\
{\
Q_OBJECT \
Prop1 \
\
public:\
ProxyName( TargetType* target ) :\
target_{ target }\
{\
setConnection();\
}\
\
virtual ~ProxyName() {}\
\
private:\
TargetType* target_;\
};

// This should create a Sy_test wrapper class called Sy_testProxy
SY_PROXY( Sy_testProxy,
Sy_test,
SY_PROXYPROPERTY( bool, prop, getProp, setProp, propChanged ) )

因此 SY_PROXY 宏应该创建一个名为 Sy_testProxy 的类,它带有 Sy_test::prop 属性的拷贝,其实现只是转发请求/信号。

几乎确实如此。查看后处理器输出(我使用的是 g++,所以是 .ii 文件),我可以看到构建了 Sy_testProxy 类,它与 Sy_test 类。但是,我得到一个错误:

../CppTest/Sy_proxy.h:47: Error: NOTIFY signal 'propChanged' of property 'prop' does not exist in class Sy_testProxy.
make: *** [moc_Sy_proxy.cpp] Error 1

看起来 moc 无法解析我的宏魔法;虽然我不确定 SY_PROXY 宏在哪里(错误来自一个名为 Sy_testProxy 的类),并且 SY_PROXYPROPERTY 必须也有效(因为 moc 必须从中读取 Q_PROPERTY 宏)。谁能看出我哪里出错了?

郑重声明:我和其他人一样讨厌宏,但由于 moc 对模板和 QObject 虚拟继承的厌恶,我开始使用它们。触发此调查是因为我有一组实例在单独的线程中执行繁重的计算,但它们驱动 QML 表示。但是 QML 不允许连接/属性绑定(bind)到主线程之外的对象,所以我被迫创建位于主线程中的代理对象。如果有人有更好的想法,我非常欢迎他们!

最佳答案

moc 不太喜欢宏。它在某种程度上扩展了它们,但当它们变得复杂时它就失败了¹。

您可以尝试将 signals: 替换为 public:²(即手动扩展 signals 宏),并告诉 moc 您想要通过将 Q_SIGNAL 放在函数声明的前面,函数成为一个信号。

替换

signals:\
void Notifier( Type value );\

public:\
Q_SIGNAL void Notifier( Type value );\

<子>¹: 对于 complicated 的某些定义...我不知道它什么时候失败了,但我过去遇到过一些不同的问题。根据我的经验,我的猜测是当一个宏体包含另一个宏时,moc 会出现问题,例如您示例中的 signals 。但这只是一个猜测——也许 moc 失败的宏类型是另外一回事。

<子>²:在 Qt 5 之前,它曾经是 protected

关于c++ - 使用宏创建 QObject 派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32612309/

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