当我启动程序时,它运行正常。但是当我按下倒计时按钮,然后尝试激活动作按钮时,它会冻结。
import wx
import time
class LeftPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
self.text = parent.GetParent().rightPanel.text
self.text_2 = parent.GetParent().rightPanel.text_2
button1 = wx.Button(self, -1, 'Count', (10, 10))
button2 = wx.Button(self, -1, 'Countdown', (10, 60))
button3 = wx.Button(self, -1, 'Action', (10, 110))
self.Bind(wx.EVT_BUTTON, self.OnPlus, id=button1.GetId())
self.Bind(wx.EVT_BUTTON, self.OnMinus, id=button2.GetId())
self.Bind(wx.EVT_BUTTON, self.button_Pressed, id=button3.GetId())
self.timed_Out = 1
def OnPlus(self, event):
value = 1
for t in range(5000):
value = value + 1
time.sleep(1)
self.text.SetLabel(str(value))
def OnMinus(self, event):
import math
value = 60
for t in range(value):
value = value - 1
time.sleep(1)
self.text.SetLabel(str(value/60) + ':' + str(value%60))
self.timed_Out = 0
self.text_2.SetLabel(str('End o\'line.'))
def button_Pressed(self, event):
if self.timed_Out == 1:
if self.text_2 == 'First':
self.text_2.SetLabel('Second')
elif self.text_2 == 'Second':
self.text_2.SetLabel('First')
class RightPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
self.text = wx.StaticText(self, -1, '0', (10,60))
self.text_2 = wx.StaticText(self,-1,'First',(10, 120))
class Communicate(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 200))
panel = wx.Panel(self, -1)
self.rightPanel = RightPanel(panel, -1)
leftPanel = LeftPanel(panel, -1)
hbox = wx.BoxSizer()
hbox.Add(leftPanel, 1, wx.EXPAND | wx.ALL, 4)
hbox.Add(self.rightPanel, 1, wx.EXPAND | wx.ALL, 5)
panel.SetSizer(hbox)
self.Centre()
self.Show(True)
app = wx.App()
Communicate(None, -1, 'widgets communicate')
app.MainLoop()
答案 0 :(得分:1)
那是因为你将time.sleep
调用放在按钮事件处理函数中。这将导致用户界面冻结。随着计数器标签的更新(它不适合我),它可能会在视觉上更新,但在事件处理程序完成之前,任何界面元素都不会起作用。
您需要做的是在一个单独的线程中运行计时器;然后,每一秒,向主窗口发送一个事件,告诉它更新其计数器。您可以使用wx.PostEvent
函数执行此操作。
或者,对于更简单和更好的解决方案,您可以使用为此目的而构建的wx.Timer
。 Here is a tutorial about it。您也可以将它用于重复事件,这是倒计时的情况。
有一个more generic tutorial about having long-running tasks activated by UI events;我正在使用此链接,因为我猜测Google上的人会在搜索他们的申请冻结的原因时寻找这个链接,而且可能不是因为计时器。