iT邦幫忙

0

Python視窗程式在運行中會出現卡頓無回應狀況該如何解決

  • 分享至 

  • xImage

近期剛學習有關PYQT5的應用,在實作上面碰到問題,想請教各位大神
提問1:
當我執行時,程式會運行cmd相關建置活動,期間會將過程輸出至textBrowser上,每當我點選textBrowser的UI要查看過程時,容易出現卡頓、無回應狀況,需等待才會恢復正常,想請教如何解決卡頓無回應的狀況
提問2:
在編程時,是依據功能能否使用就一直疊加上去,因此對於程式上的流程,是否是合理還是有誤需要調整,想請大神指點
https://ithelp.ithome.com.tw/upload/images/20230712/20123746OoHmflsHTF.png
https://ithelp.ithome.com.tw/upload/images/20230712/20123746CHvNuPHneT.png
https://ithelp.ithome.com.tw/upload/images/20230712/20123746BgiT3WitnY.png

-------0713更新-------
改寫成QProcess後,卡頓問題還是存在

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2023-07-12 09:51:58 檢舉
https://blog.51cto.com/xfxuezhang/5857239
https://www.pythonguis.com/tutorials/qprocess-external-programs/

用 QProcess,不要用subprocess,要不然主要視窗(mainWindow)會需要等你subprocess拿到結果後才能結束堵塞
win895564 iT邦新手 1 級 ‧ 2023-07-12 09:56:06 檢舉
pyqt的物件都是循環處理的所以你執行外部程式或非qt的程序
會導致會先處理你的外部程式,這時候qt程序會處於你說的無回應的狀態
建議你可以將cmd加入到threading
這樣可以在執行cmd的時候還能檢視textBrowser的資訊
gt55123 iT邦新手 5 級 ‧ 2023-07-12 10:42:54 檢舉
想確認一下,我程式上流程是合理的嗎?
目前是把print_stdout放置在Job(QThread)下,是否應該放置在主程式下,而不是子進程下
gt55123 iT邦新手 5 級 ‧ 2023-07-12 10:46:18 檢舉
@win895564 對於上述所說的cmd加入到threading,是指將整個子進程Subprocess/Qprocess都放進threading.Thread?
gt55123 iT邦新手 5 級 ‧ 2023-07-12 10:52:17 檢舉
@froce 好的感謝,我試著改寫運行看看
froce iT邦大師 1 級 ‧ 2023-07-12 10:55:09 檢舉
你用thread就不用QProcess了,QProcess基本上就是包裝好的thread
gt55123 iT邦新手 5 級 ‧ 2023-07-12 11:07:35 檢舉
@froce 請問是QProcess跟threading包Subprocess兩者擇一就行?
froce iT邦大師 1 級 ‧ 2023-07-12 11:19:52 檢舉
對,擇一就好。QProcess比較簡單。
gt55123 iT邦新手 5 級 ‧ 2023-07-12 11:23:42 檢舉
@force 好的感謝大神建議 我試試看
gt55123 iT邦新手 5 級 ‧ 2023-07-13 09:10:02 檢舉
對於改寫成QProcess 後,在運行時操作UI查看進程時,還是會出現卡頓狀況,是正常嗎?
class Job(QThread):
...
def run(self):
try:
self.task_process = QProcess()
self.task_process.setProcessChannelMode(QProcess.MergedChannels)
self.task_process.readyReadStandardOutput.connect(self.process_output)
self.task_process.started.connect(self.task_started.emit)
self.task_process.finished.connect(self.task_finished.emit)
self.task_process.start('cmd.exe, ['/c', self.job_cmd])
self.task_process.waitForFinished(-1)
except Exception as e:
logging.exception(f"[run]{e}")
finally:
self.task_process.close()

def process_output(self):
if self.task_process.state() == QProcess.Running:
output = self.task_process.readAllStandardOutput().data().decode()
self.task_msg.emit(f"{str(output)}")
if 'fail' in output:
self.task_fail_result.emit()
elif 'pass' in output:
self.task_pass_result.emit()
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答