PyQt5实现拖放功能


Posted in Python onApril 25, 2018

在这节教程中,我们将探讨PyQt5中的拖放操作。

在计算机图形用户界面(GUI)中,拖放是在某个虚拟对象上点击并拖动到另一个位置或虚拟对象上的操作。它通常用于调用多个动作,或为两个抽象对象创建某些联系。

拖放是图形用户界面的一部分。拖放可以使用户直观地完成某些复杂的操作。

通常我们可以对两种事物进行拖放操作:数据或某些图形对象。如果我们将某个应用中的图片拖放到另一个应用,我们拖放的是二进制数据。如果将Firefox的某个标签页拖放到其他地方,我们拖放的是一个图形组件。

简单的拖放

在第一个示例中我们要创建一个QLineEdit和一个QPushButton,并通过将LineEdit中的文本拖放到按钮上来改变按钮的标签。

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)
  self.show()


if __name__ == "__main__":
 app = QApplication(sys.argv)
 ex = Example()
 sys.exit(app.exec_())

这个示例演示了一个简单的拖放操作。

class Button(QPushButton):

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

  self.setAcceptDrops(True)

我们需要重新实现某些方法才能使QPushButton接受拖放操作。因此我们创建了继承自QPushButton的Button类。

self.setAcceptDrops(True)

使该控件接受drop(放下)事件。

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()方法,我们定义了在drop事件发生时的行为。这里我们改变了按钮的文字。

edit = QLineEdit('', self)
edit.setDragEnabled(True)

QLineEdit内置了对drag(拖动)操作的支持。我们只需要调用setDragEnabled()方法就可以了。

PyQt5实现拖放功能

PyQt5实现拖放功能

PyQt5实现拖放功能

拖放一个按钮

在下面的示例中我们将演示如何对一个按钮控件进行拖放。

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())

  dropAcion = 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)

我们从QPushButton派生了一个Button类,并重新实现了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)

Drag对象的exec_()方法用于启动拖放操作。

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()方法中,我们要为松开鼠标后的操作进行编码,并完成drop操作。即找出鼠标指针的当前位置,并将按钮移动过去。

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

我们定义了drop动作的类型。这里是move动作。

PyQt5实现拖放功能

PyQt5实现拖放功能

本节教程讲解了拖放操作。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之传说中的函数编写条规
Oct 11 Python
Python按行读取文件的实现方法【小文件和大文件读取】
Sep 19 Python
python利用Guetzli批量压缩图片
Mar 23 Python
深入理解Django中内置的用户认证
Oct 06 Python
python中 logging的使用详解
Oct 25 Python
python如何为被装饰的函数保留元数据
Mar 21 Python
详解配置Django的Celery异步之路踩坑
Nov 25 Python
Python中collections模块的基本使用教程
Dec 07 Python
Python中的相关分析correlation analysis的实现
Aug 29 Python
Python中读取文件名中的数字的实例详解
Dec 25 Python
python 递归相关知识总结
Mar 03 Python
Python 如何利用ffmpeg 处理视频素材
Nov 27 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
Apr 25 #Python
wxPython实现窗口用图片做背景
Apr 25 #Python
django 发送手机验证码的示例代码
Apr 25 #Python
python3+PyQt5实现自定义分数滑块部件
Apr 24 #Python
详解tensorflow载入数据的三种方式
Apr 24 #Python
关于Tensorflow中的tf.train.batch函数的使用
Apr 24 #Python
TensorFlow入门使用 tf.train.Saver()保存模型
Apr 24 #Python
You might like
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
FirePHP 推荐一款PHP调试工具
2011/04/23 PHP
php 操作调试的方法
2012/07/12 PHP
thinkphp3查询mssql数据库乱码解决方法分享
2014/02/11 PHP
解密ThinkPHP3.1.2版本之独立分组功能应用
2014/06/19 PHP
基于PHP实现的事件机制实例分析
2015/06/18 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
2015/07/03 PHP
第一次接触神奇的Bootstrap基础排版
2016/07/26 Javascript
AngularJS表单详解及示例代码
2016/08/17 Javascript
JS新包管理工具yarn和npm的对比与使用入门
2016/12/09 Javascript
vue proxyTable 接口跨域请求调试的示例
2017/09/12 Javascript
简述vue状态管理模式之vuex
2018/08/29 Javascript
微信小程序scroll-view横向滑动嵌套for循环的示例代码
2018/09/20 Javascript
Vue实现兄弟组件间的联动效果
2020/01/21 Javascript
VUE-ElementUI 自定义Loading图操作
2020/11/11 Javascript
17个Python小技巧分享
2015/01/23 Python
Python操作列表之List.insert()方法的使用
2015/05/20 Python
Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例
2017/08/18 Python
对python实时得到鼠标位置的示例讲解
2018/10/14 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
python画图——实现在图上标注上具体数值的方法
2019/07/08 Python
django项目简单调取百度翻译接口的方法
2019/08/06 Python
深入学习python多线程与GIL
2019/08/26 Python
Python 如何优雅的将数字转化为时间格式的方法
2019/09/26 Python
Python实现快速排序的方法详解
2019/10/25 Python
Pytorch 神经网络—自定义数据集上实现教程
2020/01/07 Python
Django跨域资源共享问题(推荐)
2020/03/09 Python
python实现遍历文件夹图片并重命名
2020/03/23 Python
屈臣氏泰国官网:Watsons TH
2021/02/23 全球购物
Python使用openpyxl复制整张sheet
2021/03/24 Python
八年级美术教学反思
2014/02/02 职场文书
供货协议书范本
2014/04/22 职场文书
新闻学专业职业生涯规划范文:我的人生我做主
2014/09/12 职场文书
《田忌赛马》教学反思
2016/02/19 职场文书
python中subplot大小的设置步骤
2021/06/28 Python
方法汇总:Python 安装第三方库常用
2022/04/26 Python