Qt5 QLabel::setTextInteractionFlags() not behaving as expected
-
I am using Qt 5.7. I have inherited code reading:
label = QLabel("Word1 Word2", self) label.setTextInteractionFlags(Qt.TextSelectableByMouse)
Docs for
Qt.TextSelectableByMouse
(http://doc.qt.io/qt-5/qt.html#TextInteractionFlag-enum):Qt::TextSelectableByMouse
1
Text can be selected with the mouse and copied to the clipboard using a context menu or standard keyboard shortcuts.This creates a label. I can use the mouse to select all or part of the text. So far so good.
I am reliably informed by stakeholder that at Qt 4 with this code, after selecting some text (in their case
Word2
, I don't think that's relevant, but must work in any proposed solution) user could click Ctrl+C and text would be copied to clipboard correctly. This corresponds to the documentation above "copied to the clipboard using [...] standard keyboard shortcuts."No copying to clipboard happens under Qt 5.7.
I note that I can right-click and a context menu pops up. There I see Copy shown (which works if I click on it), and also Select All Ctrl+A. Ctrl+A does work to select all text. Ctrl+C does not work.
- Under Linux the Copy is written with an underline under the
C
. Implying Ctrl+C should work. - Under Windows I am told the Copy does not have its
C
underlined.
Anyway, the gist is: stakeholder needs functionality as it (apparently) was under Qt 4: Ctrl+C should copy selected text. What is going on with the documentation/behaviour wrt the supposed but non-functioning support for "standard keyboard shortcuts"?
- Under Linux the Copy is written with an underline under the
-
Solved! The reason the label did not get the Ctrl+C for copy is that the (unrelated)
QTableView
on the page has a Copy shortcut and that (only) is receiving the shortcut.I have to say this was not clear to me from the documentation, but a
QAction
has a http://doc.qt.io/qt-5/qaction.html#shortcutContext-prop, and the default from http://doc.qt.io/qt-5/qt.html#ShortcutContext-enum isQt::WindowShortcut
, meaning that it applies to the whole window. If you define aQAction
for a widget you need to call:self.copyAction.setShortcutContext(Qt.WidgetShortcut)
to restrict it to the widget only. Once I did this, the Ctrl+C was free to work independently on my
QLabel
to allow copying there.@mrjj Thanks for your input. The above is what I needed to learn.
-
Hi
Just tested.
Works in 5.11.1 on windows. ctrl+c does copy labels text to clipboard. -
-
@mrjj
Houston, we have a problem....I tried in a standalone. Sure enough it does work (Linux). Sigh....
One notable difference: in the standalone which works, the right-click context menu does have the shortcut Ctrl+C shown (at the right-hand side) against Copy. Just like the Ctrl+A shown against Select All which has always worked. But (hence I wrote it above as a clue) in the actual project the menu's Copy does not show Ctrl+C. Clearly at some level this is the issue, so...
...What would make the context menu not show that??
-
@JonB
Oh that is odd.
As far as i know menu comes from createStandardContextMenu()
but maybe label uses another one
Browsing
https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html#_ZN6QLabel23setTextInteractionFlagsE6QFlagsIN2Qt19TextInteractionFlagEE
to see if we can find what makes the menu for us.update:
this one does it
https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qwidgettextcontrol.cpp.html#_ZN18QWidgetTextControl25createStandardContextMenuERK7QPointFP7QWidgetupdate2:
must be something in this that is different from test to real app
#define ACCEL_KEY(k) ((!QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus) \ && QGuiApplication::styleHints()->showShortcutsInContextMenus()) \ && !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \ QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
I do wonder if something else register this shortcutkey that
hasShortcutForKeySequence fails and hence its not added.i would try call
qApp->d_func()->shortcutMap.hasShortcutForKeySequence(QKeySequence::Copy)
and see if it returns true for the real app. ( if possible. seems to be inside private class) -
@mrjj
Can't get as far asd_func
(PyQt, and no sources).We know that other shortcuts (e.g.
Ctrl+A
) are shown on menu, so it's not global.No occurrences ofDamn, but there is an obscure one, and 'coz it's Python that'sQKeySequence::Copy
QKeySequence.Copy
, which I failed to check :(.Found it works on one page in my project, not on the one I want. Clearly I have goodness-knows-what to search the code for to track this down.... :(
-
@mrjj
OK, mystery both "solved" & "deepened"!Elsewhere on the page causing me problems, I have a
QTableView
for which "selected row copy" is enabled. Code for that widget is like:class JTableView(QtWidgets.QTableView): """Table view with copy enabled""" def __init__(self, parent=None): super().__init__(parent) # Allow Ctrl+C to copy the table to the clipboard self.copyAction = QAction("Copy", self) self.copyAction.setShortcut(QKeySequence.Copy) self.copyAction.triggered.connect(self.copyToClipboard) self.addAction(self.copyAction)
If I hack out the
copyAction
lines temporarily, the copying of the label text springs back to life.Note that the
self
here is theQTableView
itself, so why is that code affecting the whole page?Now, there is a difference here from what used to be there and worked at Qt 4. In the old code the Ctrl+C on a table was recognised by actual key-press event code. I asked about this in this forum in topic https://forum.qt.io/topic/92513/correctly-detecting-ctrl-key-click. In a reply there @SGaist suggested it would be better to change key-event code over to a shortcut action, which is what I did above. That must be why it worked previously but not now. Why??!!
-
Hi
I wonder if label do get keyboard focus when selected text.
Else it might be the table that fas focus and hence get the shortcut activation. -
Solved! The reason the label did not get the Ctrl+C for copy is that the (unrelated)
QTableView
on the page has a Copy shortcut and that (only) is receiving the shortcut.I have to say this was not clear to me from the documentation, but a
QAction
has a http://doc.qt.io/qt-5/qaction.html#shortcutContext-prop, and the default from http://doc.qt.io/qt-5/qt.html#ShortcutContext-enum isQt::WindowShortcut
, meaning that it applies to the whole window. If you define aQAction
for a widget you need to call:self.copyAction.setShortcutContext(Qt.WidgetShortcut)
to restrict it to the widget only. Once I did this, the Ctrl+C was free to work independently on my
QLabel
to allow copying there.@mrjj Thanks for your input. The above is what I needed to learn.
-
Ah cool. never noticed the Qt::WindowShortcut default :)
Good found. Now we know next time what to check for when shortcuts stops working.