通常のクリック信号を適切にサポートする可動ボタンの例を次に示します。
from PyQt4 import QtCore, QtGui
class DragButton(QtGui.QPushButton):
def mousePressEvent(self, event):
self.__mousePressPos = None
self.__mouseMovePos = None
if event.button() == QtCore.Qt.LeftButton:
self.__mousePressPos = event.globalPos()
self.__mouseMovePos = event.globalPos()
super(DragButton, self).mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == QtCore.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 = QtGui.QApplication([])
w = QtGui.QWidget()
w.resize(800,600)
button = DragButton("Drag", w)
button.clicked.connect(clicked)
w.show()
app.exec_()
IではmousePressEvent
、最初の開始位置と、ドラッグ中に更新される位置の両方を記録します。
ではmouseMoveEvent
、移動が正確になるように、クリックされた場所から実際の原点までのウィジェットの適切なオフセットを取得します。
でmouseReleaseEvent
、全体的な移動が少なくともわずかな量よりも大きかったかどうかを確認します。もしそうなら、それはドラッグであり、「クリックされた」信号を生成しないように通常のイベントを無視します。それ以外の場合は、通常のイベント ハンドラーがクリックを生成できるようにします。