我的wxPython小部件在激活另一个函数后冻结了我的程序

时间:2012-02-02 01:31:16

标签: wxpython

当我启动程序时,它运行正常。但是当我按下倒计时按钮,然后尝试激活动作按钮时,它会冻结。

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()

1 个答案:

答案 0 :(得分:1)

那是因为你将time.sleep调用放在按钮事件处理函数中。这将导致用户界面冻结。随着计数器标签的更新(它不适合我),它可能会在视觉上更新,但在事件处理程序完成之前,任何界面元素都不会起作用。

您需要做的是在一个单独的线程中运行计时器;然后,每一秒,向主窗口发送一个事件,告诉它更新其计数器。您可以使用wx.PostEvent函数执行此操作。

或者,对于更简单和更好的解决方案,您可以使用为此目的而构建的wx.TimerHere is a tutorial about it。您也可以将它用于重复事件,这是倒计时的情况。

有一个more generic tutorial about having long-running tasks activated by UI events;我正在使用此链接,因为我猜测Google上的人会在搜索他们的申请冻结的原因时寻找这个链接,而且可能不是因为计时器。