cma*_*t85 5 c++ macros qt moc c-preprocessor
我试图简化(即摆脱样板代码的负载)创建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 ) )
Run Code Online (Sandbox Code Playgroud)
所以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
Run Code Online (Sandbox Code Playgroud)
所以它似乎moc无法解析我的宏魔法; 虽然我不确定SY_PROXY宏存在的位置(错误来自一个被调用的类Sy_testProxy),并且SY_PROXYPROPERTY必须也是有效的(因为moc必须从中读取Q_PROPERTY宏).谁能看到我出错的地方?
为了记录:我讨厌像其他人一样的宏,但由于moc对模板和QObject虚拟继承的厌恶,我已经开始使用它们了.之所以触发此调查,是因为我在一个单独的线程中执行了大量计算的实例集合,但它们驱动了QML表示.但是QML不允许连接/属性绑定到主线程之外的对象,所以我被迫创建生活在主线程中的代理对象.如果有人有更好的想法,我对他们很开放!
moc我不太喜欢宏。它可以在一定程度上扩展它们,但是当它们变得复杂¹时会失败。
您可以尝试将其替换signals:为public:²(即,手动扩展signals宏),并通过Q_SIGNAL在函数声明的前面声明希望该函数成为信号。
更换
signals:\
void Notifier( Type value );\
Run Code Online (Sandbox Code Playgroud)
与
public:\
Q_SIGNAL void Notifier( Type value );\
Run Code Online (Sandbox Code Playgroud)
¹:关于复杂的定义...我不知道什么时候失败,但是过去我遇到了一些不同的问题。根据我的经验,就像signals您的示例一样,当宏主体包含另一个宏时,moc会出现问题。但这只是一个猜测-可能是moc失败的那种宏是另外一回事。
²:在Qt 5之前曾经是protected。
| 归档时间: |
|
| 查看次数: |
540 次 |
| 最近记录: |