Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Application stops receiving Keypress events during drag operation

Application stops receiving Keypress events during drag operation

Scheduled Pinned Locked Moved Solved Qt for Python
2 Posts 1 Posters 183 Views
  • 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.
  • S Offline
    S Offline
    sigmareaver
    wrote on last edited by sigmareaver
    #1

    I'm working on a project where I want to drag shaped widgets onto a grid, and I want to be able to rotate the shape when the R key is pressed. However, despite my best efforts, all keyboard events stop being processed when a drag operation is in progress.

    I've tried:

    • a custom QDrag class with an event filter installed.
    • having a keyPressEvent function on my window class, my widget classes, and the QDrag class
    • Installing event filters on the QApplication and the window
    • StrongFocus policy with setFocus on the widget
    • grabKeyboard on the window and widget

    I've tried both PyQt5 and PyQt6 to no avail. For what it's worth, I'm on Linux. I haven't tested on Windows. No matter what I've tried though, the application stops receiving keyboard events during a drag operation.

    I haven't been able to find any information or examples online about getting keyboard input during a drag operation, so I've finally relented and am asking here about this issue.

    Below is a minimal(-ish) viable reproduction that also includes what I have going on:

    import sys
    from PyQt6.QtWidgets import (
        QApplication, QMainWindow, QWidget, QHBoxLayout, QLabel, QFrame
    )
    from PyQt6.QtGui import QPixmap, QDrag
    from PyQt6.QtCore import Qt, QMimeData
    
    
    class DragTestWindow(QMainWindow):
        def __init__(self):
            super().__init__()
    
            self.setFixedSize(800, 600)
            main_widget = QWidget()
            self.setCentralWidget(main_widget)
            main_layout = QHBoxLayout()
            main_widget.setLayout(main_layout)
            block = DraggableBlock()
            main_layout.addWidget(block)
    
        def keyPressEvent(self, key):
            print("DragTestWindow keyPressEvent")
    
    
    class DraggableBlock(QLabel):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.setFrameShape(QFrame.Shape.Box)
            self.setFixedSize(100, 50)
            self.setStyleSheet("background-color: gray;")
            self.setText("Block")
            self.setAlignment(Qt.AlignmentFlag.AlignCenter)
    
        def mousePressEvent(self, event):
            if event.button() == Qt.MouseButton.LeftButton:
                drag = DragWithRotation(self)
                mime_data = QMimeData()
    
                drag.setMimeData(mime_data)
                drag.setHotSpot(event.pos())
    
                pixmap = QPixmap(self.size())
                self.render(pixmap)
                drag.setPixmap(pixmap)
    
                drag.exec(Qt.DropAction.MoveAction)
    
        def keyPressEvent(self, ev):
            print("DraggableBlock keyPressEvent")
    
    
    class DragWithRotation(QDrag):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        def keyPressEvent(self, event):
            print("DragWithRotation keyPressEvent")
    
        def exec_(self, *args, **kwargs):
            application = QApplication.instance()
            application.installEventFilter(self)
            super().exec(*args, **kwargs)
            application.removeEventFilter(self)
    
        def eventFilter(self, obj, event):
            if event.type() == event.KeyPress:
                self.keyPressEvent(event)
                return True
            return False
    
    
    def main():
        app = QApplication(sys.argv)
        dragtest_window = DragTestWindow()
        dragtest_window.show()
    
        sys.exit(app.exec())
    
    if __name__ == "__main__":
        main()
    
    1 Reply Last reply
    1
    • S Offline
      S Offline
      sigmareaver
      wrote on last edited by
      #2

      I've found a solution using QAbstractNativeEventFilter to grab the keyboard events that never make it to the standard Qt event system.

      1 Reply Last reply
      0
      • S sigmareaver has marked this topic as solved on

      • Login

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