Signals for QWidget's events.
-
Hi,
Ever since I started using Qt I've wondered why there aren't any signals in QWidget to notify relevant QEvents?
For example a clicked() signal to notify that the user clicked inside this widget.
Or focusIn() focusOut() SIGNALs, or maybe focus(bool) to notify that the QWidget just got focus. (Maybe you want to show/hide/resize another widget(s) when that happens)
Isn't that usefull information to other QObjects? The kind of information Signals are meant to notify... ? -
[quote]
Isn’t that usefull information to other QObjects? The kind of information Signals are meant to notify… ?[/quote]No, it's not. A QObject is a "self-contained component" and you're not supposed to mess with events received by a certain component.
Apart from this:
- Event handling is much more lightweight than signal emission
- Signals and events are different beasts
bq. An event in Qt is an object which represents something interesting that happened; the main difference between an event and a signal is that events are targeted to a specific object in our application (which decides what to do with that event), while signals are emitted “in the wild”.
( from my article http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects )
- The same "logic" signal can be achieved by more than one way (for instance: a QPushButton clicked() gets emitted when the user clicks, or if the user presses the spacebar)
- OTOH the same event can trigger different signals (a mouseclick on a QTreeView can emit a bunch of different signals depending on where the user clicked)
-
For more than 99% of the applications and widgets this would just be unnecessary overhead.
If you are interested in any event on an object, install an "event filter":http://doc.qt.nokia.com/stable/qobject.html#eventFilter - you get everything then.
-
[quote author="peppe" date="1295324207"][quote]
Isn’t that usefull information to other QObjects? The kind of information Signals are meant to notify… ?[/quote]No, it's not. A QObject is a "self-contained component" and you're not supposed to mess with events received by a certain component.
[/quote]
Emm.. you wouldn't be able to mess with the event using a signal. This would be just a notification. Very different to event handling.[quote author="peppe" date="1295324207"]
Apart from this:- Event handling is much more lightweight than signal emission
- Signals and events are different beasts
bq. An event in Qt is an object which represents something interesting that happened; the main difference between an event and a signal is that events are targeted to a specific object in our application (which decides what to do with that event), while signals are emitted “in the wild”.
( from my article http://developer.qt.nokia.com/wiki/ThreadsEventsQObjects )
- The same "logic" signal can be achieved by more than one way (for instance: a QPushButton clicked() gets emitted when the user clicks, or if the user presses the spacebar)
- OTOH the same event can trigger different signals (a mouseclick on a QTreeView can emit a bunch of different signals depending on where the user clicked)
[/quote]
Yes, I know QEvents are different to signals. I didn't mean there shouldn't be QEvents or that they should be replaced by signals. I meant that in some cases it would be usefull to have signals that notify specific events, like the ones I've mentioned in the first post.
[quote author="Volker" date="1295355461"]For more than 99% of the applications and widgets this would just be unnecessary overhead.
If you are interested in any event on an object, install an "event filter":http://doc.qt.nokia.com/stable/qobject.html#eventFilter - you get everything then.[/quote]
I think an event filter is meant to be used when you want to handle the event. Even if you choose not to modify the filtered QEvents, it is a very different objects relation, a very close relation. On the other hand, signals are meant to notify something in a convenient and easy way.Maybe I belong to that 1% that would find this usefull. I don't know. But I don't think it would be unnecessary overhead. Providing a signal isn't that much resource consuming.
-
[quote author="ivan.todorovich" date="1295376383"]
I think an event filter is meant to be used when you want to handle the event. Even if you choose not to modify the filtered QEvents, it is a very different objects relation, a very close relation. On the other hand, signals are meant to notify something in a convenient and easy way.Maybe I belong to that 1% that would find this usefull. I don't know. But I don't think it would be unnecessary overhead. Providing a signal isn't that much resource consuming.[/quote]
If you want to emit a signal, you do handle it :-)
It's not hard to define the signal you need yourself, catch the event in the event handler or event filter and emit the signal.
That way you can add whatever you need. Qt is a general purpose library, it cannot provide everything someone finds useful. But in most cases it provides some means to add the desired functionality. If, for example, they added some signals for this or that event, there would always be someone whose favorite signal-for-event is missing and want's it to be added. This way Qt would eventually emit a signal for every event...
It's always a matter of decision. Make the common cases easy and don't make the less common ones impossible.
-
[quote author="Volker" date="1295377763"]
[quote author="ivan.todorovich" date="1295376383"]
I think an event filter is meant to be used when you want to handle the event. Even if you choose not to modify the filtered QEvents, it is a very different objects relation, a very close relation. On the other hand, signals are meant to notify something in a convenient and easy way.Maybe I belong to that 1% that would find this usefull. I don't know. But I don't think it would be unnecessary overhead. Providing a signal isn't that much resource consuming.[/quote]
If you want to emit a signal, you do handle it :-)
[/quote]
The events are already being handled internally by QWidget. The only extra 'overhead' is the one that comes with this line of code per signal.
@emit whatEver();@[quote author="Volker" date="1295377763"]
It's not hard to define the signal you need yourself, catch the event in the event handler or event filter and emit the signal.That way you can add whatever you need. Qt is a general purpose library, it cannot provide everything someone finds useful. But in most cases it provides some means to add the desired functionality. If, for example, they added some signals for this or that event, there would always be someone whose favorite signal-for-event is missing and want's it to be added. This way Qt would eventually emit a signal for every event...
It's always a matter of decision. Make the common cases easy and don't make the less common ones impossible. [/quote]
As far as I know Qt is in active development. That means they are always trying to improve the library with new usefull functionality.Qt uses Signals and Slots as its default notification method to 'bind' two objects. Signals are basically notifications of events (not QEvents, just events in the literal sense of the word.) Notifications that allows other objects to act in consequence of something that happened internally.
Most of the gui languages out there allows you to bind actions on a clicked or focused event. Those are basics to every widget. Most languages support this kind of binding without having to subclass anything, that should mean something, like it isn't wild to have that kind of signals implemented.. (?)
Personally, I don't think I belong to the 1%. It's like you said, "Make the common cases easy and don't make the less common ones impossible."
It's just that I think it would be easy to make this case one of the easy.
-
Allow me to quote myself in order to explain.
[quote author="ivan.todorovich" date="1295379880"]
...Personally, I don't think I belong to the 1%...
[/quote]The links below are the top search results by google when searching for "focused signal qt".
http://www.qtforum.org/article/2532/how-can-i-emit-a-signal-when-a-lineedit-is-focused.html
http://lists.trolltech.com/qt-interest/2007-01/thread00299-0.html
http://www.qtcentre.org/threads/30118-QWidget-(Qt-Popup)-Signal-when-close-or-lost-focus
http://stackoverflow.com/questions/2194158/qpushbutton-focusin-generates-which-signal
http://stackoverflow.com/questions/321656/when-a-qt-widget-gets-focus -
To quote your first post:
[quote author="ivan.todorovich" date="1295315608"]Hi,
Ever since I started using Qt I've wondered why there aren't any signals in QWidget to notify relevant QEvents?[/quote]
What is relevant? For you it might be if the widget was clicked into, for the guy around the corner it is focus in, for his co-worker it's focus out and the crowd two cubicles further want it for some fancy event which only happens once in a while and only on an S/390 powered smart phone at full moon... Where to draw the line at?
BTW: With subclassing/reimplementing the event handler or installing an event filter you have the events when they happen. With signals you can react only some time later. It might be too late then to do some fancy stuff.
-
[quote author="Volker" date="1295387747"]To quote your first post:
[quote author="ivan.todorovich" date="1295315608"]Hi,
Ever since I started using Qt I've wondered why there aren't any signals in QWidget to notify relevant QEvents?[/quote]
What is relevant? For you it might be if the widget was clicked into, for the guy around the corner it is focus in, for his co-worker it's focus out and the crowd two cubicles further want it for some fancy event which only happens once in a while and only on an S/390 powered smart phone at full moon... Where to draw the line at?[/quote]
Clearly, signals to notify when a QWidgets gets or loses focus "is relevant to many people":http://www.google.com/search?q=focus+signal+qt , not just me.
Regarding the clicked signal it isn't that easy to get search results because of the already existing clicked() signal of QPushButton and other QWidgets. Those two I'd say are the most important events that should be notified with signals. Those two are particulary relevant to me.Now if you look at other GUI Languages, I'd say the majority allows you to bind to any event. Note that it isn't a good comparison since Qt's Signals and Slots / Events handling is a very unique approach: In Qt, Signals are used to comunicate to other objects while QEvents are supposed to be internal to the object -- Yes, I know you can use an event filter! But the point is, if you want to notify something (and get the control) the prefered way in Qt is using a Signal, while in other languages this is integrated in the event system with functionality similar to the auto slot naming in Qt.
In summary, most of the gui programming languages have convenient ways to get the control after something happened (including events).
Qt also have convenient ways to do this, with Signals and Slots! but it doesn't notify of events.I can understand that this functionality isn't particulary relevant to you, but you can't ignore the fact that there are people who would find this usefull.
What I can't understand is why would you not want this. You claim that it would add unnecessary overhead, but if you think about it, it doesn't.[quote author="Volker" date="1295387747"]BTW: With subclassing/reimplementing the event handler or installing an event filter you have the events when they happen. With signals you can react only some time later. It might be too late then to do some fancy stuff.[/quote]
Ok, then why do we have signals and slots if we can use custom events.. ? (rethorical question, please don't answer that.) -
Signal / slot is always overhead regarding time, I think that is for sure. If you add a signal for each event type, and emit it always, think of slower systems than current PCs / MACs. What to do on embedded systems, where performance is a real matter? And keep in mind, how many events there might be.
I agree, it might be helpful for some (perhaps also many) people, but for some (or many) others, it might be a problem, perhaps regarding timing etc. So which way to go? I think the current way is really good and works. And if you need those signals, create simple custom widgets, directly derive which have those signals, it's not complicated.
-
[quote author="Gerolf" date="1295423554"]Signal / slot is always overhead regarding time, I think that is for sure. If you add a signal for each event type, and emit it always, think of slower systems than current PCs / MACs. What to do on embedded systems, where performance is a real matter? And keep in mind, how many events there might be. [/quote]
Well, maybe we should look at the actual numbers and see if its really an overhead. Because a simple emit signal(), if no objects are connected, doesn't really do anything - just checks that there are no connections to that signal and returns.
Also, as explained in some Signals documentation, using a Signal connected to a Slot is about ten times slower than using callbacks but it's still much faster than using a new or delete keyword.Let me quote the "Signals & Slots Documentation":http://doc.trolltech.com/latest/signalsandslots.html
[quote]Compared to callbacks, signals and slots are slightly slower because of the increased flexibility they provide, although the difference for real applications is insignificant. In general, emitting a signal that is connected to some slots, is approximately ten times slower than calling the receivers directly, with non-virtual function calls. This is the overhead required to locate the connection object, to safely iterate over all connections (i.e. checking that subsequent receivers have not been destroyed during the emission), and to marshall any parameters in a generic fashion. While ten non-virtual function calls may sound like a lot, it's much less overhead than any new or delete operation, for example. As soon as you perform a string, vector or list operation that behind the scene requires new or delete, the signals and slots overhead is only responsible for a very small proportion of the complete function call costs.[/quote]Think how many times you use the new keyword. Do you consider that an overhead? Would you sacrifice some usefull functionality for the sake of efficiency?
Also, this numbers refer to a signal that is connected to a slot. A signal that is not connected is practically the same as nothing. Quoting the source code here:
@ if (!sender->d_func()->isSignalConnected(signal_index))
return; // nothing connected to these signals, and no spy@[quote author="Gerolf" date="1295423554"]
I agree, it might be helpful for some (perhaps also many) people, but for some (or many) others, it might be a problem, perhaps regarding timing etc. So which way to go? I think the current way is really good and works. And if you need those signals, create simple custom widgets, directly derive which have those signals, it's not complicated.[/quote]
If so, like many other Qt functionalities, it could provide an option to enable/disable this feature using preprocessor definition like @#define QT_WIDGETS_EMIT_SIGNALS_EVENTS.@ -
[quote author="Volker" date="1295476201"]Open a bug report with the suggestion. We'll see what the Trolls will comment.[/quote]
Will do, but judging the content of this thread http://developer.qt.nokia.com/forums/viewthread/3070/ I think I know their answer :P
-
[quote author="ivan.todorovich" date="1295481380"]
[quote author="Volker" date="1295476201"]Open a bug report with the suggestion. We'll see what the Trolls will comment.[/quote]Will do, but judging the content of this thread http://developer.qt.nokia.com/forums/viewthread/3070/ I think I know their answer :P
[/quote]Not only because of that, I would bet some pennies that they see it similar like some posts in this thread here ;-)
-
[quote]The links below are the top search results by google when searching for “focused signal qt”.[/quote]
The fact that so many people don't understand the difference between a signal and an event[1] doens't mean that Qt must change for them. As of now we have:
Pros:
- Avoid subclassing / installing an event filter to detect something
Cons:
- Cluttered API (all received events - only maybe only the accepted events, so we solve the little problem that events bubble up through widgets hierarchy - are emitted as signals, implying that you add a lot of additional signals in QWidget)
- A signal is emitted after an event was processed, therefore you can't change the behaviour of the event handling itself
- Every event that causes something interesting for the rest of the world is already emitted as a signal, with a proper name and a proper logic ("clicked()" when the a pushbutton is activated, no matter which event caused its activation, mouse press, spacebar, etc.)
- There's an overhead > 0 for each and every event received and handled even if you're not interested at all in those events
-
[quote author="peppe" date="1295527426"][quote]The links below are the top search results by google when searching for “focused signal qt”.[/quote]
The fact that so many people don't understand the difference between a signal and an event[1] doens't mean that Qt must change for them. [/quote]
Signals and QEvents are ment to very different things. Jira Ticket http://bugreports.qt.nokia.com/browse/QTBUG-16732 explains it better.
[quote author="peppe" date="1295527426"]
Pros:- Avoid subclassing / installing an event filter to detect something
[/quote]
Well, yeah, that's the point of almost any improvement.
But also to maintain consistence on notifications. Quote from Signals and Slots documentation: "A signal is emitted when a particular event occurs. " QEvents are events.
[quote author="peppe" date="1295527426"]
Cons:- Cluttered API (all received events - only maybe only the accepted events, so we solve the little problem that events bubble up through widgets hierarchy - are emitted as signals, implying that you add a lot of additional signals in QWidget)[/quote]
I don't understand what you meant between -'s.
But yes, it would add a lot of additional signals in QWidget, that's the whole point.. isn't it?
Btw, there aren't that many. Take a look at the QWidget's documentation, methods under the 'Events' category.
[quote author="peppe" date="1295527426"]
- A signal is emitted after an event was processed, therefore you can't change the behaviour of the event handling itself[/quote]
Yes, that's also the point. You want to notify, not handle the event.
[quote author="peppe" date="1295527426"]
- Every event that causes something interesting for the rest of the world is already emitted as a signal, with a proper name and a proper logic ("clicked()" when the a pushbutton is activated, no matter which event caused its activation, mouse press, spacebar, etc.)[/quote]
That's a cons why? I mean, I disagree on the first part. I think there are events causing something interesting for the rest of the world that aren't emitted. Like I mentioned on the first post, the focus event, for instance.
[quote author="peppe" date="1295527426"]
- There's an overhead > 0 for each and every event received and handled even if you're not interested at all in those events[/quote]
You should read "reply #10":http://developer.qt.nokia.com/forums/viewreply/21008/
- Avoid subclassing / installing an event filter to detect something
-
[quote author="Volker" date="1295355461"]For more than 99% of the applications and widgets this would just be unnecessary overhead.
If you are interested in any event on an object, install an "event filter":http://doc.qt.nokia.com/stable/qobject.html#eventFilter - you get everything then.[/quote]
Could solve my problem fast and easy thanks to this advice. Just wanted to thank you for this post.