Python многопоточность и PySimpleGUI - PullRequest
1 голос
/ 17 марта 2020

- ПЕРЕСМОТРЕННОЕ РЕШЕНИЕ ОТ MikeyB -

Спасибо Mikey за указание на простое решение. Я чувствую, что иногда слишком много мыслей вкладывается в решение, и это простое решение, которое помогает решить проблему.

Я добавил небольшую функцию, которая просматривает мои каталоги, за которыми я хочу следить, и устанавливает для переменной значение True или False.

def file_check(working_pdf):
    if len(gb1(working_pdf, '*.pdf')) == 0:
        pdf_available = False

    if len(gb1(working_pdf, '*.pdf')) > 0:
        pdf_available = True

    return pdf_available

Затем вызывается в событии PySimple GUI l oop

    if files_available is True:
        for client in client_running_list:
            working_pdf, ext = folder_Func(client)
            pdf_available = file_check(working_pdf)
            if pdf_available is True:
                analyzer_queue.put(client)
                for x in range(10):
                    t = Thread(target=analyzer)
                    t.daemon = True
                    t.start()

- Исходное сообщение -

У меня есть программа, которая просматривает каталоги, определенные с помощью функции, и, если есть файлы, он анализирует эти файлы и затем перемещает данные в базу данных. Если в каталогах есть файлы при запуске программы, она запускается так, как задумано, но при добавлении нового файла функция не выполняется. Кажется, что бесконечный l oop не выполняется через каталог.

У меня есть пользовательский интерфейс через PySimple GUI, который использует «while True: l oop», поэтому я должен раскрутить функцию через поток. Я использую очередь и пытаюсь определить, где мне нужно «while True:» l oop, чтобы постоянно искать в папке новые файлы.

Ниже приведена часть кода (отступы ниже не являются правильными):

def analyzer():
while True:
    client = analyzer_queue.get()
    working_pdf, archive_path_datetime = folder_Func(client)
    while True:
        if len(gb1(working_pdf, '*.pdf')) == 0:
            break
        else:
            print(f'Found files in ', client, ' folder. Starting Parse.')
            ##########################################################
            # Start Parse of PDF's
            # Calls pdf parse function.
            # Arguments are Client Number, and PDF to parse.
            # Returns DF of items to insert into SQL Database
            ##########################################################
            ch(working_pdf)
            for pdf in gb1(working_pdf, "*.pdf"):
                items_found_df = pdf_parse(client, pdf)


            ##########################################################
            # Connect to SQL Server and insert items
            # Calls database connection function.
            ##########################################################
                azureDBengine = sqlalchemyConn()
                items_found_df.to_sql("MainData_Capture",azureDBengine,if_exists='append',method='multi',index=False)


            ##########################################################
            # Move file to Archive
            ##########################################################
                if not ospath.exists(archive_path_datetime):
                    osmakedirs(archive_path_datetime)
                    print("Created Archive Folder.")
                file_move(working_pdf, archive_path_datetime, pdf)
            print('All Files Processed.')
            analyzer_queue.task_done()
while True:
    event_dashboard, values_dashboard = dashboard_form.Read(timeout=1000)
    if dashboard_form is None or event_dashboard == 'Exit':
        dashboard_form.Close()
        break

    for client in active_client_list:
        client_start_button_action(client, event_dashboard, dashboard_form)
        client_stop_button_action(client, event_dashboard, dashboard_form)

    if event_dashboard == 'Start Analyze':
        dashboard_form.FindElement(f'Start Analyze').Update(disabled=True)
        dashboard_form.FindElement(f'Stop Analyze').Update(disabled=False)
        print('Analyzer Started')

        for client in client_running_list:
            analyzer_queue.put(client)
        for x in range(10):
            t = Thread(target=analyzer)
            t.daemon = True
            t.start()

    if event_dashboard == 'Stop Analyze':
        dashboard_form.FindElement(f'Stop Analyze').Update(disabled=True)
        dashboard_form.FindElement(f'Start Analyze').Update(disabled=False)
        print('Analyzer Stopped')
        analyzer_queue.empty()

1 Ответ

0 голосов
/ 18 марта 2020

Вы можете искать новые вещи, опрашивать аппаратные средства, делать любую проверку, которая не займет много времени в событии PySimple GUI l oop в вашем коде.

By добавив тайм-аут к вашему вызову чтения, ваше событие l oop будет периодически запускаться. Используйте это для периодической проверки ваших новых файлов. Это также тот же метод, который можно использовать для проверки входящих сообщений от потоков с использованием очереди.

while True:             # Event Loop
    event, values = window.read(timeout=500)        # returns every 500 ms
    if event in (None, 'Exit'):
        break
    if check_for_changes():
        do_something()       

Вы запускаете свою каждую секунду. Это должно быть хорошо для опроса новых файлов. Добавьте ваше while l oop в ваше событие l oop. Если он слишком длинный, закрутите его как поток и замените check_for_changes на check_for_message_from_threads.

...