Как создать универсальный метод для соединения notifySignal различных типов Q_PROPERTY с пустым слотом (QVariant) из свойства char * name?

Я пытаюсь написать метод с двумя параметрами: Q_PROPERTY название (char *) и QObject * связанные с, что позволяют подключить notifySignal (если существует) Q_PROPERTYк void slot(QVariant)или динамически построенный слот, который вызовет void method(QVariant), Сигнатура сигнала может варьироваться в зависимости от типа параметра.

Как мне добиться этого в Qt 5? Может быть, это невозможно, но я не перестану искать, пока не уверен в этом.

Поэтому я думаю, что у меня есть 3 решения:

  • динамически построить слот точной сигнатуры сигнала из имени сигнала и вызвать в нем метод (QVariant), используя старый способ соединения Qt:

    connect(sender, SIGNAL (valueChanged(QString,QString)),
        receiver, SLOT (updateValue(QString)) );
    
  • используя новую систему Qt 5 connect:

    connect(sender, &Sender::valueChanged,receiver, &Receiver::updateValue );
    
  • построение всех подписей к слотам, которые можно использовать с QVariant.

Althougt, я не знаю, как динамически построить слот, который вызывает указанный метод для первого решения; Я не знаю, как получить указатель на функцию из QMetaMethod из notifySignal, для второго решения; возможно, последнее решение - лучший способ, и его легко достичь, но оно кажется немного экстремальным.

Что вы думаете об этом?

1 ответ

Для "динамического построения слота" в Qt есть частные API (ищите QMetaObjectBuilder или подобные классы). Однако это не решает проблему соединения.

Обратите внимание, что QObject::connect перегружен, чтобы принять QMetaMethods как сигналы и слоты. Таким образом, вы можете легко построить объект класса "приемник" (с единственной целью запомнить, на какое свойство он действует):

class Receiver : public QObject {
    Q_OBJECT
public:
    explicit Receiver(const char *property, QObject *parent = 0)
        : QObject(parent),
        m_property(property)
    {}

signals:
    void propertyChangedForObject(const char *property, QObject *object);
public slots:
    void onPropertyChanged() {
        emit propertyChangedForObject(m_property, sender());
    }
private:
   const char * const m_property;
};

И подключите это в вашем методе.

Другие вопросы по тегам