Ideal way to show markable text in QGraphicsScene
-
My question is related to this question (https://forum.qt.io/topic/120114/how-to-select-only-part-of-a-text-of-qgraphictextitem) but more general now.
My setup:
Python 3.7.3
PySide2 5.15.1
OS: Debian(I am quite a novice to Qt and GUI programming in general, just to provide some background)
I am showing text on a
QGraphicsScene
via usingQGraphicsTextItem
.Everything works well so far. But I am really struggling with comming up with a solution in order to mark only parts of the text via mouse (click-drag-relase) like I would do in a webbrowser or in a word doc.
EDIT: The marked text then also needs to be copyable.
I was able to make the text selectable via
setTextInteractionFlags(QtGui.Qt.TextSelectableByMouse)
but this way I can only select the entire text of theQGraphicsTextItem
.So my questions:
- Is
QGraphicsTextItem
the right type of widget for this? Is there anything better suited? - If it is the right type of widget: Can anyone hint me the right direction? Do I have to inherit QGraphicsTextItem and to catch the mouse events and do something on my own? Can I do this in PySide2? Or is there an already implemented way to do this?
So thankful for a hint!
Michael - Is
-
Hi,
Can you provide a minimal runnable script that allows to test your issue ?
-
Oh, while trying to set up a minimal example I discovered that
QGraphicsTextIteam
actually by default DOES what I want.The problem is that I defined a new class deriving
QGraphicsTextIteam
and there I seem to have messed up!I will make a minimal example with this new class and post it as soon as I am done.
-
Now I have a working example. The problem was that I did not propagate the event (
super().mousePressEvent(event)
).But now I have another problem. The application crahes with a
segfault
as soon as I do a right click. Probably this is my fault as well but I do not see what could cause it...Here the minimal example:
from PySide2 import QtWidgets, QtCore, QtGui class TextItem(QtWidgets.QGraphicsTextItem): def __init__(self): QtWidgets.QGraphicsTextItem.__init__(self) def mousePressEvent(self, event): if(event.button() == QtCore.Qt.MouseButton.LeftButton): print("left button") if(event.button() == QtCore.Qt.MouseButton.RightButton): print("right button") super().mousePressEvent(event) class MainWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Window title") self.scene = QtWidgets.QGraphicsScene() self.view = QtWidgets.QGraphicsView(self.scene) self.layout = QtWidgets.QHBoxLayout() self.layout.addWidget(self.view) self.setLayout(self.layout) self.setCentralWidget(self.view) app = QtWidgets.QApplication([]) window = MainWindow() window.resize(400, 100) window.show() text = TextItem() text.setTextInteractionFlags(QtGui.Qt.TextSelectableByMouse) text.setHtml("This is a test text text text text text text text text ...") window.scene.addItem(text) app.exec_()
-
Now I have a working example. The problem was that I did not propagate the event (
super().mousePressEvent(event)
).But now I have another problem. The application crahes with a
segfault
as soon as I do a right click. Probably this is my fault as well but I do not see what could cause it...Here the minimal example:
from PySide2 import QtWidgets, QtCore, QtGui class TextItem(QtWidgets.QGraphicsTextItem): def __init__(self): QtWidgets.QGraphicsTextItem.__init__(self) def mousePressEvent(self, event): if(event.button() == QtCore.Qt.MouseButton.LeftButton): print("left button") if(event.button() == QtCore.Qt.MouseButton.RightButton): print("right button") super().mousePressEvent(event) class MainWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("Window title") self.scene = QtWidgets.QGraphicsScene() self.view = QtWidgets.QGraphicsView(self.scene) self.layout = QtWidgets.QHBoxLayout() self.layout.addWidget(self.view) self.setLayout(self.layout) self.setCentralWidget(self.view) app = QtWidgets.QApplication([]) window = MainWindow() window.resize(400, 100) window.show() text = TextItem() text.setTextInteractionFlags(QtGui.Qt.TextSelectableByMouse) text.setHtml("This is a test text text text text text text text text ...") window.scene.addItem(text) app.exec_()
-
@MS_GX said in Ideal way to show markable text in QGraphicsScene:
The application crahes with a segfault as soon as I do a right click.
So do you run it from inside debugger and get the stack trace to see the cause? That's how we debug programs.
Thanks much!
I did some debugging and got the following (without capturing the
contextMenuEvent
for right button obviously):(gdb) file python Reading symbols from python...(no debugging symbols found)...done. (gdb) run /home/user/SW/minimal_example/example.py Starting program: /home/user/SW/venv/bin/python /home/user/SW/minimal_example/example.py [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff4299700 (LWP 11120)] [New Thread 0x7ffff1a98700 (LWP 11121)] [New Thread 0x7fffef297700 (LWP 11122)] Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. [New Thread 0x7fffe1efa700 (LWP 11123)] [New Thread 0x7fffdb76d700 (LWP 11124)] [New Thread 0x7fffdaf4b700 (LWP 11125)] [New Thread 0x7fffda71e700 (LWP 11126)] [New Thread 0x7fffd9f0c700 (LWP 11127)] [New Thread 0x7fffcb5ba700 (LWP 11128)] [New Thread 0x7fffcadb9700 (LWP 11129)] right button Thread 1 "python" received signal SIGSEGV, Segmentation fault. 0x00007fffe91d3b58 in QWidget::window() const () from /home/user/Software/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5
-
Thanks much!
I did some debugging and got the following (without capturing the
contextMenuEvent
for right button obviously):(gdb) file python Reading symbols from python...(no debugging symbols found)...done. (gdb) run /home/user/SW/minimal_example/example.py Starting program: /home/user/SW/venv/bin/python /home/user/SW/minimal_example/example.py [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff4299700 (LWP 11120)] [New Thread 0x7ffff1a98700 (LWP 11121)] [New Thread 0x7fffef297700 (LWP 11122)] Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. [New Thread 0x7fffe1efa700 (LWP 11123)] [New Thread 0x7fffdb76d700 (LWP 11124)] [New Thread 0x7fffdaf4b700 (LWP 11125)] [New Thread 0x7fffda71e700 (LWP 11126)] [New Thread 0x7fffd9f0c700 (LWP 11127)] [New Thread 0x7fffcb5ba700 (LWP 11128)] [New Thread 0x7fffcadb9700 (LWP 11129)] right button Thread 1 "python" received signal SIGSEGV, Segmentation fault. 0x00007fffe91d3b58 in QWidget::window() const () from /home/user/Software/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5
@MS_GX
When the seg fault happens you need to look at the stack trace. That is a window if your are debugging inside Qt Creator, or thebt
command if you are runninggdb
manually.Having said. I'm not sure I appreciated you are running Python. I'm not certain
gdb
stack trace will be useful there, I don't know whether if you run inside a Python debugger you will have more joy.Having said that: I just pasted your code and tried here on my Ubuntu 20.04/GNOME, and right-click was fine, it brought up the internal "Copy" menu.
-
@MS_GX
When the seg fault happens you need to look at the stack trace. That is a window if your are debugging inside Qt Creator, or thebt
command if you are runninggdb
manually.Having said. I'm not sure I appreciated you are running Python. I'm not certain
gdb
stack trace will be useful there, I don't know whether if you run inside a Python debugger you will have more joy.Having said that: I just pasted your code and tried here on my Ubuntu 20.04/GNOME, and right-click was fine, it brought up the internal "Copy" menu.
-
@JonB Thanks for the hints! Are you running Wayland or X11? Because I am running Wayland and I get this wayland warning there. Do you think that this might cause the problem?
Anyway, I will try to debug as you said. Many thanks!
-
@MS_GX
Yup, I wouldn't know what "Wayland" was if it smacked me upside the head ;-) I am X11, vanilla Ubuntu 20.04 inside a vanilla Windows (7) PC with a vanilla gfx card/monitor. All drivers up-to-date.Here the stacktrace for now. Not sure if helpful since I am not able to judge this to be honest.
(gdb) bt #0 0x00007fffe91d3b58 in QWidget::window() const () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #1 0x00007fffe9389156 in QWidgetTextControlPrivate::contextMenuEvent(QPoint const&, QPointF const&, QWidget*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #2 0x00007fffe9389a9c in QWidgetTextControl::processEvent(QEvent*, QTransform const&, QWidget*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #3 0x00007fffe938065b in QWidgetTextControl::processEvent(QEvent*, QPointF const&, QWidget*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #4 0x00007fffe9472ecc in QGraphicsTextItem::dropEvent(QGraphicsSceneDragDropEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #5 0x00007fffe9e2ec2f in QGraphicsTextItemWrapper::contextMenuEvent(QGraphicsSceneContextMenuEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #6 0x00007fffe947f7e1 in QGraphicsItem::sceneEvent(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #7 0x00007fffe947f985 in QGraphicsTextItem::sceneEvent(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #8 0x00007fffe9e33c1d in QGraphicsTextItemWrapper::sceneEvent(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #9 0x00007fffe94a02ed in QGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #10 0x00007fffe9e165b7 in QGraphicsSceneWrapper::contextMenuEvent(QGraphicsSceneContextMenuEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #11 0x00007fffe94b0bd5 in QGraphicsScene::event(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #12 0x00007fffe9e1802d in QGraphicsSceneWrapper::event(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #13 0x00007fffe91ad3cc in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #14 0x00007fffe91b3eb0 in QApplication::notify(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #15 0x00007fffe9c835a5 in QApplicationWrapper::notify(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #16 0x00007fffe81bf0e8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 --Type <RET> for more, q to quit, c to continue without paging--c #17 0x00007fffe94ce8a2 in QGraphicsView::contextMenuEvent(QContextMenuEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #18 0x00007fffe9e40d67 in QGraphicsViewWrapper::contextMenuEvent(QContextMenuEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #19 0x00007fffe91ec398 in QWidget::event(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #20 0x00007fffe929400e in QFrame::event(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #21 0x00007fffe94ce2ab in QGraphicsView::viewportEvent(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #22 0x00007fffe9e48d9d in QGraphicsViewWrapper::viewportEvent(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #23 0x00007fffe81bee80 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 #24 0x00007fffe91ad3a2 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #25 0x00007fffe91b5504 in QApplication::notify(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #26 0x00007fffe9c835a5 in QApplicationWrapper::notify(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #27 0x00007fffe81bf0e8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 #28 0x00007fffe92050ca in QWidgetWindow::handleMouseEvent(QMouseEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #29 0x00007fffe9207c83 in QWidgetWindow::event(QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #30 0x00007fffe91ad3cc in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #31 0x00007fffe91b3eb0 in QApplication::notify(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Widgets.so.5 #32 0x00007fffe9c835a5 in QApplicationWrapper::notify(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #33 0x00007fffe81bf0e8 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 #34 0x00007fffe88886d6 in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Gui.so.5 #35 0x00007fffe8889ae5 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Gui.so.5 #36 0x00007fffe88658cb in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Gui.so.5 #37 0x00007fffe2e4157a in xcbSourceDispatch(_GSource*, int (*)(void*), void*) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/plugins/platforms/../../lib/libQt5XcbQpa.so.5 #38 0x00007fffe5134f2e in g_main_context_dispatch () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 #39 0x00007fffe51351c8 in ?? () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 #40 0x00007fffe513525c in g_main_context_iteration () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 #41 0x00007fffe821aaac in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 #42 0x00007fffe81bdafa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 #43 0x00007fffe81c6ab3 in QCoreApplication::exec() () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/Qt/lib/libQt5Core.so.5 #44 0x00007fffe9c81038 in Sbk_QApplicationFunc_exec_ () from /home/user/SW/venv/lib/python3.7/site-packages/PySide2/QtWidgets.abi3.so #45 0x00000000005d7061 in _PyMethodDef_RawFastCallKeywords () #46 0x000000000054aac0 in ?? () #47 0x0000000000551bf9 in _PyEval_EvalFrameDefault () #48 0x000000000054b452 in _PyEval_EvalCodeWithName () #49 0x000000000054d7f3 in PyEval_EvalCode () #50 0x0000000000630152 in ?? () #51 0x0000000000630207 in PyRun_FileExFlags () #52 0x0000000000630e6f in PyRun_SimpleFileExFlags () #53 0x0000000000653eae in ?? () #54 0x000000000065420e in _Py_UnixMain () #55 0x00007ffff79c109b in __libc_start_main (main=0x4bc8d0 <main>, argc=2, argv=0x7fffffffd748, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd738) at ../csu/libc-start.c:308 #56 0x00000000005df66a in _start ()