pysimplegui之使用多線程,避免程序卡死


這個問題我也遇到過,就是還需要一個while循環的時候,放到gui本身循環會卡死,這時候就需要啟動多線程

 

 

需要“長時間”的操作

如果您是 Windows 用戶,您會在其標題欄中看到窗口顯示“未響應”,然后很快會出現一個 Windows 彈出窗口,指出“您的程序已停止響應”。好吧,如果您願意,您也可以使該消息和彈出窗口出現!您需要做的就是在您的事件循環中執行一個花費“太長”(即幾秒鍾)的操作。

你有幾個選擇來處理這個問題。如果您的操作可以分解成更小的部分,那么您可以Window.Refresh()偶爾調用以避免出現此消息。例如,如果您正在運行一個循環,請將該調用與您的其他工作一起放入。這將使 GUI 保持快樂,Window 不會抱怨。

另一方面,如果您的操作不受您的控制,或者您無法添加Refresh調用,那么您可以使用的下一個選項是將您的長操作移動到一個線程中。

“老路”

有幾個演示程序可供您查看如何執行此操作。你基本上把你的工作放到一個線程中。當線程完成時,它通過隊列發送消息來告訴 GUI。事件循環將運行一個計時器,該計時器設置為一個值,該值表示您希望您的 GUI 對工作完成的“響應”程度。

“新方式”—— Window.write_event_value

這個截至 2020 年 7 月目前僅在 tkinter 端口中可用的新功能令人興奮,它代表了在 PySimpleGUI 中處理多線程的未來方式(或者希望如此)。

以前,使用隊列,您的事件循環將輪詢來自線程的傳入消息。

現在,線程可以直接將事件注入到 Window 中,以便它顯示在window.read()調用中。這允許您的事件循環“掛起”,等待正常的窗口事件以及線程生成的事件。

您可以在此演示中看到此新功能的實際效果:Demo_Multithreaded_Write_Event_Value.py

這是您的檢查和教育計划。不再輪詢線程事件真是太好了。

import threading import time import PySimpleGUI as sg """ Threaded Demo - Uses Window.write_event_value communications Requires PySimpleGUI.py version 4.25.0 and later This is a really important demo to understand if you're going to be using multithreading in PySimpleGUI. Older mechanisms for multi-threading in PySimpleGUI relied on polling of a queue. The management of a communications queue is now performed internally to PySimpleGUI. The importance of using the new window.write_event_value call cannot be emphasized enough. It will hav a HUGE impact, in a positive way, on your code to move to this mechanism as your code will simply "pend" waiting for an event rather than polling. Copyright 2020 PySimpleGUI.org """ THREAD_EVENT = '-THREAD-' cp = sg.cprint def the_thread(window): """ The thread that communicates with the application through the window's events. Once a second wakes and sends a new event and associated value to the window """ i = 0 while True: time.sleep(1) window.write_event_value('-THREAD-', (threading.current_thread().name, i)) # Data sent is a tuple of thread name and counter cp('This is cheating from the thread', c='white on green') i += 1 def main(): """ The demo will display in the multiline info about the event and values dictionary as it is being returned from window.read() Every time "Start" is clicked a new thread is started Try clicking "Dummy" to see that the window is active while the thread stuff is happening in the background """ layout = [ [sg.Text('Output Area - cprint\'s route to here', font='Any 15')], [sg.Multiline(size=(65,20), key='-ML-', autoscroll=True, reroute_stdout=True, write_only=True, reroute_cprint=True)], [sg.T('Input so you can see data in your dictionary')], [sg.Input(key='-IN-', size=(30,1))], [sg.B('Start A Thread'), sg.B('Dummy'), sg.Button('Exit')] ] window = sg.Window('Window Title', layout, finalize=True) while True: # Event Loop event, values = window.read() cp(event, values) if event == sg.WIN_CLOSED or event == 'Exit': break if event.startswith('Start'): threading.Thread(target=the_thread, args=(window,), daemon=True).start() if event == THREAD_EVENT: cp(f'Data from the thread ', colors='white on purple', end='') cp(f'{values[THREAD_EVENT]}', colors='white on red') window.close() if __name__ == '__main__': main() 

多線程程序

在討論多線程主題時,准備了另一個演示,展示了如何在程序中運行多個線程,這些線程都與事件循環通信,以便在 GUI 窗口中顯示某些內容。回想一下,對於 PySimpleGUI(至少是 tkinter 端口),您不能在主程序線程以外的線程中進行 PySimpleGUI 調用。

這些線程程序的關鍵是從線程到事件循環的通信。為這些演示選擇的機制使用 Python 內置queue模塊。事件循環輪詢這些隊列以查看是否從要顯示的線程之一發送了某些內容。

您會發現顯示多個線程與單個 GUI 通信的演示被稱為:

Demo_Multithreaded_Queued.py

對於普通的 PySimpleGUI(基於 tkinter)再次發出警告- 您的 GUI 絕不能作為除主程序線程之外的任何東西運行,並且沒有線程可以直接調用 PySimpleGUI 調用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM