PyQt5 拖放到系统文件资源管理器中(带有延迟编码)?

我想让用户通过将项目从 PyQt 拖到系统文件资源管理器来创建文件。由于某些文件非常大,我还需要延迟将数据设置为用户完成放置时,而不是立即开始拖动。

这个例子似乎是我需要的:https://doc.qt.io/archives/4.6/draganddrop-delayedencoding.html

我尝试将其转换为简单的 PyQt5 版本,其中将 QPushButton 拖动到文件夹中将创建一个纯文本文件,但它对我不起作用...当我运行它时,删除不会执行任何操作,我的光标如下所示:

https://img1.sycdn.imooc.com/652fd1ef0001fbe409880686.jpg

import sys

from PyQt5 import QtCore, QtGui, QtWidgets

import typing

import time



class MimeData(QtCore.QMimeData):

    dataRequested = QtCore.pyqtSignal(str)


    def formats(self) -> typing.List[str]:

        return QtCore.QMimeData.formats(self) + ["text/plain"]


    def retrieveData(self, mime_type: str, preferred_type: QtCore.QVariant.Type):

        self.dataRequested.emit(mime_type)

        return QtCore.QMimeData.retrieveData(self, mime_type, preferred_type)



class SourceWidget(QtWidgets.QWidget):

    mimeData: MimeData = None


    def __init__(self, parent=None):

        super().__init__(parent)


        layout = QtWidgets.QVBoxLayout()

        button = QtWidgets.QPushButton("Drag Me")

        button.pressed.connect(self.start_drag)


        layout.addWidget(button)

        self.setLayout(layout)


    @QtCore.pyqtSlot()

    def create_data(self, mime_type):

        if mime_type == "text/plain":

            time.sleep(0.25)  # Simulate large file

            self.mimeData.setData("text/plain", b"my text file contents")


    @QtCore.pyqtSlot()

    def start_drag(self):

        self.mimeData = MimeData()

        self.mimeData.dataRequested.connect(self.create_data)


        drag = QtGui.QDrag(self)

        drag.setMimeData(self.mimeData)

        drag.exec(QtCore.Qt.CopyAction)



if __name__ == "__main__":

    app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)


    w = SourceWidget()

    w.show()


    app.exec_()


青春有我
浏览 117回答 1
1回答

慕的地8271018

这是我最终将文件从 PyQt5 拖放到文件资源管理器中的结果,并且只有在释放鼠标以完成放置时才写入文件。import timefrom PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import Qtimport tempfileimport os# Use win32api on Windows because the pynput and mouse packages cause lag# https://github.com/moses-palmer/pynput/issues/390if os.name == 'nt':    import win32api    def mouse_pressed():        return win32api.GetKeyState(0x01) not in [0, 1]else:    import mouse    def mouse_pressed():        return mouse.is_pressed()class DelayedMimeData(QtCore.QMimeData):    def __init__(self):        super().__init__()        self.callbacks = []    def add_callback(self, callback):        self.callbacks.append(callback)    def retrieveData(self, mime_type: str, preferred_type: QtCore.QVariant.Type):        mp = mouse_pressed()        if not mp:            for callback in self.callbacks.copy():                self.callbacks.remove(callback)                callback()        return QtCore.QMimeData.retrieveData(self, mime_type, preferred_type)class Navigator(QtWidgets.QTreeWidget):    def __init__(self):        super().__init__()        self.setHeaderLabels(["Name"])        QtWidgets.QTreeWidgetItem(self, ['Test1'])        QtWidgets.QTreeWidgetItem(self, ['Test2'])        QtWidgets.QTreeWidgetItem(self, ['Test3'])        self.setAcceptDrops(True)        self.setDragEnabled(True)        self.setDragDropMode(self.DragDrop)        self.setDefaultDropAction(Qt.MoveAction)        self.setSelectionMode(self.ExtendedSelection)        self.setSelectionBehavior(self.SelectRows)        self.setContextMenuPolicy(Qt.CustomContextMenu)    def startDrag(self, actions):        drag = QtGui.QDrag(self)        names = [item.text(0) for item in self.selectedItems()]        mime = DelayedMimeData()        path_list = []        for name in names:            path = os.path.join(tempfile.gettempdir(), 'DragTest', name + '.txt')            os.makedirs(os.path.dirname(path), exist_ok=True)            print(path)            def write_to_file(path=path, name=name, widget=self):                with open(path, 'w+') as f:                    print("Writing large file(s)...")                    time.sleep(2)  # Sleep to simulate long file write                    f.write(f"Contents of {name}")            mime.add_callback(write_to_file)            path_list.append(QtCore.QUrl.fromLocalFile(path))        mime.setUrls(path_list)        mime.setData('application/x-qabstractitemmodeldatalist',                     self.mimeData(self.selectedItems()).data('application/x-qabstractitemmodeldatalist'))        drag.setMimeData(mime)        drag.exec_(Qt.MoveAction)        super().startDrag(actions)app = QtWidgets.QApplication([])nav = Navigator()nav.show()app.exec_()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python