Why are there no QWidget signals?
-
Hi there. Sorry for the n00b questions, but I can't find any info on this that would be satisfactory. The only thing I found was "this post":http://www.gamedev.net/topic/528404-qt-and-resize-events/ where this guy has exact same problem as I do.
Anyway, I want to process widget resize event. I looked around Qt documentation and stumbled upon signals, slots and events.
Naturally, the signals & slots seem way easier since there's no need to override any classes, but QWidget has no signals whatsoever! Since I'm instantiating the form from a .ui file I can't really see how I could override the placeholder QWidget that I keep on the form. I also can't use sizers because that would defeat my purpose with this widget and its children which is free positioning and animation of the children.So the questions:
- Why is this seemingly easy functionality not already in QWidget?
- How can I process resize event of either my MainWindow or the placeholder QWidget and be sure that size reported for the QWidget is correct at the time of processing?
Using version 4.7.4
-
We have layouts for that. "Layout management":http://doc.qt.nokia.com/latest/layout.html .Go through this. There are couple of examples too. And you do know of the Qdesigner tool.
-
I'm designing the app in Qt Creator which is pretty much the same as designer. And yes, sorry about the wording - can't use layouts because that would defeat the purpose of free placement and animation of children.
-
Sounds like you need The "graphics view framework":http://doc.qt.nokia.com/4.7/graphicsview.html for free placement of children or even "QML":http://doc.qt.nokia.com/4.7/qdeclarativeexamples.html for the animation.
Depends on what you want to achieve exactly.
-
You can create a subclass of QWidget and then use in Creator (or designer) by using Widget Promotion.
See the "Promote to..." option in the context menu of your placeholder QWidget.
-
If you just want to listen to events, you can install an eventfilter.
-
Wow, thanks. Seems both Promotion and event filtering answer my second question to great satisfaction.
@eddy: I was originally considering QGraphicsView + Scene, but have later decided that QLabel + QPropertyAnimation provide everything I need. I would revert back to QGraphics if the above two suggestions didn't work for me already :)
How about question 1? Why is there no signalling in QWidget? One would think that since the documentation promotes this aggressively it would at least be implemented throughly in the framework?
-
Signals and slots are not free. Furthermore, these are things that in reality don't all that often need listeners outside of the object itself. That means that just the event works well enough for almost all cases. It is easy enough to add a signal if it is needed for some special case after all, either via subclassing or via event filtering. Signals&slots and events are not the same thing, they cater to different scenarios.
-
By the way, if Qt would have a signal for each possibility where someone could need one, you would have so many of them, you would never know which to use. And, as Andre said, it's not for free. It needs bookkeeping (for the connections) calls to the corresponding meta objects for signal invoking, etc.
-
Thanks everyone for the explanations.
@Gerolf: Your argument about too many signals is pretty weak IMO: Currently those exact numbers are covered by events. How would signal equivalents be more confusing to the user of the library? If anything they would simplify the model because only one approach would be advertized in the documentation.
@Andre & Gerolf: I understand what you are trying to communicate. I also see how signals work and that calls to them are not free, especially with already established events being fast as they are.
But I still feel if a framework is provided, it should be implemented throughly in a library or not at all. What good does it do me to learn signals when the first usage-case -which is very common BTW - I come by is not supported? I believe at least I should have a configuration option that would compile signals in / out of the library - that way I could decide if the performance penalty is worth my learning curve steepness or implementation time.
But I also understand that the whole concept of signals may have been added on at a later time and that transition to them is slow, especially due to performance issues.
-
I will try to reverse the question:
Since I'm planning to use Qt for a while now, and since I'm new to Qt altogether, I seem to have two options right now:- Accept the current modus operandi and do stuff as suggested
- I could take the time and implement signalling to QWidget and its derivatives. Perhaps I could even go as far as to even fix the documentation while at it
Would option 2 be appreciated / allowed in the Qt community?
-
While contributions from the community are very welcome in Qt, I doubt that a patch that would basically add a signal for every event that comes into a widget would be accepted.
I am still not convinced about the usecase, and how frequently you really would use it. As a comment in the thread you mentioned in your first post also states: the way to specialize object in C++ is by subclassing. That goes for Qt as well.
If you really would like to have a solution that you can atttach to any widget, I suggest you write a very simple class that sends out a signal on the events you specify for the object you install it on. Should be quite trivial. Something like:
@
class Event2Signal: public QObject {
Q_OBJECT
public:
Event2Signal(QObject* watched, QObject* parent = 0);
void addEvent(int eventType);virtual bool eventFilter ( QObject * watched, QEvent * event );
signals:
eventCought(QEvent* e);private:
QSet<int> m_interestingEvents;
}
@The implementation would be trivial: simply make the constructor install an eventfilter on the watched object (and uninstall it again from the destructor, of course). Then, in your eventFilter() implementation, you check if the event type is a type you are interested in (is in the m_interestingEvents set that you fill using addEvent()). If so, you emit the signal with the event attached.
This is very basic of course, and can be made much more sofisticated. You can of course specialize to supply more usable signals for specific events, like the resize event wich could directly contain the size instead of a pointer to the event.
This way, you can selectively create signals only for the widgets that really need them in a way that is reusable and doesn't need any patching of Qt.
-
I suppose this suggestion is a lot easier than messing around core Qt code and also achieves the desired result :)
If I look around, I may even find ready-made code for this. -
[quote author="velis" date="1317285284"]Thanks everyone for the explanations.
@Gerolf: Your argument about too many signals is pretty weak IMO: Currently those exact numbers are covered by events. How would signal equivalents be more confusing to the user of the library? If anything they would simplify the model because only one approach would be advertized in the documentation.
But I still feel if a framework is provided, it should be implemented throughly in a library or not at all. What good does it do me to learn signals when the first usage-case -which is very common BTW - I come by is not supported? I believe at least I should have a configuration option that would compile signals in / out of the library - that way I could decide if the performance penalty is worth my learning curve steepness or implementation time.
But I also understand that the whole concept of signals may have been added on at a later time and that transition to them is slow, especially due to performance issues.
[/quote]Your first use case stumbled over it. I use Qt now since nearly 10 years and never needed signals like resized() etc.
Events are something totally different. Events are meant for usage inside the class, the event was sent to. Like Resize, focusIn / focusOut, etc, as the widget might have to repaint itself, calculate some new borders etc. Whether external objects are interested in such things is something totally different.
Especially, signals have no defined call order. And no predefined target. A focusIn event must reach the target widget, and first of all no one else. If this specific widget thinks, someone else might also be interested in that, it can define and emit a signal.
But if all events would be signals, how to guarantee that only one specific widget gets the signal? Who would do the mapping and the connecting?
-
Yes, I am sorry. I misinterpreted the documentation about signals and events. The fact is that I was looking for QWidget resize processing and stumbled on signals while looking. I can easily see how I thought signals to be the perfect solution for me despite the very second paragraph talking about inter-object communication and callbacks :P
Reading the same documentation after your explanations really isn't the same experience any more :DAnyway, thanks for all the help.