Qt 4.6 behaves differently when "overloading" signals

Friedrich W. H. Kossebau kossebau at kde.org
Sun Nov 8 14:56:56 GMT 2009


Pardon me, accidently sent before completing:

Dimanche, le 8 novembre 2009, à 15:22, Olivier Goffart a écrit:
> Le Sunday 08 November 2009, Friedrich W. H. Kossebau a écrit :
> > Related to this:
> > Has it ever been considered to make it possible to add signals to
> > abstract interfaces? Such that a class implementing this interface has
> > this signal?
> >
> > In Okteta/Kasten I currently use a hack I have seen somewhere else (don't
> > remember where) by adding the signal as abstract method to the interface,
> > like
> > 	virtual somethingChanged() = 0;
>
> What would be the reason for doing that at all?
> Remember the signal are normal methods implemented by the moc.
> Wether the implementation is in the base class or in the derived class does
> not matter. So better to keep it in the base class.

The base class here is an abstract interface, so not a QObject, so the signal 
can not be placed there.

Example:
An interface adds a property, say "data". Now users of classes implementing 
this interface also want to be informed about changes of this property, per 
signal. E.g. they check if the object has the interface, then read the 
current state and also connect to the change signal:
    if( dataContainer = qobject_cast<DataContainer*>(object) )
    {
        Data data = dataContainer->data();
        connect( object, SIGNAL(dataChanged( const Data& ),
            SLOT(onDataChanged( const Data& )) );
    }

Currently it's implemented like this:

class DataContainer // abstract interface
{
  public:
    virtual ~DataContainer();
  public:
    virtual Data data() const = 0;
    virtual void setData( const Data& data ) = 0;
  public: // signal hack
    virtual void dataChanged( const Data& data ) = 0;
}
Q_DECLARE_INTERFACE( DataContainer, "org.kde.datacontainer/1.0" )

class Class : public QObject, public DataContainer 
{
  Q_OBJECT
  Q_INTERFACES( DataContainer )
  public:
    virtual Data data() const;
    virtual void setData( const Data& data );
  Q_SIGNALS:
    virtual void dataChanged( const Data& data );
}

I would prefer:
class DataContainer // abstract interface
{
  public:
    virtual ~DataContainer();
  public:
    virtual Data data() const = 0;
    virtual void setData( const Data& data ) = 0;

    Q_ABSTRACT_SIGNAL(dataChanged( const Data& data ))
}

class Class : public QObject, public DataContainer 
{
  Q_OBJECT
  Q_INTERFACES( DataContainer )
  public:
    virtual Data data() const;
    virtual void setData( const Data& data );
  Q_SIGNALS:
    void dataChanged( const Data& data );
}

Moc would see there should be a signal "dataChanged( const Data& )" and checks 
if the class implementing the interface also has this.

Explained better now?

Cheers
Friedrich
-- 
Okteta - KDE 4 Hex Editor - http://utils.kde.org/projects/okteta
-- 
Okteta - KDE 4 Hex Editor - http://utils.kde.org/projects/okteta




More information about the kde-core-devel mailing list