pyinstaller запускает дополнительный процесс с многопроцессорностью - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть приложение, которое ищет текст в PDF-документах. В полное приложение я включил многопроцессорный процесс, потому что чтение некоторых PDF-файлов может быть очень медленным, и у меня есть функция тайм-аута.

Этот процесс отлично работает при запуске в виде скрипта ('python main.py').

Я создаю исполняемый файл, используя pyinstaller на Windows.

Если я закомментирую строку:

document_text = self._get_pages_through_process(path)

это работает.

Однако, если я использую эту строку и закомментирую

document_text = self._get_pages(path), 

нажатие на кнопку «Найти» порождает вторую копию фрейма, и процесс не запускается.

Может кто-нибудь предложить решение?

    import wx
    import os
    import PyPDF4
    from multiprocessing import Process, Queue


    class SearchScreen(wx.Frame):
        def __init__(self, *args, **kwargs):
            super(SearchScreen, self).__init__(None, *args, **kwargs)
            self.Title = 'Text search'
            panel = MainPanel(self)
            sizer = wx.BoxSizer()
            sizer.Add(panel)
            self.SetSizerAndFit(sizer)
            self.Show()
            self.Center()

        def on_cmd_find_click(self, event):
            del event
            search = Search().search(path='.', search_text='anything')
            label = '{} documents found'.format(len(search))
            self.lbl_found.SetLabel(label)


    class MainPanel(wx.Panel):
        def __init__(self, parent, *args, **kwargs):
            super(MainPanel, self).__init__(parent, *args, **kwargs)

            cmd_find = wx.Button(self, id=wx.ID_FIND)
            cmd_find.Bind(wx.EVT_BUTTON, parent.on_cmd_find_click)
            parent.lbl_found = wx.StaticText(self, label='')

            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add((200, 0))
            sizer.Add(cmd_find, flag=wx.ALL, border=5)
            sizer.Add(parent.lbl_found, flag=wx.LEFT, border=5)
            self.SetSizer(sizer)


    class Search(object):
        def __init__(self):
            self.time_out = 5

        def search(self, path, search_text):
            documents_searched = 0
            documents_with_text = []
            self.document_paths = self._get_all_docs(path)
            for path in self.document_paths:
                #document_text = self._get_pages_through_process(path)
                document_text = self._get_pages(path)
                for page_text in document_text:
                    if search_text in page_text:
                        documents_with_text.append(path)
                        break
                documents_searched += 1
            return documents_with_text

        def _get_pages_through_process(self, path, pfd_output=None):
            document_text = []
            pfd_output = Queue()
            process = Process(target=self._get_pages, args=(path, pfd_output))
            process.start()
            process.join(self.time_out)
            if process.is_alive():
                document_text = pfd_output.get()
                process.terminate()
                if not document_text:
                    self.timed_out.append(path)
            else:
                document_text = pfd_output.get()
            return document_text

        def _get_pages(self, path, pfd_output=None):
            full_text = []
            doc = PyPDF4.PdfFileReader(path)
            pages = doc.getNumPages()
            for page_number in range(pages):
                page = doc.getPage(page_number)
                text = page.extractText()
                full_text.append(text)
            if pfd_output:
                pfd_output.put(full_text)
            return full_text

        def _get_all_docs(self, path):
            documents = []
            for root, dirs, files in os.walk(path):
                for file_name in files:
                    extension = os.path.splitext(file_name)[1]
                    if extension.replace('.', '') == 'pdf':
                        file_path = root + os.sep + file_name
                        documents.append(file_path)
            return documents


    if __name__ == '__main__':
        wx_app = wx.App()
        SearchScreen()
        wx_app.MainLoop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...