日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

wxPython多线程界面卡死或在不同平台崩溃问题

發布時間:2025/3/21 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 wxPython多线程界面卡死或在不同平台崩溃问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、測試程序界面

?

二、不使用多線程代碼如下(當點擊開啟日志的時候,直接導致界面卡死)

#coding:utf-8 import sys import threading import time import wxclass MyWindow():def __init__(self):self.app = Noneself.frame = Noneself.logObj = Noneself.main()def main(self):self.app = wx.App()self.frame = wx.Frame(None, -1, title='線程安全測試', size=wx.Size(1100, 700))self.createMainPanel()def show(self):self.frame.Show()self.app.MainLoop()def createMainPanel(self):mainPanel = wx.Panel(self.frame)startButton = wx.Button(mainPanel, label="啟動", pos=(5, 5))openLogButton = wx.Button(mainPanel, label="開啟日志", pos=(95, 5))closeLogButton = wx.Button(mainPanel, label="關閉日志", pos=(180, 5))self.logTextCtr = wx.TextCtrl(mainPanel, size=wx.Size(1000, 500), pos=(5,50),style=wx.TE_MULTILINE)self.frame.Bind(wx.EVT_BUTTON, lambda evt, textArea=self.logTextCtr: self.startBut(evt,self.logTextCtr),startButton)self.frame.Bind(wx.EVT_BUTTON, lambda evt: self.startLog(evt),openLogButton)self.frame.Bind(wx.EVT_BUTTON, lambda evt: self.closeLog(evt),closeLogButton)def startBut(self,evt,textArea):self.logObj = LogPrint(textArea)def startLog(self,evt):self.logObj.toPrint()def closeLog(self,evt):self.logObj.setIsPrint(0)class LogPrint():def __init__(self,textArea):self.isPrint = 0self.textArea = textAreadef toPrint(self):self.isPrint = 1i = 0while self.isPrint == 1:j = str(i) + " this is log!"self.textArea.WriteText(j + "\n")i = i + 1time.sleep(1)def setIsPrint(self,data):self.isPrint = dataif __name__ == "__main__":MyWindow().show()

三、使用threading多線程后,界面不會卡死,在windows下運行啟動后界面可正常操作不會阻塞;但是在linux或mac下面點擊開啟日志后程序直接崩潰,代碼如下:

#coding:utf-8 import sys import threading import time import wxclass MyWindow():def __init__(self):self.app = Noneself.frame = Noneself.logObj = Noneself.main()def main(self):self.app = wx.App()self.frame = wx.Frame(None, -1, title='線程安全測試', size=wx.Size(1100, 700))self.createMainPanel()def show(self):self.frame.Show()self.app.MainLoop()def createMainPanel(self):mainPanel = wx.Panel(self.frame)startButton = wx.Button(mainPanel, label="啟動", pos=(5, 5))openLogButton = wx.Button(mainPanel, label="開啟日志", pos=(95, 5))closeLogButton = wx.Button(mainPanel, label="關閉日志", pos=(180, 5))self.logTextCtr = wx.TextCtrl(mainPanel, size=wx.Size(1000, 500), pos=(5,50),style=wx.TE_MULTILINE)self.frame.Bind(wx.EVT_BUTTON, lambda evt, textArea=self.logTextCtr: self.startBut(evt,self.logTextCtr),startButton)self.frame.Bind(wx.EVT_BUTTON, lambda evt: self.startLog(evt),openLogButton)self.frame.Bind(wx.EVT_BUTTON, lambda evt: self.closeLog(evt),closeLogButton)def startBut(self,evt,textArea):self.logObj = LogPrint(textArea)def startLog(self,evt):threadObj = threading.Thread(target=self.dolog, args=())threadObj.start()#self.logObj.toPrint()def dolog(self):self.logObj.toPrint()def closeLog(self,evt):self.logObj.setIsPrint(0)class LogPrint():def __init__(self,textArea):self.isPrint = 0self.textArea = textAreadef toPrint(self):self.isPrint = 1i = 0while self.isPrint == 1:j = str(i) + " this is log!"self.textArea.WriteText(j + "\n")i = i + 1time.sleep(1)def setIsPrint(self,data):self.isPrint = dataif __name__ == "__main__":MyWindow().show()

四、解決卡死或不同平臺崩潰問題(使用wxpython中CallAfter自帶多線程,以及pubsub進行線程之間消息通訊來實現)

python3多線程threading功能強大,結合jion()和setDaemon()函數使用更靈活,使用多線程時首先想到了threading, 但wxpython是用python寫的一個UI框架,其本身自帶有多線程函數:

  • wx.PostEvent
  • wx.CallAfter
  • wx.CallLater

其中,wx.CallLater是最抽象的線程安全函數,其次是callAfter,最后是PostEvent。舍去這三個,直接使用threading導致UI出現卡頓,卡死等情況。結合wxpython自帶的多線程函數效果很好。

pubsub模塊中,pub.subscribe 可以理解為注冊一個接收消息的方法;pub.sendMessage 可以理解為發送消息給上一步注冊的方法

實現代碼:

#coding:utf-8import sys import threading import timeimport wx from wx.lib.pubsub import pubclass MyWindow():def __init__(self):self.app = Noneself.frame = Noneself.logObj = Noneself.main()def main(self):self.app = wx.App()self.frame = wx.Frame(None, -1, title='線程安全測試', size=wx.Size(1100, 700))self.createMainPanel()def show(self):self.frame.Show()self.app.MainLoop()def createMainPanel(self):mainPanel = wx.Panel(self.frame)startButton = wx.Button(mainPanel, label="啟動", pos=(5, 5))openLogButton = wx.Button(mainPanel, label="開啟日志", pos=(95, 5))closeLogButton = wx.Button(mainPanel, label="關閉日志", pos=(180, 5))self.logTextCtr = wx.TextCtrl(mainPanel, size=wx.Size(1000, 500), pos=(5,50),style=wx.TE_MULTILINE)self.frame.Bind(wx.EVT_BUTTON, lambda evt, textArea=self.logTextCtr: self.startBut(evt,self.logTextCtr),startButton)self.frame.Bind(wx.EVT_BUTTON, lambda evt: self.startLog(evt),openLogButton)self.frame.Bind(wx.EVT_BUTTON, lambda evt: self.closeLog(evt),closeLogButton)pub.subscribe(self.updateDisplay, "update")def startBut(self,evt,textArea):self.logObj = LogPrint()def startLog(self,evt):threadObj = threading.Thread(target=self.dolog, args=())threadObj.start()def dolog(self):self.logObj.toPrint()def updateDisplay(self, msg):t = msgself.logTextCtr.WriteText(t + "\n")def closeLog(self,evt):self.logObj.setIsPrint(0)class LogPrint():def __init__(self):self.isPrint = 0def toPrint(self):self.isPrint = 1i = 0while self.isPrint == 1:j = str(i) + " this is log!"wx.CallAfter(pub.sendMessage, "update", msg=j)print(j)i = i + 1time.sleep(1)def setIsPrint(self,data):self.isPrint = dataif __name__ == "__main__":MyWindow().show()

?

?

總結

以上是生活随笔為你收集整理的wxPython多线程界面卡死或在不同平台崩溃问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。