文章目录
1 前言
扫地僧-smile 潜心打造保姆级知识点博客,从提出疑问到全面解决,仅看此文就够了。本博客汇聚以下优势。
-
问题相关知识齐全
-
解决问题逻辑清晰
-
所有演示代码均可用:无乱码,注释清晰,可复制,全部代码均自己开发,测试无误后上传。
2 看前准备
- 具备Python基础
- 具备PyQt5 GUI编程基础
- 具备面向对象基础,了解继承
- 已安装好pyqt5模块
- Python环境正常
3 我们的疑问是
- Pyqt5的控件如何实现拖放获取文件路径?
- 写出来的拖放代码如何融入自己的项目?
4 正式开始
本文以 QtWidgets.QLineEdit
类为示例展开讲解。
4.1 解决思路
4.1.1 新建类(继承于原始类)
-
为什么新建类?因为原始
QLineEdit
类在通常的情况下不具备拖放功能,或处理起来较为为麻烦。所以为了方便我们实现,我们需要继承QLineEdit
类,重写拖放功能,添加拖放获取文件路径功能,其余所有功能均不变。 -
新建
QLineEdit
类,命名为NewQLineEdit
,继承QtWidgets.QLineEdit
类。 重写QtWidgets.QLineEdit
中的dropEvent
和dragEnterEvent
方法,实现拖放获取文件路径的需求。# 该块儿仅为框架,不可直接拿走使用 class NewQLineEdit(QtWidgets.QLineEdit): # 新建类,命名为 `NewQLineEdit` def __init__(self, *args, **kwargs): # 继承父类构造函数 super().__init__(*args, **kwargs) self.setAcceptDrops(True) # 设置接受拖放动作 def dragEnterEvent(self, event): if event.mimeData().hasUrls(): # 当文件拖入此区域时为True event.accept() # 接受拖入文件 else: event.ignore() # 忽略拖入或关闭 def dropEvent(self, event): # 本方法为父类方法,本方法中的event为鼠标放事件对象 pass # 根据自己的业务需求,重写此方法,在4.2中讲解
4.1.2 融入项目
-
2.融入创建好的ui实例文件
- 更改前
# 该块儿仅为框架,不可直接拿走使用 # 此代码为Qtdesigner生成的ui转py文件 # 源码未动,效果图如下 class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(1043, 453) Form.setAcceptDrops(True) self.lineEdit = QtWidgets.QLineEdit(Form) self.lineEdit.setGeometry(QtCore.QRect(70, 230, 881, 41)) self.lineEdit.setAcceptDrops(True) self.lineEdit.setStyleSheet("font: 12pt \"Arial\";") self.lineEdit.setText("") self.lineEdit.setObjectName("lineEdit") self.label = QtWidgets.QLabel(Form) self.label.setGeometry(QtCore.QRect(430, 160, 311, 41)) self.label.setStyleSheet( "font: 12pt \"黑体\";\n" "font: 14pt \"微软雅黑\";" ) self.label.setObjectName("label") self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "扫地僧-smile"))
- 更改后
# 该块儿仅为框架,不可直接拿走使用 # 以下为更改后的代码 # 更改内容将 self.lineEdit = QtWidgets.QLineEdit(Form) 中的 QtWidgets.QLineEdit 更改为 NewQLineEdit class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(1043, 453) Form.setAcceptDrops(True) self.lineEdit = NewQLineEdit(Form) # 此处更改 self.lineEdit.setGeometry(QtCore.QRect(70, 230, 881, 41)) self.lineEdit.setAcceptDrops(True) self.lineEdit.setStyleSheet("font: 12pt \"Arial\";") self.lineEdit.setText("") self.lineEdit.setObjectName("lineEdit") self.label = QtWidgets.QLabel(Form) self.label.setGeometry(QtCore.QRect(430, 160, 311, 41)) self.label.setStyleSheet( "font: 12pt \"黑体\";\n" "font: 14pt \"微软雅黑\";" ) self.label.setObjectName("label") self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "扫地僧-smile"))
4.1.3 开发新项目
- 3.若没有预先开发的ui实例文件。后续开发,若需拖拽,直接使用
NewQLineEdit
类,其使用的方法与QLineEdit
完全一致。
4.2 重写方法
-
我的业务需求是,将文件拖入
LineEdit
放下时,此LineEdit
中能够显示文件的绝对路径。# 该块儿仅为框架,不可直接拿走使用 # 以下为重写的方法 class NewQLineEdit(QtWidgets.QLineEdit): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setAcceptDrops(True) # 删除没有影响,目前不确定(因为True和False测试结果一样) self.setDragEnabled(True) # 删除没有影响,(因为True和False测试结果一样) def dragEnterEvent(self, event): if event.mimeData().hasUrls(): # 当文件拖入此区域时为True event.accept() # 接受拖入文件 else: event.ignore() # 忽略拖入文件 def dropEvent(self, event): # 本方法为父类方法,本方法中的event为鼠标放事件对象 urls = [u for u in event.mimeData().urls()] # 范围文件路径的Qt内部类型对象列表,由于支持多个文件同时拖入所以使用列表存放 for url in urls: self.setText(url.path()[1:]) # 将Qt内部类型转换为字符串类型
5 案例演示
-
本案例共包含两个文件,一个入口文件
main.py
,一个UI文件MyWindow.py
,分别如下# main.py # 注入口文件不再注释,仅提供读者测试使用 import sys from PyQt5.QtWidgets import QApplication, QWidget from PyQt5.QtCore import QCoreApplication import os from MyWindow import * class Main: def __init__(self, ui, root): QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) self.__app = QApplication(sys.argv) self.__ui = ui() self.__root = root() def __close(self): os._exit(520) def __main(self): self.__app.setQuitOnLastWindowClosed(False) self.__app.lastWindowClosed.connect(self.__close) # 设置关闭程序 self.__ui.setupUi(self.__root) self.__root.show() sys.exit(self.__app.exec_()) def run(self): self.__main() if __name__ == '__main__': app = Main(Ui_Form, QWidget) app.run()
# MyWindow.py from PyQt5 import QtCore, QtGui, QtWidgets class NewQLineEdit(QtWidgets.QLineEdit): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setAcceptDrops(True) # 删除没有影响,目前不确定(因为True和False测试结果一样) self.setDragEnabled(True) # 删除没有影响,(因为True和False测试结果一样) def dragEnterEvent(self, event): if event.mimeData().hasUrls(): # 当文件拖入此区域时为True event.accept() # 接受拖入文件 else: event.ignore() # 忽略拖入文件 def dropEvent(self, event): # 本方法为父类方法,本方法中的event为鼠标放事件对象 urls = [u for u in event.mimeData().urls()] # 范围文件路径的Qt内部类型对象列表,由于支持多个文件同时拖入所以使用列表存放 for url in urls: self.setText(url.path()[1:]) # 将Qt内部类型转换为字符串类型 class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(1043, 453) Form.setAcceptDrops(True) self.lineEdit = NewQLineEdit(Form) # 此处更改 self.lineEdit.setGeometry(QtCore.QRect(70, 230, 881, 41)) self.lineEdit.setAcceptDrops(True) self.lineEdit.setStyleSheet("font: 12pt \"Arial\";") self.lineEdit.setText("") self.lineEdit.setObjectName("lineEdit") self.label = QtWidgets.QLabel(Form) self.label.setGeometry(QtCore.QRect(430, 160, 311, 41)) self.label.setStyleSheet( "font: 12pt \"黑体\";\n" "font: 14pt \"微软雅黑\";" ) self.label.setObjectName("label") self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "扫地僧-smile"))
6 谢谢大家观看,关注小编,持续更新
(郑重声明:本博文版权归扫地僧-smile所有,博文禁止转载!)
(关注博主,不定期更新博客,每一篇都是精品哦,满满干货!!!)