QT : Templated Q_OBJECT class

后端 未结 4 733
予麋鹿
予麋鹿 2020-11-29 03:26

Is it possible to have a template class, which inherit from QObject (and has Q_OBJECT macro in it\'s declaration)?

I would like to create something like adapter for

相关标签:
4条回答
  • 2020-11-29 03:46

    I tried explicitly instantiating templates, and got this :

    core_qta_qt_publisheradapter.hpp:96: Error: Template classes not supported by Q_OBJECT

    I guess that answers my question.

    EDIT

    Actually, if I place whole template class definition in the header, then the qt preprocessor doesn't process it, and then I get linker errors. Therefore it must be possible to do it, if I add missing methods.

    EDIT #2

    This library did exactly what I wanted - to use a custom signal/slot mechanism, where the slot has not-defined signature.

    0 讨论(0)
  • 2020-11-29 03:47

    It is not possible to mix template and Q_OBJECT but if you have a subset of types you can list the slots and signals like this:

        class SignalsSlots : public QObject
        {
            Q_OBJECT
    
        public:
            explicit SignalsSlots(QObject *parent = 0) :
                QObject(parent) {}
    
        public slots:
            virtual void writeAsync(int value) {}
            virtual void writeAsync(float value) {}
            virtual void writeAsync(double value) {}
            virtual void writeAsync(bool state) {}
            virtual void writeAsync(svga::SSlideSwitch::SwitchState state) {}   
    
        signals:
            void readAsynkPolledChanged(int value);
            void readAsynkPolledChanged(float value);
            void readAsynkPolledChanged(double value);
            void readAsynkPolledChanged(bool state);
            void readAsynkPolledChanged(svga::SSlideSwitch::SwitchState state);
        };
    ...
    template <class T>
    class Abstraction : public SignalsSlots
    {...
    
    0 讨论(0)
  • 2020-11-29 04:04

    Taking into account some restrictions: you can. First please became familiar (if already not) https://doc.qt.io/archives/qq/qq16-dynamicqobject.html. - it will help to imlement it. And about restrictions: you can have a template QObject class i.e. template class derived from QObject, but:

    1. Do not tell the moc to compile it.
    2. Q_OBJECT is just a macro and you have to replace it by it real content which is virtual interface and something else :)
    3. Implement QMetaObject activation (above mentioned virtual interface and be caution with object info data, which is also come from Q_OBJECT) and some else functionality and you will have template QObject (even with template slots)
    4. But as I managed to catch the one draw back - it is not possible to simply use this class as a base for another class.
    5. There are some other drawbacks - but I think the detail investigation will show you them.

    Hope this will helpful.

    0 讨论(0)
  • 2020-11-29 04:04

    It is still not possible to mix templates and Q_OBJECT but depending on your use case you may use the new 'connect'-syntax. This allows at least the usage of template-slots.

    Classical non-working approach:

    class MySignalClass : public QObject {
      Q_OBJECT
    public:
    
    signals:
      void signal_valueChanged(int newValue);
    };     
    
    
    template<class T>
    class MySlotClass : public QObject {
      Q_OBJECT
    public slots:
      void slot_setValue(const T& newValue){ /* Do sth. */}
    };
    

    Desired usage but not compilable:

    MySignalClass a;
    MySlotClass<int> b;
    
    QObject::connect(&a, SIGNAL(signal_valueChanged(int)),
                     &b, SLOT(slot_setValue(int)));
    

    Error: Template classes not supported by Q_OBJECT (For MySlotClass).

    Solution using new the 'connect'-syntax:

    // Nothing changed here
    class MySignalClass : public QObject {
      Q_OBJECT
    public:
    
    signals:
      void signal_valueChanged(int newValue);
    };
    
    
    // Removed Q_OBJECT and slots-keyword
    template<class T>
    class MySlotClass : public QObject {  // Inheritance is still required
    public:
      void slot_setValue(const T& newValue){ /* Do sth. */}
    };
    

    Now we can instantiate desired 'MySlotClass'-objects and connect them to appropriate signal emitters.

      MySignalClass a;
      MySlotClass<int> b;
    
      connect(&a, &MySignalClass::signal_valueChanged,
              &b, &MySlotClass<int>::slot_setValue);
    

    Conclusion: Using template-slots is possible. Emitting template signals is not working since a compiler error will occur due to missing Q_OBJECT.

    0 讨论(0)
提交回复
热议问题