PyQt5初级教程--PyQt5中的拖放[10/13]

时间:2021-10-16 04:46:01
想用PyQt5写GUI,但是网上的PyQt5资源太少了,找到一个英文的,翻译一下,和学习PyQt5的同学共勉!

(本系列中所有代码在windows7 64位[]/Python 3.4.3 32bit/PyQt GPL v5.5 for Python v3.4 (x32)/eric6-6.0.8下测试通过.)

原本地址:http://zetcode.com/gui/pyqt5/

================================================================================

在这部分我们会讨论拖放操作.

在计算机的图形用户界面,拖放是一个通过点击住某虚拟对象并拖动它到不同位置或其他虚拟对象的操作.通常,它可以用于调用很多种动作或在两个抽象对象之间创建不同类型的关联.

拖放是图形用户界面的一部分.拖放操作允许用户很直观地完成复杂的事情.

通常情况下,我们可以拖放两种东西:数据和一些图形对象.如果我们把一张图片从一个程序拖放到另一个程序上,那我们拖放的是二进制数据.如果我们在Firefox里拖一个标签,然后把它放到别的地方,那么我们拖放的是一个图形组件.

简单的拖放

在第一个例子里,我们有一个QLineEdit和一个QPushButton.我们把纯文本从行编辑器部件拖放到按钮部件上.按钮的标签会改变.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial

This is a simple drag and
drop example.

author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import (QPushButton, QWidget,
QLineEdit, QApplication)

class Button(QPushButton):

def __init__(self, title, parent):
super().__init__(title, parent)

self.setAcceptDrops(True)


def dragEnterEvent(self, e):

if e.mimeData().hasFormat('text/plain'):
e.accept()
else:
e.ignore()

def dropEvent(self, e):

self.setText(e.mimeData().text())


class Example(QWidget):

def __init__(self):
super().__init__()

self.initUI()


def initUI(self):

edit = QLineEdit('', self)
edit.setDragEnabled(True)
edit.move(30, 65)

button = Button("Button", self)
button.move(190, 65)

self.setWindowTitle('Simple drag & drop')
self.setGeometry(300, 300, 300, 150)


if __name__ == '__main__':

app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()

例子演示了一个简单的拖放操作.

class Button(QPushButton):

def __init__(self, title, parent):
super().__init__(title, parent)

self.setAcceptDrops(True)
为了拖放文本到QPushButton部件,我们必须重装一些方法.因此,我们创建自己的Button类,它是从QPushButton类继承下来的.

self.setAcceptDrops(True)
我们让部件允许拖放事件.

def dragEnterEvent(self, e):

if e.mimeData().hasFormat('text/plain'):
e.accept()
else:
e.ignore()
首先,我们重载dragEnterEvent()方法.我们告之我们所接受的数据类型.在这里是纯文本.

def dropEvent(self, e):

self.setText(e.mimeData().text())
通过重载dropEvent()方法,我们定义了拖放事件.因此我们可以改变按钮部件上的文本.

edit = QLineEdit('', self)
edit.setDragEnabled(True)
QLineEdit部件有一个内置的拖放操作.我们所需要做的就是调用setDragEnable()方法或激活它.

PyQt5初级教程--PyQt5中的拖放[10/13]

图片:一个简单的拖放

拖放一个按钮部件

在下面这个例子中,我们会演示如何拖放一个按钮部件.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial

In this program, we can press on a button with
a left mouse click or drag and drop the button
with the right mouse click.

author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QApplication
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag


class Button(QPushButton):

def __init__(self, title, parent):
super().__init__(title, parent)


def mouseMoveEvent(self, e):

if e.buttons() != Qt.RightButton:
return

mimeData = QMimeData()

drag = QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())

dropAction = drag.exec_(Qt.MoveAction)


def mousePressEvent(self, e):

QPushButton.mousePressEvent(self, e)

if e.button() == Qt.LeftButton:
print('press')


class Example(QWidget):

def __init__(self):
super().__init__()

self.initUI()


def initUI(self):

self.setAcceptDrops(True)

self.button = Button('Button', self)
self.button.move(100, 65)

self.setWindowTitle('Click or Move')
self.setGeometry(300, 300, 280, 150)


def dragEnterEvent(self, e):

e.accept()


def dropEvent(self, e):

position = e.pos()
self.button.move(position)

e.setDropAction(Qt.MoveAction)
e.accept()


if __name__ == '__main__':

app = QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()

在这个例子中,我们有一个QPushButton在窗口里.如果我们在它上面点击鼠标左键,那么会打印press信息到终端.如果在它上面点击右键并移动,那么我们就会拖放这个按钮部件.

class Button(QPushButton):

def __init__(self, title, parent):
super().__init__(title, parent)
我们创建一个Button类,它继承于QPushButton.我们还重载了两个它的方法:mouseMoveEvent()和mousePressEvent().其中mouseMoveEvent方法是为了拖放操作的.

if e.buttons() != Qt.RightButton:
return
在这里我们决定只有鼠标右键才可以执行拖放操作.左键保留给点击按钮的.

mimeData = QMimeData()

drag = QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
QDrag对象被创建,这个类提供了基于MIME的拖放数据转输.

dropAction = drag.exec_(Qt.MoveAction)
拖放对象的start()方法开始拖放操作.

def mousePressEvent(self, e):

QPushButton.mousePressEvent(self, e)

if e.button() == Qt.LeftButton:
print('press')
如果我们在按钮上点击左键,那么我们就打印press到终端.注意我们在这里也调用了父类的mousePressEvent()方法.否则,我们不会看碟到按钮被点击的.

position = e.pos()
self.button.move(position)
在dropEvent()方法里,我们的代码在我们释放鼠标按钮后完成拖放操作.我们会找到当前鼠标的位置并相应地移动按钮到那里.

e.setDropAction(Qt.MoveAction)
e.accept()

我们指定了拖放操作的类型.在这里是一个移动操作.