@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.