我在Windows 7,64位,MSYS2 Mingw64殼(殼開始命令是C:\msys64\msys2_shell.cmd -use-full-path -mingw64
)測試;這裏我已經通過pacman
安裝:mingw-w64-x86_64-python2-2.7.13-1
,mingw-w64-x86_64-wxWidgets-3.0.2-17
和mingw-w64-x86_64-wxPython-3.0.2.0-6
。在MSYS2中的wxPython:線程處理程序中的SetLabel導致凍結?
考慮這個代碼,其中只有一個標題標籤,按鈕和目標標籤;點擊按鈕時,標籤應改變從「X」爲「1」:
import wx #, wx.html
import sys, os
from threading import Thread
# disable buffering (Windows)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)
class Frame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.label = wx.StaticText(self, wx.ID_ANY, "Click the button to change label below: ")
self.bt_main = wx.Button(self, label="Click ME")
self.bt_main.Bind(wx.EVT_BUTTON, self.BtnClickHandler)
self.label2 = wx.StaticText(self, wx.ID_ANY, "XX")
sizer_vmain_app = wx.BoxSizer(wx.VERTICAL)
sizer_vmain_app.Add(self.label, proportion=0, flag=wx.EXPAND, border=0)
sizer_vmain_app.Add(self.bt_main, proportion=0, flag=0, border=0)
sizer_vmain_app.Add(self.label2, proportion=0, flag=0, border=0)
self.SetSizer(sizer_vmain_app)
self.Layout()
def BtnClickHandler(self, event):
testThread = Thread(target=self.DoBtnClick)
testThread.start()
testThread.join()
def DoBtnClick(self):
print("BtnClickHandler ")
myval = int("1")
self.label2.SetLabel(str(myval))
if __name__ == "__main__":
app = wx.PySimpleApp(0)
wx.InitAllImageHandlers()
app_frame = Frame(None, wx.ID_ANY, "")
app.SetTopWindow(app_frame)
app_frame.Show()
app.MainLoop()
當我爲這段代碼運行,那麼當它涉及到self.label2.SetLabel(str(myval))
申請凍結。
但是,如果我避免了線程,並使用此功能來代替:
def BtnClickHandler(self, event):
# testThread = Thread(target=self.DoBtnClick)
# testThread.start()
# testThread.join()
self.DoBtnClick()
......然後一切工作正常。請注意,我通過在MSYS2 Mingw64 shell中運行python test.py
來調用此腳本。
那麼,是不是可以用線程在Windows上運行此代碼,如果是這樣,怎麼樣? (否則,在Linux下使用線程運行它沒有問題)
你看過wxpython演示嗎? – Igor
謝謝@Igor - 不,我沒有,它有什麼不同?這對我有何幫助? – sdaau
對不起我的壞。請參閱下面的答案。 – Igor