Article directory
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.QLineEdit
the 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
QLineEdit
class 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 inheritQLineEdit
the 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
QLineEdit
class , name itNewQLineEdit
, inherit fromQtWidgets.QLineEdit
the class . Override the and methods inQtWidgets.QLineEdit
the file to achieve the requirement of dragging and dropping to obtain the file path .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 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"))
- 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
NewQLineEdit
the class , and the method used isQLineEdit
exactly the same as that of .
4.2 Override method
-
My business requirement is that when a file is dragged and
LineEdit
dropped ,LineEdit
the 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.py
and one UI fileMyWindow.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"))
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!!!)