2020年3月8日 星期日

Python pyqt + logging 整合範例1

當有了圖形化介面的時候,發現工作列卡一個 cmd 實在想隱藏起來。
用 pythonw + .pyw,就能不卡 cmd。
但是一旦將 cmd 隱藏起來,就看不到輸出了甚麼。
logging可以將紀錄在輸出並同時保存下來,操作起來比 open() 還便捷。

GUI的操作功能得寫在一塊,格局被侷限了。
如果想整合更多的功能,而且是單獨寫過寫好的部分,或是打開音樂播放器聽音樂與執行某串程式碼等。
大夥都進來專案,會讓專案顯得異常混雜,也可能產生多個同名同功能但不同亞種的函式,搞得你混淆誰新誰舊。
此外,這些功能不需要傳入或只有固定參數,啟動後就能自動獨立運行完成。

那些其他程式運作情形,可以靠logging紀錄,不一定要回傳給主程式。
主程式透過查閱記錄,就能在GUI上觀察到程式進度。

然而可預期的錯誤能被處理,不可預期的錯誤會讓程式跳掉而無法用logging傳出ERROR以上的紀錄。
為了避免看不到錯誤訊息的憾事,得將錯誤訊息輸出保存下來以供來日查閱。

範例1:githubyoutube

展示以下功能:
1.透過整合logging,看見額外程式運行狀況。
2.能篩選紀錄,顯示一定level以上的紀錄。
3.有做錯誤處理且ERROR以上的紀錄,會跳出通知視窗。
4.萬一沒有做錯誤處理,會把錯誤訊息保存下來。

對於這個範例不是的某些部份若不是很瞭解,請找我最近寫了幾篇範例與文章。
我想唯有這個 cmd "python pyfile.py > output.txt 2>&1 "沒有講到。
簡單來說,把pyfile.py的結果標準輸出到output.txt,cmd上有甚麼,txt就大概會有甚麼。
但是沒有錯誤訊息,因為錯誤訊息不在標準輸出裡面。而 2>&1 意思是把錯誤輸出重定向到標準輸出,錯誤訊息才會輸出到output.txt。

程式敘述:

有一個介面,上面有一個清單會顯示過去10秒的紀錄,以及對應四個程式的四個按鈕,按下去會執行對應的程式,及其他按鈕等。

四個程式分別為ProgramA、ProgramB、ProgramC、ProgramD,都有整合logging,會把紀錄傳到主程式查閱的.log檔案。

ProgramA,有錯誤處理,而且有錯誤發生
ProgramB,有錯誤處理,但沒有錯誤發生
ProgramC,沒有錯誤處理,但有錯誤發生
ProgramD,無限循環。

執行這四個程式時,會在 ./error 生成一個 txt ,如果順利執行, txt 的大小會是0,然後被刪除掉。
ProgramA 與 ProgramB 順利執行完畢,而 ProgramC 會報錯,因此 ./error 會有記錄錯誤訊息的 ProgramC 的 txt。
而ProgramD,無限循環,觀察是否使用多核。會。



語:
花了好幾天,一點一滴摸索最終達到這個架構。

如果要做一個任務管理器,執行各種任務,自然得靠多線程,不然會看到主程式執行下去動彈不得就難堪。雖然多線程無法讓主程式使用多核,但用此例方法執行的程式,不會跟主程式擠在同一核,以往寫python需要引入多進程才能用到多核,這方法經測試過後,python程式會自動分配到其他核上。

關於logging的設定想了很久,雖然上一篇教學大開使用的自由度,但是卻沒有規劃一定的架構。從好幾種設定探索,並且探索其可能遇到的問題,最後把能想到的問題都有了解法。

這範例中各程式都引入同一個自訂Logging,這避免產生同名同功能的亞種,不論哪個專案,都是引入這個。之前我就遇到複製太多造成維護不易,更新了一個,還要手動複製貼上到其他的兄弟姊妹實在太費工。

這範例對我來說,就是改善過去不良的架構,為更好維護的架構打下基礎。