Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Signal/slot vs direct call, and related question
Forum Updated to NodeBB v4.3 + New Features

Signal/slot vs direct call, and related question

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 3 Posters 1.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by
    #1

    Two questions: one stylistic, one implementation.

    GUI application, main window with several widget-windows on it, one of which is a QGraphicsScene (sub-classed). Objects there can be copy/pasted etc.

    1. Style: "To signal/slot or not to signal/slot, that is the question..."

    Inherited code which used QGraphicsScene::keyPressEvent() to capture and act on the Copy etc. key presses. Now that these actions have been added to the main window's menu with shortcuts, that stops working (and I need to deal with menu actions anyway).

    As I move to the action handler in the main window, I simply call directly the desired exported method from the graphics scene sub-class. Is there any good reason why I should instead raise a signal for these actions, and make the methods slots? The main window would still need to see those methods exported so that it can connect() to them, at which point am I just as good with a direct call?

    1. Implementation

    When the code was in QGraphicsScene::keyPressEvent() we knew that the key press was directed at the QGraphicsScene. Now the actions are on main menu we do not, it could be for other windows. What is the "rule" I need to test for (presumably in main window action handler) before I pass on to deal with in QGraphicsScene window? It's not enough to say "is there an item selected on the scene", is it? I presume I'm supposed to test for something like where the focus is, is that it?? Or is it "window is activated" (I don't think so)? Or what?

    Pl45m4P 1 Reply Last reply
    0
    • JonBJ JonB

      Two questions: one stylistic, one implementation.

      GUI application, main window with several widget-windows on it, one of which is a QGraphicsScene (sub-classed). Objects there can be copy/pasted etc.

      1. Style: "To signal/slot or not to signal/slot, that is the question..."

      Inherited code which used QGraphicsScene::keyPressEvent() to capture and act on the Copy etc. key presses. Now that these actions have been added to the main window's menu with shortcuts, that stops working (and I need to deal with menu actions anyway).

      As I move to the action handler in the main window, I simply call directly the desired exported method from the graphics scene sub-class. Is there any good reason why I should instead raise a signal for these actions, and make the methods slots? The main window would still need to see those methods exported so that it can connect() to them, at which point am I just as good with a direct call?

      1. Implementation

      When the code was in QGraphicsScene::keyPressEvent() we knew that the key press was directed at the QGraphicsScene. Now the actions are on main menu we do not, it could be for other windows. What is the "rule" I need to test for (presumably in main window action handler) before I pass on to deal with in QGraphicsScene window? It's not enough to say "is there an item selected on the scene", is it? I presume I'm supposed to test for something like where the focus is, is that it?? Or is it "window is activated" (I don't think so)? Or what?

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by
      #2

      @JonB said in Signal/slot vs direct call, and related question:

      Now that these actions have been added to the main window's menu with shortcuts, that stops working (and I need to deal with menu actions anyway).

      Your keyPressEvents are shortcuts?!
      Why dont you use QShortcut?! You can set a ShortcutContext (click) to trigger your actions even when your scene doesn't have focus. Then you redirect your shortcut to your scene.

      @JonB said in Signal/slot vs direct call, and related question:

      What is the "rule" I need to test for (presumably in main window action handler) before I pass on to deal with in QGraphicsScene window? It's not enough to say "is there an item selected on the scene", is it? I presume I'm supposed to test for something like where the focus is, is that it?? Or is it "window is activated" (I don't think so)? Or what?

      QShortcut handles that for you, if you use WindowShortcut or ApplicationShortcut.
      If your window or widget, where your scene is in, is a child of MainWindow your scene doesnt even need focus (AppShortcut: your shortcut works everywhere, you just need one active window)


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      JonBJ 1 Reply Last reply
      1
      • Pl45m4P Pl45m4

        @JonB said in Signal/slot vs direct call, and related question:

        Now that these actions have been added to the main window's menu with shortcuts, that stops working (and I need to deal with menu actions anyway).

        Your keyPressEvents are shortcuts?!
        Why dont you use QShortcut?! You can set a ShortcutContext (click) to trigger your actions even when your scene doesn't have focus. Then you redirect your shortcut to your scene.

        @JonB said in Signal/slot vs direct call, and related question:

        What is the "rule" I need to test for (presumably in main window action handler) before I pass on to deal with in QGraphicsScene window? It's not enough to say "is there an item selected on the scene", is it? I presume I'm supposed to test for something like where the focus is, is that it?? Or is it "window is activated" (I don't think so)? Or what?

        QShortcut handles that for you, if you use WindowShortcut or ApplicationShortcut.
        If your window or widget, where your scene is in, is a child of MainWindow your scene doesnt even need focus (AppShortcut: your shortcut works everywhere, you just need one active window)

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        @Pl45m4
        Sorry, I don't understand any of this, and don't think it relates to what I am asking.

        I know how shortcuts work and how to use them. I'm (now) using shortcuts, as I explained.

        Inherited code which used QGraphicsScene::keyPressEvent() to capture and act on the Copy etc. key presses. Now that these actions have been added to the main window's menu with shortcuts, that stops working (and I need to deal with menu actions anyway).

        You suggested:

        to trigger your actions even when your scene doesn't have focus.

        That's 100% precisely what I don't want to happen. The whole point is asking how, when an action on a main window menu is triggered by click or shortcut (doesn't matter which), how you decide which widget is supposed to respond to it. I do not want to direct a Copy command to the scene if it does not have focus, do I? That is what I am asking about.

        Pl45m4P 1 Reply Last reply
        0
        • JonBJ JonB

          @Pl45m4
          Sorry, I don't understand any of this, and don't think it relates to what I am asking.

          I know how shortcuts work and how to use them. I'm (now) using shortcuts, as I explained.

          Inherited code which used QGraphicsScene::keyPressEvent() to capture and act on the Copy etc. key presses. Now that these actions have been added to the main window's menu with shortcuts, that stops working (and I need to deal with menu actions anyway).

          You suggested:

          to trigger your actions even when your scene doesn't have focus.

          That's 100% precisely what I don't want to happen. The whole point is asking how, when an action on a main window menu is triggered by click or shortcut (doesn't matter which), how you decide which widget is supposed to respond to it. I do not want to direct a Copy command to the scene if it does not have focus, do I? That is what I am asking about.

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on last edited by
          #4

          @JonB said in Signal/slot vs direct call, and related question:

          how you decide which widget is supposed to respond to it.

          Aren't your QActions in your menu connected to some slots (at destination)?

          It seems, that I really dont understand your problem :-)

          @JonB said in Signal/slot vs direct call, and related question:

          I do not want to direct a Copy command to the scene if it does not have focus, do I? That is what I am asking about.

          Ah, check. You want Qt::WidgetShortcut behavior, but still trigger your QActions from your mainWindow's menuBar (or wherever they are) to copy your GraphicItem?!


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          JonBJ 1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            How are you creating your actions ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • Pl45m4P Pl45m4

              @JonB said in Signal/slot vs direct call, and related question:

              how you decide which widget is supposed to respond to it.

              Aren't your QActions in your menu connected to some slots (at destination)?

              It seems, that I really dont understand your problem :-)

              @JonB said in Signal/slot vs direct call, and related question:

              I do not want to direct a Copy command to the scene if it does not have focus, do I? That is what I am asking about.

              Ah, check. You want Qt::WidgetShortcut behavior, but still trigger your QActions from your mainWindow's menuBar (or wherever they are) to copy your GraphicItem?!

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @Pl45m4 said in Signal/slot vs direct call, and related question:

              Ah, check. You want Qt::WidgetShortcut behavior, but still trigger your QActions from your mainWindow's menuBar (or wherever they are) to copy your GraphicItem?!

              This sounds like it. Yes I think to all. Let me go read about Qt::WidgetShortcut...! :)

              @SGaist
              Menu items/actions/shortcuts are created in Designer, with whatever default. Each item has an action triggered slot in the MainWindow class. I have, say, a Copy menu item/shortcut. The gfx scene does its own copy stuff. I want to know how I am supposed to know, when the action slot is hit, that it should be directed to the gfx widget.

              Since asking this earlier, I now have in Main Window slot something like

              def copy_action(self):
                  if QApplication.focusWidget() is scene_view:
                      scene.do_copy_action()
              

              and that works.

              See also my post today at https://forum.qt.io/topic/80019/find-which-widget-had-focus-when-menu-item-is-clicked/8.

              Pl45m4P 1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Do you have several different widgets which are providing copy behaviour ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                JonBJ 1 Reply Last reply
                0
                • JonBJ JonB

                  @Pl45m4 said in Signal/slot vs direct call, and related question:

                  Ah, check. You want Qt::WidgetShortcut behavior, but still trigger your QActions from your mainWindow's menuBar (or wherever they are) to copy your GraphicItem?!

                  This sounds like it. Yes I think to all. Let me go read about Qt::WidgetShortcut...! :)

                  @SGaist
                  Menu items/actions/shortcuts are created in Designer, with whatever default. Each item has an action triggered slot in the MainWindow class. I have, say, a Copy menu item/shortcut. The gfx scene does its own copy stuff. I want to know how I am supposed to know, when the action slot is hit, that it should be directed to the gfx widget.

                  Since asking this earlier, I now have in Main Window slot something like

                  def copy_action(self):
                      if QApplication.focusWidget() is scene_view:
                          scene.do_copy_action()
                  

                  and that works.

                  See also my post today at https://forum.qt.io/topic/80019/find-which-widget-had-focus-when-menu-item-is-clicked/8.

                  Pl45m4P Offline
                  Pl45m4P Offline
                  Pl45m4
                  wrote on last edited by
                  #8

                  @JonB said in Signal/slot vs direct call, and related question:

                  The gfx scene does its own copy stuff. I want to know how I am supposed to know, when the action slot is hit, that it should be directed to the gfx widget.

                  Do you also have multiple scenes or graphicsViews?
                  Otherwise why dont you connect your copy-action with a slot in your custom scene, determine which item shoud be copied (if this is relevant?!) and then let the scene do its copy work? :)


                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                  ~E. W. Dijkstra

                  1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Do you have several different widgets which are providing copy behaviour ?

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @SGaist said in Signal/slot vs direct call, and related question:

                    Do you have several different widgets which are providing copy behaviour ?

                    As of today, no. But as of tomorrow, quite possibly. There are a couple of other "panes" in the main window. They do not currently copy. But most importantly, if they have "focus" the I do not want the Copy/Paste menu actions/shortcuts to go to the gfx widget.

                    @Pl45m4
                    Only one scene/view. As of today.

                    The scene does do the copy work. The code does not call slots in other modules (nor do I think Designer offers that). For consistency, all action trigger slots are in main window class. I expected to implement a "dispatcher" which figured which window had the focus and call its method as required. As I said, FWIW I haven't looked at Qt::WidgetShortcut, yet.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      You can associate an action with several widgets. Did you check if sender gives you the information you seek once you add the action to all the widgets you want to use it on ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      JonBJ 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        You can associate an action with several widgets. Did you check if sender gives you the information you seek once you add the action to all the widgets you want to use it on ?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        @SGaist said in Signal/slot vs direct call, and related question:

                        once you add the action to all the widgets you want to use it on

                        The code is not (presently) written that way. All menu items/toolbar items/shortcuts have actions & slots in the main window class. I guess all shortcuts are the default Qt::WindowShortcut. Most do not care what the focused widget is, e.g. New/Open/Save/Exit etc. In the case of Copy/Cut/Paste, however, it does matter whether, say, the graphics widget has the focus.

                        I expected to handle that in the main window action slot by checking which widget has focus. It sounds like maybe if I look into using Qt::WidgetShortcut (or maybe Qt::WidgetWithChildrenShortcut?) on Copy/Cut/Paste for the gfx widget (and any others which might want these in the future), the menu items and shortcut keys will only activate when the desired window is focused, and my main window will not have to decide who to "dispatch" to. I need to have a look at how this behaves tomorrow....

                        1 Reply Last reply
                        0
                        • JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @Pl45m4 , @SGaist
                          Now I am trying to make this work with Qt::WidgetShortcut, which does seem like it should be the right approach. However, it does not work correctly at all! Please don't abandon me! Read on...

                          • I have a QMainWindow. I design it, and add its toolbar/menu items/shortcuts in Designer.
                          • It has 4 widgets inside it. One of them is the QGraphicsScene/View. That has code for, say, Cut. The others do not (at present) have anything for Cut.
                          • In the case of a menu item/toolbar/shortcut key Cut I want that to go to the gfx view if it has the focus, else it should be ignored.

                          This really should not be an unusual situation. Some menu items function regardless of which widget has focus (e.g. Save), some depend on which widget has focus (e.g. Cut).

                          I start from the relevant code as generated (mainwindow.py), which includes:

                          self.action_cut = QtWidgets.QAction(MainWindow)
                          self.action_cut.setShortcutContext(QtCore.Qt.WindowShortcut)
                          self.menuEdit.addAction(self.action_cut)
                          self.toolBar.addAction(self.action_cut)
                          self.action_cut.setShortcut(QtWidgets.QApplication.translate("MainWindow", "Ctrl+X", None, -1))
                          

                          To make this work, I have found I can go:

                          self.action_cut.triggered.connect(self.cut)
                          
                          def cut(self):
                              if QApplication.focusWidget() is self.graphicsView_model:
                                  self.model_scene.cutItems()
                          

                          At this point:

                          • If I click the toolbar/menu item, regardless of where focus is my cut() is hit. Its code determines whether the gfx widget has focus or not, and correctly works accordingly.
                          • If I click Ctrl+X, if the current focus widget absorbs that (e.g. a QLineEdit in some other widget). If not (e.g. on a plain QWidget) it goes via my cut(), and again that checks focus and works correctly.

                          Now I try changing as best I can to make the Cut only apply to my gfx widget. I change/add things like:

                          self.action_cut.setParent(self.graphicsView_model)
                          # OR
                          self.action_cut = QtWidgets.QAction(self.graphicsView_model)
                          self.action_cut.setShortcutContext(QtCore.Qt.WidgetShortcut)
                          # OR
                          self.action_cut.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut)
                          

                          At this point:

                          • If I click toolbar/menu it still calls my cut() regardless of where focus is. It has not made it so this is only called when self.graphicsView_model has focus. So I will still need to test if QApplication.focusWidget() is self.graphicsView_model.
                          • Ctrl+X no longer does anything, regardless of focus.

                          Both of these are no good/not expected.

                          I came across thread starting at https://lists.qt-project.org/pipermail/qt-interest-old/2011-February/031257.html. I think that guy reports my findings trying to use Qt::WidgetShortcut. Summary:

                          So if I install an action on a QWidget I would assume that the actions
                          shortcut is only active if the QWidget has focus, right? But this seems
                          to be broken somehow.
                          .
                          My educated guess would be that this "shortcut context" thing might only work between "dialog and main windows", but not between common QWidgets?

                          In a word: if you expect Qt::WidgetShortcut to work for me, please tell me how?!

                          My case should not be that unusual: some menu items/shortcuts apply regardless of focused window, some do not. If you do not want me to have to use my if QApplication.focusWidget() is self.graphicsView_model-type-dispatching, please tell me how?! I'm exhausted typing this all up....

                          P.S.
                          And this is only a P.S., I really don't think this is to do with the problem:
                          @SGaist said in Signal/slot vs direct call, and related question:

                          You can associate an action with several widgets. Did you check if sender gives you the information you seek once you add the action to all the widgets you want to use it on ?

                          See the accepted solutuon at https://stackoverflow.com/a/6003452/489865. Note how the approach is still to look at QWidget::hasFocus() to decide which the user was in when trying to invoke the action. If I'm going to do that, my current code will suffice.

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved