日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

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

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

一、測試程序界面

?

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

#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="關(guān)閉日志", 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="關(guān)閉日志", 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進行線程之間消息通訊來實現(xiàn))

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

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

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

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

實現(xiàn)代碼:

#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="關(guān)閉日志", 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()

?

?

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。