Issue
I have a Qt program that has many child widgets. I want the user to be able to move the window by middle mouse clicking and dragging around, it works fine when there are no children, like this:
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.startPos = QtCore.QPoint()
def mousePressEvent(self, event):
self.startPos = event.pos()
super(MainWindow, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.Qt.MiddleButton:
delta = event.pos() - self.startPos
self.move(self.pos() + delta)
event.accept()
super(MainWindow, self).mouseMoveEvent(event)
But when I populate my widget with all the children widgets, and their children widgets, and so on. I only catch the event if I click in the margin/padding area, and not anywhere else in the widget.
Is there a way to make the middle mouse drag event usable with children widgets in the way?
Solution
When mouse events are intercepted by widgets that can relate to them, they are automatically accepted and won't be relayed to the parent widgets. While most widgets ignore middle clicks, some actually do, so your main window will never receive them.
The solution is to install an event filter on the QApplication instead, so that any mouse event you're interested into will be filtered before being sent to any possible target widget:
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
# just some test widgets
layout = QtWidgets.QGridLayout(self)
for row in range(4):
for col in range(4):
layout.addWidget(QtWidgets.QPushButton('Button'), row, col)
layout.addWidget(QtWidgets.QTextEdit(),
layout.rowCount(), 0, 1, layout.columnCount())
self.startPos = None
# install the event filter on the application
QtWidgets.QApplication.instance().installEventFilter(self)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseButtonPress and
event.button() == QtCore.Qt.MiddleButton):
self.startPos = event.pos()
return True
elif event.type() == QtCore.QEvent.MouseMove and self.startPos is not None:
self.move(self.pos() + event.pos() - self.startPos)
return True
elif event.type() == QtCore.QEvent.MouseButtonRelease and self.startPos is not None:
self.startPos = None
return True
return super(MainWindow, self).eventFilter(source, event)
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.