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