Как правильно использовать wx.CallLater в wx.Python - PullRequest
1 голос
/ 28 мая 2019

Я хочу зациклить и вызывать функцию каждые 1000 миллисекунд с помощью wx.CallLater. Я реализовал это (см. Ниже), но это не учитывает задержку - похоже, она выполняется автоматически. Как я могу заставить это ждать 1000 миллисекунд между вызовами функций?

Эта функция находится внутри класса. В моем основном модуле я создаю экземпляр объекта этого класса и вызываю функцию task_loop. Я намерен продолжать цикл до тех пор, пока для will_break не будет установлено значение True, а task_loop вернет work_session_agenda в главном модуле. Спасибо за вашу помощь!

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

    will_break = False
    will_continue = False

    duration -= datetime.timedelta(seconds=1)

Здесь больше кода - который в зависимости от условий устанавливает значения will_break и will_continue

    if will_break:
        print('BREAKING')
        return work_session_agenda
    else:
        print('GOT HERE')
        timer = wx.CallLater(1000, self.task_loop, duration, window, task, work_session_agenda, start, completed)

Ответы [ 2 ]

0 голосов
/ 28 мая 2019

Пример простого таймера

import wx
class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title,size=(350, 225))
        panel = wx.Panel(self)
        self.Text = wx.StaticText(panel,-1,"Tick")
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
        self.Bind(wx.EVT_CLOSE, self.onExit)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.Text, 0, wx.ALL, 10)
        panel.SetSizer(sizer)
        self.timer.Start(1000) # fire every second
        self.Show()

    def onTimer(self, event):
        if self.Text.GetLabel() == "Tick":
            self.Text.SetLabel("Tock")
        else:
            self.Text.SetLabel("Tick")

    def onExit(self, event):
        self.timer.Stop()
        self.Destroy()

if __name__ == '__main__':
    app = wx.App()
    MyFrame(None,"Tick Tock timer")
    app.MainLoop()
0 голосов
/ 28 мая 2019

Ниже вы можете найти пример с 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...