Qt 4.6 behaves differently when "overloading" signals

View: New views
14 Messages — Rating Filter:   Alert me  

Qt 4.6 behaves differently when "overloading" signals

by Dario Freddi-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello list,

I'm writing about a problem I've run into running Qt 4.6. PolkitQt::Action
inherits from QAction, and redefines the "activated()" signal of it, so that
it gets streamed when the action is also authorized. This used to work fine
with Qt < 4.6, but with Qt 4.6 I get this warning line:

Warning: QMetaObject::indexOfSignal:PolkitQt::Action: Conflict with
QAction::activated()

And my application catching the signals actually catches QAction::activated().
I found out about this behavior also in KDE Partition Manager and I fear some
more apps might actually be hurted by this.

Any thoughts from trolls? Is this an intended change? I quite don't like the
idea to change the name of the signal to make everything work again.

--
-------------------

Dario Freddi
KDE Developer
GPG Key Signature: 511A9A3B


signature.asc (205 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Bugzilla from kde@michael-jansen.biz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

That warning and behaviour is about 5 or six years old. I asked thiago about
it some weeks before. You only see it now because it only appears in qt
developer builds which we only started to use when switching to the qt git
repo.

So i think the ... it worked with qt <4.6 may be unlikely. Are you really
sure?

Mike

On Saturday 07 November 2009 17:56:24 Dario Freddi wrote:

> Hello list,
>
> I'm writing about a problem I've run into running Qt 4.6. PolkitQt::Action
> inherits from QAction, and redefines the "activated()" signal of it, so
>  that it gets streamed when the action is also authorized. This used to
>  work fine with Qt < 4.6, but with Qt 4.6 I get this warning line:
>
> Warning: QMetaObject::indexOfSignal:PolkitQt::Action: Conflict with
> QAction::activated()
>
> And my application catching the signals actually catches
>  QAction::activated(). I found out about this behavior also in KDE
>  Partition Manager and I fear some more apps might actually be hurted by
>  this.
>
> Any thoughts from trolls? Is this an intended change? I quite don't like
>  the idea to change the name of the signal to make everything work again.
>

Re: Qt 4.6 behaves differently when "overloading" signals

by Dario Freddi-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 07 November 2009 18:19:44 you wrote:
> That warning and behaviour is about 5 or six years old. I asked thiago
>  about it some weeks before. You only see it now because it only appears in
>  qt developer builds which we only started to use when switching to the qt
>  git repo.
>
> So i think the ... it worked with qt <4.6 may be unlikely. Are you really
> sure?

Sure, otherwise for example the k3bsetup and some other polkit-qt applications
wouldn't work as expected with qt 4.5.

>
> Mike
>
> On Saturday 07 November 2009 17:56:24 Dario Freddi wrote:
> > Hello list,
> >
> > I'm writing about a problem I've run into running Qt 4.6.
> > PolkitQt::Action inherits from QAction, and redefines the "activated()"
> > signal of it, so that it gets streamed when the action is also
> > authorized. This used to work fine with Qt < 4.6, but with Qt 4.6 I get
> > this warning line:
> >
> > Warning: QMetaObject::indexOfSignal:PolkitQt::Action: Conflict with
> > QAction::activated()
> >
> > And my application catching the signals actually catches
> >  QAction::activated(). I found out about this behavior also in KDE
> >  Partition Manager and I fear some more apps might actually be hurted by
> >  this.
> >
> > Any thoughts from trolls? Is this an intended change? I quite don't like
> >  the idea to change the name of the signal to make everything work again.
>
--
-------------------

Dario Freddi
KDE Developer
GPG Key Signature: 511A9A3B


signature.asc (205 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Bugzilla from thiago@kde.org :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Em Sábado 7. Novembro 2009, às 18.26.48, Dario Freddi escreveu:

> On Saturday 07 November 2009 18:19:44 you wrote:
> > That warning and behaviour is about 5 or six years old. I asked thiago
> >  about it some weeks before. You only see it now because it only appears
> > in qt developer builds which we only started to use when switching to the
> > qt git repo.
> >
> > So i think the ... it worked with qt <4.6 may be unlikely. Are you really
> > sure?
>
> Sure, otherwise for example the k3bsetup and some other polkit-qt
>  applications wouldn't work as expected with qt 4.5.
The warning is correct.

Overriding signals is an extremely bad idea. Since signals aren't virtual, the
code in the base class that emits the signal will emit the lower-ID signal.
However, the connect() call searches from the most derived class towards
QObject -- that means you connect to the most-derived class's signal.

In other words, the signal is emitted, but it's never caught.

DO NOT override signals.

Also, Michael is right: that warning is extremely old. It was added for Qt
4.0.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Senior Product Manager - Nokia, Qt Development Frameworks
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358


signature.asc (197 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Dario Freddi-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 07 November 2009 19:19:22 Thiago Macieira wrote:

> Em Sábado 7. Novembro 2009, às 18.26.48, Dario Freddi escreveu:
> > On Saturday 07 November 2009 18:19:44 you wrote:
> > > That warning and behaviour is about 5 or six years old. I asked thiago
> > >  about it some weeks before. You only see it now because it only
> > > appears in qt developer builds which we only started to use when
> > > switching to the qt git repo.
> > >
> > > So i think the ... it worked with qt <4.6 may be unlikely. Are you
> > > really sure?
> >
> > Sure, otherwise for example the k3bsetup and some other polkit-qt
> >  applications wouldn't work as expected with qt 4.5.
>
> The warning is correct.
>
> Overriding signals is an extremely bad idea. Since signals aren't virtual,
>  the code in the base class that emits the signal will emit the lower-ID
>  signal. However, the connect() call searches from the most derived class
>  towards QObject -- that means you connect to the most-derived class's
>  signal.
>
> In other words, the signal is emitted, but it's never caught.
>
> DO NOT override signals.
Could be good to have this information somewhere. But being good or bad, the
problem is that some applications working with Qt 4.5 won't work with Qt 4.6
(even if I still would like to test using a non developer build, if somebody
could point me in the right direction).

I can come up with a patch for partitionmanager and that wouldn't hurt since
it's an application, whereas polkit-qt is a library and quite a more complex
matter, since I would have to add another (different) signal or work around it
somehow, and to avoid having people rewrite parts of their application I'd
surely favor for the second, which would anyway bring up problems.

>
> Also, Michael is right: that warning is extremely old. It was added for Qt
> 4.0.

The problem is that is showing (at least for me) only using 4.6, but could be
because of developer builds

>

--
-------------------

Dario Freddi
KDE Developer
GPG Key Signature: 511A9A3B


signature.asc (205 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Bugzilla from thiago@kde.org :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Em Sábado 7. Novembro 2009, às 19.35.44, Dario Freddi escreveu:

> On Saturday 07 November 2009 19:19:22 Thiago Macieira wrote:
> > Em Sábado 7. Novembro 2009, às 18.26.48, Dario Freddi escreveu:
> > > On Saturday 07 November 2009 18:19:44 you wrote:
> > > > That warning and behaviour is about 5 or six years old. I asked
> > > > thiago about it some weeks before. You only see it now because it
> > > > only appears in qt developer builds which we only started to use when
> > > > switching to the qt git repo.
> > > >
> > > > So i think the ... it worked with qt <4.6 may be unlikely. Are you
> > > > really sure?
> > >
> > > Sure, otherwise for example the k3bsetup and some other polkit-qt
> > >  applications wouldn't work as expected with qt 4.5.
> >
> > The warning is correct.
> >
> > Overriding signals is an extremely bad idea. Since signals aren't
> > virtual, the code in the base class that emits the signal will emit the
> > lower-ID signal. However, the connect() call searches from the most
> > derived class towards QObject -- that means you connect to the
> > most-derived class's signal.
> >
> > In other words, the signal is emitted, but it's never caught.
> >
> > DO NOT override signals.
>
> Could be good to have this information somewhere.
That's what the warning is there for.

> But being good or bad,
>  the problem is that some applications working with Qt 4.5 won't work with
>  Qt 4.6 (even if I still would like to test using a non developer build, if
>  somebody could point me in the right direction).

If it's a behaviour regression, please report it. A testcase would do wonders
to speed up its fixing.

If it's really a behaviour regression in dealing with signal-slot connections,
this needs to be fixed *now* before 4.6.0-RC1.

> I can come up with a patch for partitionmanager and that wouldn't hurt
>  since it's an application, whereas polkit-qt is a library and quite a more
>  complex matter, since I would have to add another (different) signal or
>  work around it somehow, and to avoid having people rewrite parts of their
>  application I'd surely favor for the second, which would anyway bring up
>  problems.
>
> > Also, Michael is right: that warning is extremely old. It was added for
> > Qt 4.0.
>
> The problem is that is showing (at least for me) only using 4.6, but could
>  be because of developer builds
Could be too that the test that the warning depended on didn't work before.
Olivier optimised the area around the warning and maybe corrected the check.

He maybe introduced the regression too.

Like I said, we need a testcase.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Senior Product Manager - Nokia, Qt Development Frameworks
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358


signature.asc (197 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Dario Freddi-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Saturday 07 November 2009 19:44:13 Thiago Macieira wrote:
> Like I said, we need a testcase.

I will post it on the tracker in a pair of days

>

--
-------------------

Dario Freddi
KDE Developer
GPG Key Signature: 511A9A3B


signature.asc (205 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Olivier Goffart :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Le Saturday 07 November 2009, Thiago Macieira a écrit :

> Em Sábado 7. Novembro 2009, às 19.35.44, Dario Freddi escreveu:
> > On Saturday 07 November 2009 19:19:22 Thiago Macieira wrote:
> > > Em Sábado 7. Novembro 2009, às 18.26.48, Dario Freddi escreveu:
> > > > On Saturday 07 November 2009 18:19:44 you wrote:
> > > > > That warning and behaviour is about 5 or six years old. I asked
> > > > > thiago about it some weeks before. You only see it now because it
> > > > > only appears in qt developer builds which we only started to use
> > > > > when switching to the qt git repo.
> > > > >
> > > > > So i think the ... it worked with qt <4.6 may be unlikely. Are you
> > > > > really sure?
> > > >
> > > > Sure, otherwise for example the k3bsetup and some other polkit-qt
> > > >  applications wouldn't work as expected with qt 4.5.
> > >
> > > The warning is correct.
> > >
> > > Overriding signals is an extremely bad idea. Since signals aren't
> > > virtual, the code in the base class that emits the signal will emit the
> > > lower-ID signal. However, the connect() call searches from the most
> > > derived class towards QObject -- that means you connect to the
> > > most-derived class's signal.
> > >
> > > In other words, the signal is emitted, but it's never caught.
> > >
> > > DO NOT override signals.
> >
> > Could be good to have this information somewhere.
>
> That's what the warning is there for.
>
> > But being good or bad,
> >  the problem is that some applications working with Qt 4.5 won't work
> > with Qt 4.6 (even if I still would like to test using a non developer
> > build, if somebody could point me in the right direction).
>
> If it's a behaviour regression, please report it. A testcase would do
>  wonders to speed up its fixing.
>
> If it's really a behaviour regression in dealing with signal-slot
>  connections, this needs to be fixed *now* before 4.6.0-RC1.
>
> > I can come up with a patch for partitionmanager and that wouldn't hurt
> >  since it's an application, whereas polkit-qt is a library and quite a
> > more complex matter, since I would have to add another (different) signal
> > or work around it somehow, and to avoid having people rewrite parts of
> > their application I'd surely favor for the second, which would anyway
> > bring up problems.
> >
> > > Also, Michael is right: that warning is extremely old. It was added for
> > > Qt 4.0.
> >
> > The problem is that is showing (at least for me) only using 4.6, but
> > could be because of developer builds
>
> Could be too that the test that the warning depended on didn't work before.
> Olivier optimised the area around the warning and maybe corrected the
>  check.
>
> He maybe introduced the regression too.
>
> Like I said, we need a testcase.
>

The thing is that the warning was shown in Qt 4.5 if the signal conflict with
one signal in the class dirrectly under the hierarchy.

(It has been fixed in 919b7230.  It is a bit difficult to read but one can see
that in QMetaObject::indexOfSignal, before the patch, it will do
m = m->d.superdata;  before exiting the while loop, and then again
m->d.superdata->indexOfMethod(signal);  
But now the while loop is breaked before.)

So the warning may appears more often.

But the signal was already overriding the QAction::activated meaning that
QAction::activated cannot be emitted anymore. which is quite bad.






Re: Qt 4.6 behaves differently when "overloading" signals

by Dario Freddi-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sunday 08 November 2009 13:50:54 Olivier Goffart wrote:

> Le Saturday 07 November 2009, Thiago Macieira a écrit :
> > Em Sábado 7. Novembro 2009, às 19.35.44, Dario Freddi escreveu:
> > > On Saturday 07 November 2009 19:19:22 Thiago Macieira wrote:
> > > > Em Sábado 7. Novembro 2009, às 18.26.48, Dario Freddi escreveu:
> > > > > On Saturday 07 November 2009 18:19:44 you wrote:
> > > > > > That warning and behaviour is about 5 or six years old. I asked
> > > > > > thiago about it some weeks before. You only see it now because it
> > > > > > only appears in qt developer builds which we only started to use
> > > > > > when switching to the qt git repo.
> > > > > >
> > > > > > So i think the ... it worked with qt <4.6 may be unlikely. Are
> > > > > > you really sure?
> > > > >
> > > > > Sure, otherwise for example the k3bsetup and some other polkit-qt
> > > > >  applications wouldn't work as expected with qt 4.5.
> > > >
> > > > The warning is correct.
> > > >
> > > > Overriding signals is an extremely bad idea. Since signals aren't
> > > > virtual, the code in the base class that emits the signal will emit
> > > > the lower-ID signal. However, the connect() call searches from the
> > > > most derived class towards QObject -- that means you connect to the
> > > > most-derived class's signal.
> > > >
> > > > In other words, the signal is emitted, but it's never caught.
> > > >
> > > > DO NOT override signals.
> > >
> > > Could be good to have this information somewhere.
> >
> > That's what the warning is there for.
> >
> > > But being good or bad,
> > >  the problem is that some applications working with Qt 4.5 won't work
> > > with Qt 4.6 (even if I still would like to test using a non developer
> > > build, if somebody could point me in the right direction).
> >
> > If it's a behaviour regression, please report it. A testcase would do
> >  wonders to speed up its fixing.
> >
> > If it's really a behaviour regression in dealing with signal-slot
> >  connections, this needs to be fixed *now* before 4.6.0-RC1.
> >
> > > I can come up with a patch for partitionmanager and that wouldn't hurt
> > >  since it's an application, whereas polkit-qt is a library and quite a
> > > more complex matter, since I would have to add another (different)
> > > signal or work around it somehow, and to avoid having people rewrite
> > > parts of their application I'd surely favor for the second, which would
> > > anyway bring up problems.
> > >
> > > > Also, Michael is right: that warning is extremely old. It was added
> > > > for Qt 4.0.
> > >
> > > The problem is that is showing (at least for me) only using 4.6, but
> > > could be because of developer builds
> >
> > Could be too that the test that the warning depended on didn't work
> > before. Olivier optimised the area around the warning and maybe corrected
> > the check.
> >
> > He maybe introduced the regression too.
> >
> > Like I said, we need a testcase.
After the last pull on kde-qt my testcase works, so it was probably an old
build's fault

>
> The thing is that the warning was shown in Qt 4.5 if the signal conflict
>  with one signal in the class dirrectly under the hierarchy.
>
> (It has been fixed in 919b7230.  It is a bit difficult to read but one can
>  see that in QMetaObject::indexOfSignal, before the patch, it will do
> m = m->d.superdata;  before exiting the while loop, and then again
> m->d.superdata->indexOfMethod(signal);
> But now the while loop is breaked before.)
>
> So the warning may appears more often.
>
> But the signal was already overriding the QAction::activated meaning that
> QAction::activated cannot be emitted anymore. which is quite bad.
>
--
-------------------

Dario Freddi
KDE Developer
GPG Key Signature: 511A9A3B


signature.asc (205 bytes) Download Attachment

Re: Qt 4.6 behaves differently when "overloading" signals

by Bugzilla from kossebau@kde.org :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Samedi, le 7 novembre 2009, à 19:19, Thiago Macieira a écrit:

> Em Sábado 7. Novembro 2009, às 18.26.48, Dario Freddi escreveu:
> > On Saturday 07 November 2009 18:19:44 you wrote:
> > > That warning and behaviour is about 5 or six years old. I asked thiago
> > >  about it some weeks before. You only see it now because it only
> > > appears in qt developer builds which we only started to use when
> > > switching to the qt git repo.
> > >
> > > So i think the ... it worked with qt <4.6 may be unlikely. Are you
> > > really sure?
> >
> > Sure, otherwise for example the k3bsetup and some other polkit-qt
> >  applications wouldn't work as expected with qt 4.5.
>
> The warning is correct.
>
> Overriding signals is an extremely bad idea. Since signals aren't virtual,
> the code in the base class that emits the signal will emit the lower-ID
> signal. However, the connect() call searches from the most derived class
> towards QObject -- that means you connect to the most-derived class's
> signal.
>
> In other words, the signal is emitted, but it's never caught.
>
> DO NOT override signals.

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;
so the compiler will enforce a developer to also define this signal in the
class using implementing the interface.
        Q_SIGNALS:
        virtual somethingChanged();
Since Qt 4.6 (IIRC) moc complains about this
        Warning: Signals cannot be declared virtual
but it can be fooled by just leaving out the redundant "virtual" keyword in
the class declaration, keeping the signal method still virtual.

Now it would be great if I could add something like
        Q_SIGNAL_NEEDED( somethingChanged() )
or similar to the abstract interface, which moc will read* and, instead of the
compiler, check if the signal is declared in the class implementing this
interface and complain/stop if not. So I (and others) can get rid of this
hack :)

*Does moc also parse the included headers?

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

Re: Qt 4.6 behaves differently when "overloading" signals

by Olivier Goffart :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

> so the compiler will enforce a developer to also define this signal in the
> class using implementing the interface.
> Q_SIGNALS:
> virtual somethingChanged();
> Since Qt 4.6 (IIRC) moc complains about this
> Warning: Signals cannot be declared virtual
> but it can be fooled by just leaving out the redundant "virtual" keyword in
> the class declaration, keeping the signal method still virtual.

The warning was actually an error in 4.5, but the error was not thrown often
because of a bug in moc (fixed in e43eae35)

> Now it would be great if I could add something like
> Q_SIGNAL_NEEDED( somethingChanged() )
> or similar to the abstract interface, which moc will read* and, instead of
>  the compiler, check if the signal is declared in the class implementing
>  this interface and complain/stop if not. So I (and others) can get rid of
>  this hack :)

again, it is fine to have the signal in the base class.  Signal are protected,
derived class can emit it.
 
> *Does moc also parse the included headers?

Yes, provided that you give the include paths to moc (option -I)


Re: Qt 4.6 behaves differently when "overloading" signals

by Bugzilla from kossebau@kde.org :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Le Sonntag, 8. November 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:
    Data data() const = 0;
    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 )
  Q_SIGNALS:
    virtual void dataChanged( const Data& data );
}

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

    Q_ABSTRACT_SIGNAL(dataChanged( const Data& data ))
}

class Class : public QObject, public DataContainer
{
  Q_OBJECT
  Q_INTERFACES( DataContainer )
  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

Parent Message unknown Re: Qt 4.6 behaves differently when "overloading" signals

by Bugzilla from kossebau@kde.org :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

Re: Qt 4.6 behaves differently when "overloading" signals

by Olivier Goffart :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Le Sunday 08 November 2009, Friedrich W. H. Kossebau a écrit :
> Pardon me, accidently sent before completing:

Is there a difference between the two mails?
 

> 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.

Ok, now it makes sens to me.


[...]

> 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 );
> }

You can omit the keyword 'virtual' there, and then moc will not output
warnings.

The only problem is that someone could forget the Q_SIGNALS keyword in the
reimplementation.  Then there will be a warning at runtime saying "signal not
found"

> 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.

This is indeed a good idea. But it would add very little for the changes it
requires.