[Development] RFC: banning _q_slot() in favour of new-style connect()?

Olivier Goffart olivier at woboq.com
Fri Oct 12 12:54:51 CEST 2012


On Friday 12 October 2012 10:26:04 Olivier Goffart wrote:
> On Thursday 11 October 2012 23:06:18 Thiago Macieira wrote:
> > On sexta-feira, 12 de outubro de 2012 07.27.51, Marc Mutz wrote:
> > > Hi,
> > > 
> > > I was wondering whether we should stop using the pattern of declaring
> > > _q_privateSlots() in favour of connecting to functors or functions
> > > directly.
> > 
> > Makes sense, except that it's of inconvenient use:
> >  - lambdas: can't use in Qt code
> >  - functors: inconvenient (need to be out of the class)
> >  - static member or free functions: will not have access to the target
> > 
> > object - private member functions: disallowed by Qt coding guidelines
> 
> That is indeed a problem: it is not possible to connect to member function
> of a QObjectPrivate, only QObject.
> 
> One could add an overload  (or even a QObjectPrivate::connect) that connect
> to a QObjectPrivate function.
> 
> From the implementation point of view  it is just a matter of adding a
> QPrivateSlotObject inhartiting from QSlotBase.

Implemented here:
https://codereview.qt-project.org/37012

It adds a new QObjectPrivate::connect  funciton to connects to functions in 
the QObjectPrivate.

So now, one can do 
QObjectPrivate::connect(someObject, &SomeObject::signal, 
							d, &MyObjectPrivate::slot);

I was not sure if the receiver should be of type QObjectPrivate* or QObject*. 
I choose QObjectPrivate since it ease the implementation. But it would also be 
possible to change the patch to use 'this' instead of 'd'.


This however still do not solve the problems for third party library that do 
not rely on our private header.
For them I came up with this hack:
(code based of the test in the previous patch)


#define DECLARE_PRIVATESLOT(Class) \
    template <void (Class##Private::*F)()> \
    inline void privateSlot() { (d_func()->*F)(); } \
    template <typename A1, void (Class##Private::*F)(A1)> \
    inline void privateSlot(A1 a1) { (d_func()->*F)(a1); } \
    /* ... More to support each arguments */

class ConnectToPrivateSlot :public QObject {
    //...
private:
    DECLARE_PRIVATESLOT(ConnectToPrivateSlot);
};


QObject::connect(obj1, &SenderObject::signal1, this, 
     &ConnectToPrivateSlot::privateSlot<&ConnectToPrivateSlotPrivate::thisIsAPrivateSlot>);
QObject::connect(obj1, &SenderObject::signal7, this,
     &ConnectToPrivateSlot::privateSlot<const QVariant&,
                                        &ConnectToPrivateSlotPrivate::thisIsAPrivateSlotWithArg>);


Not very pretty, but works.  
(maybe some macro magic could make it prettier)

-- 
Olivier

Woboq - Qt services and support - http://woboq.com




More information about the Development mailing list