Signal/slot approach question
-
Approach advice, please.
-
QMainWindow
has a variety ofQTabWidget
s,QWidget
s on it. I'll call them all "panes". -
One pane is for "Help". Its code just needs a (string) of the name of the "topic" wanted to be displayed there.
-
Multiple other panes have their own context menus, with a Help item. They figure out what the "topic" requested is internally, depending on what was clicked on. Note that in some cases the context menu will be on content items which are created dynamically.
-
The question is, how best to architect for them all to cause the "Help" pane to (be shown and) display the appropriate help topic.
-
I am thinking that the various context menu handlers/slots, having figured what topic string is for the item clicked on, would be best
emit()
-ing a "general" signal, with the topic as a parameter.QMainWindow
can then have a slot for that, which up-fronts the Help pane and tells it topic to display. This seems right, we don't want all the panes to know about the Help pane, do we? -
My problem is what object/class to declare this signal in? So that main window can just go
connect(something, helpSignal, this [or helpPane], helpSlot)
, and panes can goemit something.helpSignal(topic)
. I have a fairly firm rule that I'm not going to include main window in any other module (only the other way round), so I don't think I can declare the signal inQMainWindow
and use it as thesomething
. Would you require some other class/module which must be included into all these panes which require help? Singleton class/instance? Global variable? What?
Because I was bad in a former life, now I have to program in Python/Pyside2 :) But I'll accept any C++ approach, provided I can Python-ise it.
Is this how you would do it?
-
-
If you are doing python you could use pypubsub. It does not require the sender or receiver to know anything about each other. It allows for complete decoupling of code modules except for the import of the pubsub library. It is a great way to provide layer separation in a program.
-
@fcarney
Thank you for the link. I had a quick look. I counted 21 source files. I was expecting to achieve my goal in maybe a dozen lines of code! I will consider, but I'm already using Qt signals/slots e.g. for the context menu clicks, so I had intended to keep within that technology, not learn a new system for this.The point nonetheless is: you seem to be agreeing with an architecture which has the various panes' context menu slots do some packaging of an argument and then emit a "global" signal/publish for a slot/subscriber to pick up and activate the Help pane. As opposed, say, to the context menu slots for Help actually trying to tell the Help pane directly to do something. Right?
-
@VRonin said in Signal/slot approach question:
Sub pane emits a signal to request the help
I wish. Problem: there are an unknown number of distinct "sub panes" which might wish to emit the signal. They currently do not include (Python
import
) any common modules, are not derived from any common class. So where do I define the signal they emit? -
@JonB said in Signal/slot approach question:
we don't want all the panes to know about the Help pane, do we?
...
I have a fairly firm rule that I'm not going to include main window in any other module (only the other way round).... Would you require some other class/module which must be included into all these panes which require help? Singleton class/instance? Global variable? What?
Since the panes need to know about the concept of "asking for help", that means they need to know roughly where to point the user for help, or at the very least they must know how to label their help topics.
My approach would be to have a global registry of supported topics. The other panes could either query the
HelpWidget
directly, or you could refactor out parts of the HelpWidget into aHelpCoordinator
object which contains 2 methods (C++ declaration as follows):QStringList HelpCoordinator::availableTopics()
void HelpCoordinator::callForHelp(const QString& topic)
Problem: there are an unknown number of distinct "sub panes" which might wish to emit the signal.
Each pane can have access to the global HelpCoordinator object and call the
callForHelp()
function. The HelpCoordinator is the one that emits the actual signal. This way, you can easily add/remove panes/entities that trigger help.If you want further clean separation between the HelpWidget and the HelpCoordinator, the HelpCoordinator could act as the authoritative source of all help topics and help content. The HelpWidget could pull content (text and images) from the HelpCoordinator, and the HelpWidget could be responsible for formatting.
-
@JKSH
Hi, yes, thanks.Each pane can have access to the global HelpCoordinator object and call the callForHelp() function. The HelpCoordinator is the one that emits the actual signal.
The important point is, although I had no such before, I have now had to create a common file containing the signal definition/HelpCoordinator, imported into each module which can ask for help. This is an object of which I create one global instance from Python, and that is the object which does the
emit()
and is used as the source in theconnect()
.I have decided that it should be the main window which handles this signal, not the help widget. Although the help widget knows how to access & display the topic, I did not feel it had the right to "up-front" itself (become current widget on a
QTabWidget
), so I have the main window do that and then pass the topic to it for display.I trust this corresponds to what you and the others who have posted here have in mind, and am marking this topic as solved now.
-
@JonB said in Signal/slot approach question:
I trust this corresponds to what you and the others who have posted here have in mind
What you wrote sounds very sensible to me :)