而循环是采取永远冻结屏幕?

2024-06-30 08:16:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大程序,其中一个部分包括单击按钮(这个GUI是用wxPython制作的)。基本上,按钮是一个计时器,当你点击它时,按钮的文本会根据剩余的时间进行切换,例如5秒、4秒、3秒。。。但是,由于某些原因,当我点击GUI中的按钮时,整个程序冻结,我不得不强制退出应用程序。(在我点击这个按钮之前,应用程序中的所有其他功能都很好,并且会做出响应)。下面是单击按钮时调用的事件处理程序。在

提前谢谢!在

    def TossUpTimer(self, event):
        while self.tossuptimer > -1:
            while self.tossuptimer > 0:
                self.tossupbutton.SetLabel(str(self.tossuptimer) + "Seconds")
                time.sleep(1)
                self.tossuptimer -= 1
            if self.tossuptimer == 0:
                self.tossupbutton.SetLabel("Time is Up!")
                time.sleep(1)
                self.tossupbutton.SetLabel(str(self.tossuptimer) + "Seconds")
        self.tossuptimer = 5

Tags: self程序应用程序timewxpythonguisleep按钮
1条回答
网友
1楼 · 发布于 2024-06-30 08:16:57

Why your GUI app freezes试图解释基本思想,以及处理它的所有不同选项。在

但这里有一个简短的版本:

GUI应用程序的全部意义在于它运行一个事件循环,对来自用户或操作系统的事件做出响应。为特定事件编写处理程序。在下一个事件处理程序之前,GUI不能返回。这意味着整个应用程序都被冻结了。在

您需要尽快从处理程序返回。你永远不能做的是time.sleep(1)或一个长的while循环或直接在处理程序中的任何类型的操作。在

有很多方法可以解决这个问题。两种最常见的方法是请求事件循环稍后运行某些代码,或者将其移到后台线程。(wx添加了第三种方法,SafeYield和朋友,这在某些情况下是合适的,但可能不是您在这里想要的。)


对于第一个替代方案,我们的想法是,不是围绕sleep循环,而是编写一个处理循环的单个迭代的函数,并安排一个计时器以每秒触发一次该函数。这被称为“把你的控制流从里到外”,这可能有点难以让你的头脑清醒过来。在

不幸的是,我不能百分之百地确定你要做什么,因为正如Jon Clements指出的,你的逻辑即使在顺序程序中也没有意义。但我要写一些简单的东西:当你点击按钮时,它会倒计时一次/秒,持续5秒,然后停止计数。在

def OnTossUpTimer(self, event):
    self.tossuptimer -= 1
    if self.tossuptimer > 0:
        self.tossupbutton.SetLabel(str(self.tossuptimer) + "Seconds")
    else:
        self.tossupbutton.SetLabel("Time is Up!")
        self.tossuptimer_timer.Stop()

def TossUpTimer(self, event):
    self.tossuptimer = 5
    self.tossupbutton.SetLabel(str(self.tossuptimer) + "Seconds")
    self.tossuptimer_timer = wx.Timer(self)
    self.Bind(wx.EVT_TIMER, self.OnTossUpTimer, self.tossuptimer_timer)
    self.tossuptimer_timer.Start(1000, False)

有关详细信息,请参见Using wx.Timers^{}文档。在


线程版本在某些方面更简单,在其他方面更复杂。您可以不使用序列逻辑,但除了通过调用PostEvent间接地与任何GUI小部件对话。所以:

^{pr2}$

如果你做了很多这样的事情,你可能想写更多通用的“on main thread”函数,而不是为每个函数编写所有这些样板文件。(事实上,您可以编写一个完整的泛型函数,wxPython确实应该附带该函数,但实际上没有。)

相关问题 更多 >