Pyqt5:如何限制QMainWindow中QPushButton的拖动区域?
Pyqt5: How to limit the dragging area of a QPushButton in QMainWindow?
在 QWidget 中拖动 QPushButton 时,它会工作直到它消失 一旦它通过(跨越)MainWindow 的边界(QWidget )
我想将此 QPushButton 限制为不跨越其容器的边界,但仅在 QWidget 中保持可见
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import Qt
class DragButton(QPushButton):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.globalPos()
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
# adjust offset from clicked point to origin of widget
currPos = self.mapToGlobal(self.pos())
globalPos = event.globalPos()
diff = globalPos - self.__mouseMovePos
newPos = self.mapFromGlobal(currPos + diff)
self.move(newPos)
self.__mouseMovePos = globalPos
super(DragButton, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.__mousePressPos is not None:
moved = event.globalPos() - self.__mousePressPos
if moved.manhattanLength() > 3:
event.ignore()
return
super(DragButton, self).mouseReleaseEvent(event)
def clicked():
print ("click as normal!")
if __name__ == "__main__":
app = QApplication([])
w = QWidget()
w.resize(800,600)
button = DragButton("Drag", w)
button.clicked.connect(clicked)
w.show()
app.exec_()
有办法吗?
由于要求确保子项在父项的边界内,因此您需要检查子项 rect()
转换到新位置后是否在该区域内 在移动它之前。
请注意,要实现“自我”移动,无需连续平移全局位置。
class DragButton(QPushButton):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.pos()
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
delta = event.pos() - self.__mouseMovePos
newPos = self.pos() + delta
if self.parent():
geo = self.rect().translated(newPos)
parentRect = self.parent().rect()
if geo.x() < 0:
geo.moveLeft(0)
elif geo.right() > parentRect.right():
geo.moveRight(parentRect.right())
if geo.y() < 0:
geo.moveTop(0)
elif geo.bottom() > parentRect.bottom():
geo.moveBottom(parentRect.bottom())
self.move(geo.topLeft())
else:
self.move(newPos)
super(DragButton, self).mouseMoveEvent(event)
另请注意,拖动已启用的按钮并不是一个好主意,因为它可能会导致不需要的、不直观的和意外的行为。您的实现显示了这一点,因为如果按钮移动超过 3 像素限制,它将保持按下状态。
在 QWidget 中拖动 QPushButton 时,它会工作直到它消失 一旦它通过(跨越)MainWindow 的边界(QWidget )
我想将此 QPushButton 限制为不跨越其容器的边界,但仅在 QWidget 中保持可见
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtCore import Qt
class DragButton(QPushButton):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.globalPos()
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
# adjust offset from clicked point to origin of widget
currPos = self.mapToGlobal(self.pos())
globalPos = event.globalPos()
diff = globalPos - self.__mouseMovePos
newPos = self.mapFromGlobal(currPos + diff)
self.move(newPos)
self.__mouseMovePos = globalPos
super(DragButton, self).mouseMoveEvent(event)
def mouseReleaseEvent(self, event):
if self.__mousePressPos is not None:
moved = event.globalPos() - self.__mousePressPos
if moved.manhattanLength() > 3:
event.ignore()
return
super(DragButton, self).mouseReleaseEvent(event)
def clicked():
print ("click as normal!")
if __name__ == "__main__":
app = QApplication([])
w = QWidget()
w.resize(800,600)
button = DragButton("Drag", w)
button.clicked.connect(clicked)
w.show()
app.exec_()
有办法吗?
由于要求确保子项在父项的边界内,因此您需要检查子项 rect()
转换到新位置后是否在该区域内 在移动它之前。
请注意,要实现“自我”移动,无需连续平移全局位置。
class DragButton(QPushButton):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.pos()
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
delta = event.pos() - self.__mouseMovePos
newPos = self.pos() + delta
if self.parent():
geo = self.rect().translated(newPos)
parentRect = self.parent().rect()
if geo.x() < 0:
geo.moveLeft(0)
elif geo.right() > parentRect.right():
geo.moveRight(parentRect.right())
if geo.y() < 0:
geo.moveTop(0)
elif geo.bottom() > parentRect.bottom():
geo.moveBottom(parentRect.bottom())
self.move(geo.topLeft())
else:
self.move(newPos)
super(DragButton, self).mouseMoveEvent(event)
另请注意,拖动已启用的按钮并不是一个好主意,因为它可能会导致不需要的、不直观的和意外的行为。您的实现显示了这一点,因为如果按钮移动超过 3 像素限制,它将保持按下状态。