0

I write a simple window, when cursor in QLineEdit and press Enter Key, I want the QGraphicsRectItem, QGraphicsScene, QGraphicsView and QWidget also accept QKeyEvent or MyEvent(customize event).I have no idea to do it,Could someone have good method to do this?

Code Sample

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

class MyEvent(QEvent):
    Type = QEvent.registerEventType()
    def __init__(self):
        super().__init__(MyEvent.Type)
        self._data = "test"

class Item(QGraphicsRectItem):
    def __init__(self):
        super().__init__()
        self.setRect(0 ,0,  100, 100)
        self.setBrush(Qt.red)
        self.setFlags(QGraphicsItem.ItemIsFocusable)

    def keyPressEvent(self, event: QKeyEvent) -> None:
        print("Item KeyPress", event.key())
        return super().keyPressEvent(event)

class Scene(QGraphicsScene):
    def keyPressEvent(self, event: QKeyEvent) -> None:
        print("Scene KeyPress", event.key())
        return super().keyPressEvent(event)

class View(QGraphicsView):
    def keyPressEvent(self, event: QKeyEvent) -> None:
        print("View KeyPress", "do something work here", event.key())
        return super().keyPressEvent(event)

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        lay = QVBoxLayout()
        view = View()
        scene = Scene()
        scene.addItem(Item())
        view.setScene(scene)
        lay.addWidget(view)
        lay.addWidget(QLineEdit("Cursor In here, post Enter Event to QGraphicsView"))
        self.setLayout(lay)
        self.show()

        self.view = view

    def keyPressEvent(self, e: QKeyEvent) -> None:
        print("QWidget KeyPress", e.key())

        # myEvent = MyEvent()
        # QApplication.postEvent(myEvent)
        return super().keyPressEvent(e)

app = QApplication([])
m = MainWindow()
app.exec()

How let others item also get the event? enter image description here

jett chen
  • 1,067
  • 16
  • 33
  • You don't need a custom event for that. May I ask you why you need *all* those targets to receive the same event? What are you trying to achieve? – musicamante May 28 '22 at 09:35
  • Just write some code test,Need all other targets receive event to do some work, like show text, change color and so on. – jett chen May 28 '22 at 09:47
  • Key events are sent to the *focused* object (usually, a Qt widget), if they are not *accepted* they are propagated to their parents through the object hierarchy. This means that a widget that is a *sibling* of the focused one will **never** receive those events. If you want multiple items to react to key events, and those items have no direct [gran]parent/[gran]child relation, then you must propagate the event programmatically. It seems unlikely that you need a specific override of `keyPressEvent()` (due to the expected behavior explained above), so you should probably create an -> – musicamante May 28 '22 at 21:44
  • -> implementation on the common parent (the scene, in this case) and eventually call the relative functions of each item. Note that overriding the main window `keyPressEvent()` is rarely a good idea, as widgets can handle (and, thus, prevent propagation) those events, or you could receive events that were meant (or should have been ignored) for other widgets. If you're interested in key events of the line edit, then install an event filter on it, then post the event on the Graphics View, and add your implementation in the override of the scene `keyPressEvent()`. – musicamante May 28 '22 at 21:47
  • `QGraphicsView` events seems different with `QWidget` events. Post Qt event may cause many problem, but post customize my event will ok. – jett chen May 31 '22 at 02:24
  • Yes of course they are different, as widgets are different than graphics items. Posting events to widgets represents a problem only if the event is not properly created, was previously handled and accepted or causes recursion. Besides, QGraphicsScene events *cannot* be synthesized, as they are autonomously created by the view and internally managed by the scene. – musicamante May 31 '22 at 07:37

0 Answers0