为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

青春有我 2023-10-18 16:39:53
我想让用户通过将项目从 PyQt 拖到系统文件资源管理器来创建文件。由于某些文件非常大,我还需要延迟将数据设置为用户完成放置时,而不是立即开始拖动。这个例子似乎是我需要的:https://doc.qt.io/archives/4.6/draganddrop-delayedencoding.html我尝试将其转换为简单的 PyQt5 版本,其中将 QPushButton 拖动到文件夹中将创建一个纯文本文件,但它对我不起作用...当我运行它时,删除不会执行任何操作,我的光标如下所示:import sysfrom PyQt5 import QtCore, QtGui, QtWidgetsimport typingimport timeclass 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_()
查看完整描述

1 回答

?
慕的地8271018

TA贡献1796条经验 获得超4个赞

这是我最终将文件从 PyQt5 拖放到文件资源管理器中的结果,并且只有在释放鼠标以完成放置时才写入文件。



import time


from PyQt5 import QtCore, QtGui, QtWidgets

from PyQt5.QtCore import Qt


import tempfile

import os


# Use win32api on Windows because the pynput and mouse packages cause lag

# https://github.com/moses-palmer/pynput/issues/390

if 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_()


查看完整回答
反对 回复 2023-10-18
  • 1 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信