一文讲清Python PyQt5的QLineEdit控件如何实现拖放获取文件路径

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中的 dropEventdragEnterEvent方法,实现拖放获取文件路径的需求。

    # 该块儿仅为框架,不可直接拿走使用
    
    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所有,博文禁止转载!)

(关注博主,不定期更新博客,每一篇都是精品哦,满满干货!!!)

  • 16
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值