This article explains how the QLineEdit control of Python PyQt5 implements drag and drop to obtain the file path

1 Introduction

​Sweeping Monk-smile devotes himself to building a nanny-level knowledge point blog, from raising questions to comprehensive solutions, just reading this article is enough. This blog brings together the following advantages .

  • Complete knowledge about the problem

  • Logical problem solving

  • All demo codes are available : no garbled characters, clear comments, reproducible, all codes are self-developed, and uploaded after the test is correct.

2 Prepare before watching

  • Have the basics of Python
  • Possess PyQt5 GUI programming foundation
  • Have an object-oriented foundation and understand inheritance
  • The pyqt5 module has been installed
  • Python environment is normal

3 Our question is

  • How does the control of Pyqt5 implement drag and drop to obtain the file path ?
  • How can the drag-and-drop code written be integrated into your own project?

4 official start

This article uses QtWidgets.QLineEditthe class as an example to explain.

4.1 Solutions
4.1.1 Create a new class (inherited from the original class)
  • Why create a new class? Because the original QLineEditclass does not have the drag-and-drop function under normal circumstances, or it is more troublesome to handle . So in order to facilitate our implementation, we need to inherit QLineEditthe class , rewrite the drag and drop function , and add the function of drag and drop to obtain the file path, and all other functions remain unchanged.

  • Create a new QLineEditclass , name it NewQLineEdit, inherit from QtWidgets.QLineEditthe class . Override the and methods inQtWidgets.QLineEdit the file to achieve the requirement of dragging and dropping to obtain the file path .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 Integration into the project
  • 2. Integrate into the created ui instance file

    • before change
    # 该块儿仅为框架,不可直接拿走使用
    # 此代码为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"))
    

    insert image description here

    • after change
    # 该块儿仅为框架,不可直接拿走使用
    # 以下为更改后的代码
    # 更改内容将 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 Develop new projects
  • 3. If there is no pre-developed ui instance file. For subsequent development, if you need to drag and drop, use NewQLineEditthe class , and the method used is QLineEditexactly the same as that of .
4.2 Override method
  • My business requirement is that when a file is dragged and LineEditdropped , LineEditthe absolute path of the file can be displayed here.

    # 该块儿仅为框架,不可直接拿走使用
    # 以下为重写的方法
    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 case presentation

  • This case contains two files, one entry file main.pyand one UI file MyWindow.py, which are as follows

    # 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"))
    

insert image description here

6 Thank you for watching, follow the editor, and continue to update

(Solemnly declare: The copyright of this blog post belongs to Sweeping Monk-smile , and reprinting of the blog post is prohibited!)

(Follow the blogger, update the blog from time to time, every article is a boutique, full of dry goods!!!)

Guess you like

Origin blog.csdn.net/z132533/article/details/125939667