Widget signal chaining
-
Hi guys,
I could really need some design advices :)
Assume
A
is aQWidget
-based class, which has a function to do something in constant time.
I want it to be possible to "chain" these widgets, so that one widget will notify one or more possible successors, where this function is also called then and they will propagate this further on.
At first, I thought, that would be no problem at all, since I can simply connect them via signals and that's it, but then some doubts came up.My idea is that something like this is possible,
(A_4
andA_5
start afterA_3
is done)A a1, a2, a3, a4, a5; a1.next(a2); // A_1 // | a2.next(a3); // A_2 // | a3.next(a4); // A_3 // / \ a3.next(a5); // A_4 A_5
as well as something like this (and any other combination or chain)
(AfterA_1
,A_2
, ....A_n
are done,A_3
will start)A a1, a2, a3, a4, a5; a1.next(a3); // A_1 A_2 // \ / a2.next(a3); // A_3 // / \ a3.next(a4); // A_4 A_5 a3.next(a5);
Every widget should be able to be removed at any time without breaking the whole thing and leaking memory.
Of course I want to avoid dangling pointers and invalid connections, when the receiver got removed/unchained (or a whole widget in this chain got deleted).Would it be better for every node in this chain to know its predecessor(s), instead of their next?! Or should I build something like a double-linked list, where previous and next nodes are known by every widget?! How to handle something like this?
What's the best and cleanest way to do something like this?
Maybe I am missing the obvious, but it feels like using signals only isn't the best approach in this case.
Found this topic, it's similar but not quite what I think I can use.
Any help and ideas for improvement are appreciated :)
Thanks in advance :)
-
@Pl45m4
Hi,
If I understand you well, from your description,
each widged needs to maintain a list of all their parents and another list of all their children.You can create a abstract base class with a pure virtual method like:
void done(parent)=0;When all parents have done for a widget, starts himself and when finished, calls done() for all the children.
-
@mpergand said in Widget signal chaining:
each widged needs to maintain a list of all their parents and another list of all their children.
From my side there is no need to do that, but this might be one solution.
Was looking for the "cleanest" way, if there is any.
I'm not sure about putting a list of pointers to all other widgets in every widget. Deleting a widget will become more difficult then.All I'm planing to do is to notify (via signal or something else) the next widget in the chain to start its task.
Currently I'm not even sure if it's better to work with widgetx
and let it notify widgetx+1
or the other way round ("previous" vs. "next" approach, or both) -
@Pl45m4 said in Widget signal chaining:
I'm not sure about putting a list of pointers to all other widgets in every widget. Deleting a widget will become more difficult then.
You can use QObject::destroyed signal.
Or inform any children when a parent is deleted yourself.
Since you use subclasses of widgets, signals/slots are superflous.
You can create any methods you want to manage the states of your widgets. -
@jeremy_k
Signals and Slots are made to interact to the outside, for ex a button with the mainWindow.
If you look at QWidget, it doesn't use signals when an internal state has changed, ex: focus, close, show etc, it use events.
Here, there is no benefice to us signals, it's heavy and complicated. -
@mpergand said in Widget signal chaining:
@jeremy_k
Signals and Slots are made to interact to the outside, for ex a button with the mainWindow.
If you look at QWidget, it doesn't use signals when an internal state has changed, ex: focus, close, show etc, it use events.
Here, there is no benefice to us signals, it's heavy and complicated.devhost:qtbase/$ git grep connect src/widgets/
[...]A quick glance will show that there are lots of signal and slot uses within complex widgets.
-
First of all, thanks to all of you for your comments and suggestions :)
Coming back to this, I decided to make something like
QButtonGroup
containing my widgets, to manage the chaining and notifications. I want to keep this private, so that it will be not a part of my widget's "API". Therefore I created a class similar toQButtonGroup
's code and added signals and functions.Since I have some experience in Qt in general but almost none in developing Qt plugins (QtDesigner plugins / widget "libraries") I'm wondering if it can/should be done like this?
Would it be better to subclassQButtonGroup
(my widgets areQAbstractButton
subclasses)? -
Solved.
Made some kind of manager class to organize the widget chain / hierarchy. So not the widgets know about the next or prev actions, but only the managing class knows. The widgets just have to know when it's their turn (notification comes via call or signal from controlling obj).
The tree / structure is also built in the controlling obj -
-
Not read the whole thread but maybe this is of interest: https://wiki.qt.io/TaskTree