【问题标题】:Obtain property changed notifier from meta-object从元对象获取属性更改通知
【发布时间】:2017-01-08 11:04:03
【问题描述】:

我想编写一个属性连接器,用于以 QML 方式连接 C++ Qt 中的属性。可能是这样的:

new PropConnector ( receiver, "propName", sender, "propName" );

propConnector 类是一个小型 QObject 类,它使用发送方作为父级,侦听属性更改的信号并设置接收方的适当属性。像这样:

class PropConnector : public QObject
{
    Q_OBJECT
private:
    QObject *_sender;
    QObject *_receiver;
    QString _senderProp;
    QString _receiverProp;
public:
    PropConnector(QObject *sender, QObject *receiver, QString senderProp, QString receiverProp) : 
      QObject(sender)
      ,_sender(sender)
      ,_receiver(receiver)
      ,_senderProp(senderProp)
      ,_receiverProp(receiverProp)
    { 
        // Is it possible to get the proper property-changed notifier signal?
        //connect(sender, SIGNAL( on<PROPERTY>Changed() ), this, SLOT( forward ) );
    }

private slots:
    void forward()
    {
        _receiver->setProperty( receiverProp, _sender->property( senderProp ) );
    }
};

唯一的问题是,我怎样才能找到我想听的属性名称的正确信号名称?我想,这是可能的,但我直到现在通过阅读元对象文档才知道。

编辑:在 Kevin 的建议下,我得以实现该类。

propconnector.h

#ifndef PROPCONNECTOR_H
#define PROPCONNECTOR_H

#include <QObject>
#include <QString>

class PropConnector : public QObject
{
    Q_OBJECT
private:
    QObject *_sender;
    QObject *_receiver;
    QString _senderProperty;
    QString _receiverProperty;
public:
    PropConnector(QObject *sender, QString senderProperty, QObject *receiver, QString receiverProperty);

private slots:
    void forward();
};

#endif // PROPCONNECTOR_H

propconnector.cpp

#include "propconnector.h"
#include <QMetaObject>
#include <QMetaProperty>

PropConnector::PropConnector(QObject *sender, QString senderProperty, QObject *receiver, QString receiverProperty) : 
  QObject(sender)
  ,_sender(sender)
  ,_receiver(receiver)
  ,_senderProperty(senderProperty)
  ,_receiverProperty(receiverProperty)
{ 
    const QMetaObject *senderMeta = sender->metaObject();
    const int index = senderMeta->indexOfProperty(senderProperty.toUtf8().constData());
    if (index != -1) {
        const QMetaProperty p = senderMeta->property(index);
        if ( p.hasNotifySignal() ) {
            const QMetaMethod s = p.notifySignal();

            QString sig = QString("2%1").arg(s.signature());
            const char *ssig = SLOT(forward());
            bool ok = connect(sender, sig.toStdString().c_str() , this, SLOT(forward()));   
            int i=0;
            i++;
        }
    }       
}

void PropConnector::forward()
{
    _receiver->setProperty( _receiverProperty.toStdString().c_str(), _sender->property( _senderProperty.toStdString().c_str() ) );
}

【问题讨论】:

    标签: c++ qt qmetaobject qmetatype


    【解决方案1】:

    您可以从QMetaProperty获取该信息

    QMetaObject *senderMeta = sender->metaObject();
    const int index = senderMeta->indexOfProperty(senderProperty.toUtf8().constData());
    if (index != -1) {
        const QMetaProperty property = senderMeta->property(index);
        if (property.hasNotifySignal) {
            const QMetaMethod notifySignal = property.notifySignal();
    
            connect(sender, notifySignal, receiver, metaMethodOfSlot);     
        }
    }
    

    未经测试,可能无法编译。 metaMethodOfSlot 将是接收器插槽的QMetaMethod,以类似的方式获得。

    【讨论】:

    • 酷,有帮助。接收器信号并不重要,因为连接只是单向的。信号是从连接器类本身发出的。我已经在问题编辑中发布了代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 2017-05-21
    • 2021-04-16
    • 1970-01-01
    • 2022-11-08
    相关资源
    最近更新 更多