Concurrency Pyqt5与concurrent.futures模块的并发文件操作

Concurrency Pyqt5与concurrent.futures模块的并发文件操作,concurrency,pyqt,Concurrency,Pyqt,我目前正在运行一个基于Pyqt5的python Gui开发。有很多与文件系统相关的操作,如复制、移动和删除。我试图通过使用concurrent.futures模块来提高这些操作的性能,并在Threadpoolexecutor和Processpoolexecutor上进行了实验。但是,他们都不能给我一个解锁gui,在我将文件操作提交到池中后,它可以继续与用户交互。这些提交的操作只是本地python类的静态方法。我还通过提交返回的未来对象添加了回调,这些对象是一个qt类的实例方法,并且在相应提交的作

我目前正在运行一个基于Pyqt5的python Gui开发。有很多与文件系统相关的操作,如复制、移动和删除。我试图通过使用concurrent.futures模块来提高这些操作的性能,并在Threadpoolexecutor和Processpoolexecutor上进行了实验。但是,他们都不能给我一个解锁gui,在我将文件操作提交到池中后,它可以继续与用户交互。这些提交的操作只是本地python类的静态方法。我还通过提交返回的未来对象添加了回调,这些对象是一个qt类的实例方法,并且在相应提交的作业完成时被调用。 只是想不出一个方法来解决冻结用户界面的问题(即使只有几秒钟的时间),有人能帮忙吗

from concurrent.futures import ProcessPoolExecutor

class ArchiveResManager:
    def __init__(self, resource_dir):
        self._path_reference_dir = resource_dir

def get_resource_list(self):
    return tuple(
        de.path for de in os.scandir(self._path_reference_dir) if de.is_file()
        )

def add_callback_resource_added(fn):
    self._callback_on_resource_added = fn

def add_resources(self, resources: iter):
    src_paths = tuple(p for p in resources)
    dest_paths = tuple(self._get_dest_path(p) for p in resources)
    with ProcessPoolExecutor(2) as executor:
        exe.submit(
            ArchiveResManager._do_resource_operations,
            src_paths,
            dest_paths
        ).add_done_callback(self._on_resource_added)

@staticmethod
def _do_resource_operations(src_paths, dest_paths):
    added_items = list()
    for src_path, dest_path in zip(src_paths, dest_paths):
        shutil.copyfile(
            src_path, dest_path
        )
        added_items.append(dest_path)
    return added_items

def _on_resource_added(self, future):
    if future.done():
        if self._callback_on_resource_added:
            self._callback_on_resource_added(future.result())

# This model class is bound to a instance of QListView in the QDialog of my project
class ArchiveModel(QAbstractListModel):

def __init__(self, archive_dir, parent):
    super().__init__(parent)
    self._archive_manager = ArchiveResManager(archive_dir)
    self._archive_manager.add_callback_resource_added(self._on_archive_operations_completed)
    self._archive_items = self._archive_manager.get_resource_list()

def _on_archive_operations_completed(self, result_list):
    last_row = self.rowCount() - 1
    self.beginInsertRows(QModelIndex(), last_row, last_row + len(result_list))
    self._archive_items.extend(result_list)
    self.endInsetRows()

我只是用我的项目中的片段编辑了这个问题。我承认我没有完全遵循SO的规则,但构建一个最小的、完整的和可验证的示例本身也可能有助于我理解这个问题。谢谢你关于使用信号的建议和提示。