Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在wx.Python中正确使用wx.CallLater_Python_Loops_User Interface_Wxpython - Fatal编程技术网

如何在wx.Python中正确使用wx.CallLater

如何在wx.Python中正确使用wx.CallLater,python,loops,user-interface,wxpython,Python,Loops,User Interface,Wxpython,我想用wx.CallLater每隔1000毫秒循环调用一个函数。我实现了这一点(见下文),但它没有考虑延迟——它似乎是自动执行的。如何让函数调用之间等待1000毫秒 这个函数在一个类中。在我的主模块中,我实例化了这个类的一个对象,并调用task_循环函数。我打算一直保持循环,直到will_break设置为True,task_loop返回主模块中的work_session_议程。谢谢你的帮助 def task_loop(self, duration, window, task, work_sess

我想用wx.CallLater每隔1000毫秒循环调用一个函数。我实现了这一点(见下文),但它没有考虑延迟——它似乎是自动执行的。如何让函数调用之间等待1000毫秒

这个函数在一个类中。在我的主模块中,我实例化了这个类的一个对象,并调用task_循环函数。我打算一直保持循环,直到will_break设置为True,task_loop返回主模块中的work_session_议程。谢谢你的帮助

def task_loop(self, duration, window, task, work_session_agenda, start, completed):

    will_break = False
    will_continue = False

    duration -= datetime.timedelta(seconds=1)
这里有更多的代码-根据条件设置will\u break和will\u continue的值
下面您可以找到注释中建议的带有
wx.CallLater
wx.Timer
的示例。请注意,在这两种情况下,GUI在等待时间内保持响应

wx.Timer

import wx
import time

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="With wx.Timer", size=(500,500))

        #### Variables
        self.will_continue = True
        self.i = 0
        self.total = 5
        self.mili = 1000

        #### Widgets
        # Parent panel
        self.panel = wx.Panel(self)
        # Button
        self.button  = wx.Button(self.panel, label="Start", pos=(50, 50))
        self.button2 = wx.Button(self.panel, label="Button", pos=(50 ,100))

        #### Timer Notice that wx.Timer is own by the frame itself
        self.timer = wx.Timer(self)

        #### Bind
        self.button.Bind(wx.EVT_BUTTON, self.OnStart)
        self.Bind(wx.EVT_TIMER, self.OnCheck, self.timer)

    def OnStart(self, event):
        ## OnStart, disable the button and change its label and start the timer.
        ## Notice with Button that the GUI remain responsive
        ## while the timer runs
        if self.will_continue:
            print(self.i)
            print(time.ctime())
            self.button.SetLabel("Running")
            self.button.Disable()
            self.timer.Start(self.mili)
        ## When finish waiting reset everything so the start button can run 
        ## again and stop the timer
        else:
            self.timer.Stop()
            self.button.SetLabel("Start")
            self.button.Enable()
            self.will_continue = True
            self.i = 0            

    def OnCheck(self, event):
        self.i += 1 
        if self.i > self.total:
            self.will_continue = False
        else:
            pass
        self.OnStart(event)


# Run the program
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()
使用
wx.CallLater

import wx
import time

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="With wx.CallAfter", size=(500,500))

        #### Variables
        self.will_continue = True
        self.i = 0
        self.total = 5
        self.mili = 1000

        #### Widgets
        # Parent panel
        self.panel = wx.Panel(self)
        # Button
        self.button  = wx.Button(self.panel, label="Start", pos=(50, 50))
        self.button2 = wx.Button(self.panel, label="Button", pos=(50 ,100))

        #### Bind
        self.button.Bind(wx.EVT_BUTTON, self.OnStart)

    def OnStart(self, event):
        ## OnStart, disable the button and change its label and make the 
        ## wx.CallLater call. Notice with Button that the GUI remain responsive
        ## while wx.CallLater waits
        if self.will_continue:
            print(self.i)
            print(time.ctime())
            self.button.SetLabel("Running")
            self.button.Disable()
            wx.CallLater(self.mili, self.OnCheck, event)
        ## When finish waiting reset everything so the start button can run 
        ## again
        else:
            self.button.SetLabel("Start")
            self.button.Enable()
            self.will_continue = True
            self.i = 0            

    def OnCheck(self, event):
        self.i += 1 
        if self.i > self.total:
            self.will_continue = False
        else:
            pass
        self.OnStart(event)


# Run the program
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()

下面您可以找到注释中建议的带有
wx.CallLater
wx.Timer
的示例。请注意,在这两种情况下,GUI在等待时间内保持响应

wx.Timer

import wx
import time

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="With wx.Timer", size=(500,500))

        #### Variables
        self.will_continue = True
        self.i = 0
        self.total = 5
        self.mili = 1000

        #### Widgets
        # Parent panel
        self.panel = wx.Panel(self)
        # Button
        self.button  = wx.Button(self.panel, label="Start", pos=(50, 50))
        self.button2 = wx.Button(self.panel, label="Button", pos=(50 ,100))

        #### Timer Notice that wx.Timer is own by the frame itself
        self.timer = wx.Timer(self)

        #### Bind
        self.button.Bind(wx.EVT_BUTTON, self.OnStart)
        self.Bind(wx.EVT_TIMER, self.OnCheck, self.timer)

    def OnStart(self, event):
        ## OnStart, disable the button and change its label and start the timer.
        ## Notice with Button that the GUI remain responsive
        ## while the timer runs
        if self.will_continue:
            print(self.i)
            print(time.ctime())
            self.button.SetLabel("Running")
            self.button.Disable()
            self.timer.Start(self.mili)
        ## When finish waiting reset everything so the start button can run 
        ## again and stop the timer
        else:
            self.timer.Stop()
            self.button.SetLabel("Start")
            self.button.Enable()
            self.will_continue = True
            self.i = 0            

    def OnCheck(self, event):
        self.i += 1 
        if self.i > self.total:
            self.will_continue = False
        else:
            pass
        self.OnStart(event)


# Run the program
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()
使用
wx.CallLater

import wx
import time

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title="With wx.CallAfter", size=(500,500))

        #### Variables
        self.will_continue = True
        self.i = 0
        self.total = 5
        self.mili = 1000

        #### Widgets
        # Parent panel
        self.panel = wx.Panel(self)
        # Button
        self.button  = wx.Button(self.panel, label="Start", pos=(50, 50))
        self.button2 = wx.Button(self.panel, label="Button", pos=(50 ,100))

        #### Bind
        self.button.Bind(wx.EVT_BUTTON, self.OnStart)

    def OnStart(self, event):
        ## OnStart, disable the button and change its label and make the 
        ## wx.CallLater call. Notice with Button that the GUI remain responsive
        ## while wx.CallLater waits
        if self.will_continue:
            print(self.i)
            print(time.ctime())
            self.button.SetLabel("Running")
            self.button.Disable()
            wx.CallLater(self.mili, self.OnCheck, event)
        ## When finish waiting reset everything so the start button can run 
        ## again
        else:
            self.button.SetLabel("Start")
            self.button.Enable()
            self.will_continue = True
            self.i = 0            

    def OnCheck(self, event):
        self.i += 1 
        if self.i > self.total:
            self.will_continue = False
        else:
            pass
        self.OnStart(event)


# Run the program
if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    frame.Show()
    app.MainLoop()

使用支持以固定间隔发送事件的wx.Timer。感谢您的回复!我将如何着手实施这一点?我过去试过使用wx.Timer,但没有用。你说“它不考虑延迟”是什么意思?如果您使用的是
CallLater
方式,它将正确延迟1秒。@user2682863它不会延迟1秒。请使用支持以固定间隔发送事件的wx.Timer。感谢您的回复!我将如何着手实施这一点?我过去试过使用wx.Timer,但没有用。你说“它不考虑延迟”是什么意思?如果您使用的是
CallLater
,它将正确延迟1秒。@user2682863它不会延迟1秒。