在大型目录上遍历iglob迭代器时,PyQt5 GUI崩溃

时间:2016-06-02 12:35:15

标签: python file user-interface pyqt5

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import os
from os import scandir, walk
from time import sleep
from glob import iglob, glob

class FileRead(QWidget):
    def __init__(self, parent=None):
        super(FileRead, self).__init__(parent)

        self.resize(600, 400)

        self.layout = QVBoxLayout()

        self.loader = QProgressDialog("File read progress", "stop showing progress", 0, 100)
        self.layout.addWidget(self.loader)

        self.curfile = QLabel("CURRENT FILE")
        self.layout.addWidget(self.curfile)

        self.dirs = QLabel("DIRECTORY LISTING")
        self.layout.addWidget(self.dirs)

        self.btn = QPushButton("read files")
        self.btn.clicked.connect(self.wrapper)
        self.layout.addWidget(self.btn)

        self.setLayout(self.layout)
        self.filenames = []

    def wrapper(self):
        self.file_names('.')

这个方法:process_subdir,是造成最多问题的原因。

    def process_subdir(self, path, toplevel=True):
        txts = iglob(path + "/**/*.txt", recursive=True)
        for t in txts:
            print(t)  

    def file_names(self, start_path = '.'):
        dirs = glob(start_path + '/*/')
        d_len = len(dirs)

        files = glob(start_path + '/*.txt')
        f_len = len(files)

        total_len = d_len + f_len

        toplevel = [(d.split('\\'))[1] for d in dirs]
        # setting the text to empty for now
        self.dirs.setText("\n".join(toplevel))

        ctr = 0

        for f in files:
            ctr += 1
            if (f.endswith('.txt')):
                self.filenames.append(f)
                self.curfile.setText(f)
                self.loader.setValue(((ctr)/total_len)*100)
            sleep(1)

        for idx, d in enumerate(dirs):
            ctr += 1

            write_str = ""
            for n_idx, n_d in enumerate(dirs):
                n_d = (n_d.split('\\'))[1]
                if (n_idx < idx):
                    write_str += n_d + "(done)\n"
                elif (n_idx == idx):
                    write_str += n_d + "(in progress)\n"
                else:
                    write_str += n_d + "\n"
            self.dirs.setText(write_str)
            self.loader.setValue(((ctr)/total_len)*100)
            self.process_subdir(d)
            sleep(1)

        write_str = ""
        for d in dirs:
            d = (d.split('\\'))[1]
            write_str += d + "(done)\n"
        self.dirs.setText(write_str)

        print(self.filenames)

if __name__ == '__main__':
    ...

我在这个程序中尝试做的是读取某个目录中的所有文件并检查它们的文件扩展名。对于此部分代码,它正在检查.txt个文件。我用于此的方法是允许用户单击按钮,并扫描硬编码(现在)目录中的文本文件。它适用于较小的目录,并且不会崩溃,但是当我尝试运行程序并解析较大的目录时,GUI往往会崩溃。我还注意到的一点是,当我在较小的目录上运行程序时,我无法再与GUI交互。有办法吗? a)在解析大目录时防止GUI崩溃? b)即使文件解析正在进行,也允许GUI仍然可以进行交互?

1 个答案:

答案 0 :(得分:0)

我使用的解决方案是使用QThreads而不是为dir中的每个d运行for循环。这样就不会阻止GUI事件循环,它看起来不像GUI崩溃。此外,该程序整体运行速度更快。