using boost signals instead of qt

前端 未结 1 1411
被撕碎了的回忆
被撕碎了的回忆 2021-02-03 13:14

This is a long shot but, having come across a constrain in a form of a qt\'s signals, slots being unable to be templatized, I\'m just thinking of replacing them with boost signa

1条回答
  •  执念已碎
    2021-02-03 13:54

    You are not forced to use qt's signals and slots. From Using Qt with 3rd Party Signals and Slots:

    It is possible to use Qt with a 3rd party signal/slot mechanism. You can even use both mechanisms in the same project. Just add the following line to your qmake project (.pro) file.

    CONFIG += no_keywords
    

    It tells Qt not to define the moc keywords signals, slots, and emit, because these names will be used by a 3rd party library, e.g. Boost. Then to continue using Qt signals and slots with the no_keywords flag, simply replace all uses of the Qt moc keywords in your sources with the corresponding Qt macros Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT.

    There is a complete explanation of how to connect boost signals to qt signals.


    I found this adapter somewhere on the net, but no idea where:

    #ifndef _QT_2_FUNC_3_H_
    #define _QT_2_FUNC_3_H_
    
    #include 
    
    #include 
    #include 
    
    #include 
    
    #include 
    
    using namespace boost;
    
    namespace QtSignalAdapters
    {
    
    /**
    * \cond
    */
    template
    class Qt2FuncSlot3
    {
    public:
        typedef function FuncType;
        typedef typename function_traits::arg1_type ParmType1;
        typedef typename function_traits::arg2_type ParmType2;
        typedef typename function_traits::arg3_type ParmType3;
    
        Qt2FuncSlot3(const FuncType& func) :
            func_(func)
        {
        }
    
        void call(QObject* sender, void **arguments)
        {
            ParmType1* a1 = reinterpret_cast(arguments[1]);
            ParmType2* a2 = reinterpret_cast(arguments[2]);
            ParmType3* a3 = reinterpret_cast(arguments[3]);
            if ( func_ )
                func_(*a1,*a2, *a3);
        }
    
    private:
        FuncType func_;
    };
    /**
    * \endcond
    */
    
    template
    class Qt2Func3 : public QObject, public QtConnDefault
    {
    public:
        typedef function FuncType;
        typedef typename function_traits::arg1_type ParmType;
    
        Qt2Func3(QObject* qobject, int signalIdx, const FuncType& func,
                bool initiallyConnected=true) :
            QObject(qobject),
            QtConnDefault(qobject, signalIdx),
            func_(func)
        {
            //
            // Get the next usable slot ID on this...
            //
            slotIdx_ = metaObject()->methodCount();
    
            //
            // Create a slot to handle invoking the boost::function object.
            //
            slot_ = new Qt2FuncSlot3(func);
    
            if ( initiallyConnected )
                connect();
        }
    
        ~Qt2Func3()
        {
            delete slot_;
        }
    
        int qt_metacall(QMetaObject::Call c, int id, void **arguments)
        {
            id = QObject::qt_metacall(c, id, arguments);
            if ( id < 0 || c != QMetaObject::InvokeMetaMethod )
                return id;
    
            slot_->call(sender(), arguments);
            return -1;
        }
    
        void connect()
        {
            connect_();
        }
    
        void disconnect()
        {
            disconnect_();
        }
    
    private:
        void connect_()
        {
            connected_ =
                QMetaObject::connect(qobject_, signalIdx_, this, slotIdx_);
        }
    
        void disconnect_()
        {
            connected_ =
                !QMetaObject::disconnect(qobject_, signalIdx_, this, slotIdx_);
        }
    
    
        FuncType func_;
        Qt2FuncSlot3* slot_;
    };
    
    }
    
    #endif
    

    So, basically you have to reimplement qt_metacall function.

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