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

发布于 2025-01-01 09:08:10 字数 2307 浏览 0 评论 0原文

当我启动该程序时,它运行良好。但是,当我按下倒计时按钮,然后尝试激活操作按钮时,它冻结了。

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

When I start the program, it runs fine. But when I press the Countdown Button, and then attempt to activate the Action Button, it freezes.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瀞厅☆埖开 2025-01-08 09:08:10

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

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

或者,为了获得更简单、更好的解决方案,您可以使用为此目的构建的wx.Timer这里有一个关于它的教程。您也可以使用它来重复事件,这就是倒计时的情况。

有一个关于通过 UI 事件激活长时间运行的任务的更通用教程;我放置此链接是因为我猜测 Google 上的人们在搜索应用程序冻结原因时会寻找此链接,而且可能不是因为计时器。

That's because you are putting time.sleep calls in the button event handler function. This will cause the user interface to freeze. It may get visually updated as the counter label gets updated (it doesn't for me) but no interface elements will work until the event handler finishes.

What you need to do is to run the timer in a separate thread; then, each second, send an event to the main window to tell it to update its counter. You can do that with the wx.PostEvent function.

Or, for a simpler and better solution, you can use wx.Timer built for this very purpose. Here is a tutorial about it. You can use it for repeating events too, which is the case for this countdown.

There is a more generic tutorial about having long-running tasks activated by UI events; I am putting this link because I am guessing people on Google will be looking for this when they search for why their application is freezing, and it will probably not be because of a timer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文