Pregunta

Hello I have one question,the timer is set to 1000 milliseconds and I want with the radio buttons to change that value.Above I have a sample code but I dont know exactly how to do it.Is it possible with wx.lib.pubsub to change the value of the timer? Can someone give me an example?

Here is the code:

import wx
import time

class SettingsFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,size=(100,200))
        self.CenterOnParent()
        self.SetBackgroundColour('#e4e4e4')

        self.radio1 = wx.RadioButton(self, label="1 sec",pos=(40,45))
        self.Bind(wx.EVT_RADIOBUTTON, self.SetLab1)

        self.radio2 = wx.RadioButton(self, label="5 sec",pos=(40,65))
        self.Bind(wx.EVT_RADIOBUTTON, self.SetLab2)

        self.radio3 = wx.RadioButton(self, label="10 sec",pos=(40,85))
        self.Bind(wx.EVT_RADIOBUTTON, self.SetLab3)

        extBtn = wx.Button(self, label="Exit",pos=(20,110))
        extBtn.Bind(wx.EVT_BUTTON, self.extFrame)

    def SetLab1(self,event):
        self.Show()
    def SetLab2(self,event):
        self.Show()
    def SetLab3(self,event):
        self.Show

    def extFrame(self,event):
        self.Close()

class MainPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent)
        self.frame = parent
        self.CenterOnParent()

        setBtn = wx.Button(self, label="Set",pos=(45,10))
        setBtn.Bind(wx.EVT_BUTTON, self.setFrame)

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)        
        self.redraw_timer.Start(milliseconds=1000)


        def setFrame(self, event):
            SettingsFrame().Show()

        def on_redraw_timer(self, event):
            print "Test: "+time.ctime()

class MainFrame(wx.Frame): 

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,size=(200,200))
        panel = MainPanel(self)
        self.CenterOnParent()

if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MainFrame()
    frame.Show()
    app.MainLoop()
¿Fue útil?

Solución 2

Non pubsub version

Add a change timer method to MainPanel that alters the timers start value

When creating SettingsFrame pass a ref of the MainPanel instance to it.

Store a ref to the parent on SettingsFrame.

Correct RadioButton 1 from

self.radio2

to

self.radio1.

Change the binds so they bind to the radio button itself like this

self.radio1.Bind(wx.EVT_RADIOBUTTON, self.SetLab1)

In the events handles call the parent change timer method with the new value

self.parent.change_timer(1000)

Here is the full code in case i may of missed one of the steps of the changes i made

import wx
import time


class SettingsFrame(wx.Frame):

    def __init__(self, parent):
        wx.Frame.__init__(self, None, wx.ID_ANY, size=(100, 200))
        self.parent = parent
        self.CenterOnParent()
        self.SetBackgroundColour('#e4e4e4')

        self.radio1 = wx.RadioButton(self, label="1 sec", pos=(40, 45))
        self.radio1.Bind(wx.EVT_RADIOBUTTON, self.SetLab1)

        self.radio2 = wx.RadioButton(self, label="5 sec", pos=(40, 65))
        self.radio2.Bind(wx.EVT_RADIOBUTTON, self.SetLab2)

        self.radio3 = wx.RadioButton(self, label="10 sec", pos=(40, 85))
        self.radio3.Bind(wx.EVT_RADIOBUTTON, self.SetLab3)

        extBtn = wx.Button(self, label="Exit", pos=(20, 110))
        extBtn.Bind(wx.EVT_BUTTON, self.extFrame)

    def SetLab1(self, event):
        self.parent.change_timer(1000)

    def SetLab2(self, event):
        self.parent.change_timer(5000)

    def SetLab3(self, event):
        self.parent.change_timer(10000)

    def extFrame(self, event):
        self.Close()


class MainPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent)
        self.frame = parent
        self.CenterOnParent()

        setBtn = wx.Button(self, label="Set", pos=(45, 10))
        setBtn.Bind(wx.EVT_BUTTON, self.setFrame)

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)
        self.redraw_timer.Start(milliseconds=1000)

    def setFrame(self, event):
        SettingsFrame(self).Show()

    def on_redraw_timer(self, event):
        print "Test: " + time.ctime()

    def change_timer(self, value):
        print 'Changing timer to:', value
        self.redraw_timer.Start(value)


class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, size=(200, 200))
        panel = MainPanel(self)
        self.CenterOnParent()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

Using a custom made event

Here another way of doing it using a custom made event sent from the SettingsFrame that the MainPanel can bind to.

import time

import wx
from wx.lib.newevent import NewCommandEvent


TimerChangeEvent, EVT_TIMER_CHANGE = NewCommandEvent()


class SettingsFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, size=(100, 200))
        self.CenterOnParent()
        self.SetBackgroundColour('#e4e4e4')

        self.radio1 = wx.RadioButton(self, label="1 sec", pos=(40, 45))
        self.radio1.Bind(wx.EVT_RADIOBUTTON, self.SetLab1)

        self.radio2 = wx.RadioButton(self, label="5 sec", pos=(40, 65))
        self.radio2.Bind(wx.EVT_RADIOBUTTON, self.SetLab2)

        self.radio3 = wx.RadioButton(self, label="10 sec", pos=(40, 85))
        self.radio3.Bind(wx.EVT_RADIOBUTTON, self.SetLab3)

        extBtn = wx.Button(self, label="Exit", pos=(20, 110))
        extBtn.Bind(wx.EVT_BUTTON, self.extFrame)

    def SetLab1(self, event):
        self.post_timer_change_event(1000)

    def SetLab2(self, event):
        self.post_timer_change_event(5000)

    def SetLab3(self, event):
        self.post_timer_change_event(10000)

    def post_timer_change_event(self, value):
        evt = TimerChangeEvent(self.Id, value=value)
        wx.PostEvent(self, evt)

    def extFrame(self, event):
        self.Close()


class MainPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent)
        self.frame = parent
        self.CenterOnParent()

        setBtn = wx.Button(self, label="Set", pos=(45, 10))
        setBtn.Bind(wx.EVT_BUTTON, self.setFrame)

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)
        self.redraw_timer.Start(milliseconds=1000)

    def setFrame(self, event):
        settings_frame = SettingsFrame()
        settings_frame.Show()
        settings_frame.Bind(EVT_TIMER_CHANGE, self.on_change_timer)

    def on_redraw_timer(self, event):
        print "Test: " + time.ctime()

    def on_change_timer(self, event):
        value = event.value
        print 'Changing timer to:', value
        self.redraw_timer.Start(value)


class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, size=(200, 200))
        panel = MainPanel(self)
        self.CenterOnParent()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

Otros consejos

There are lots of issues with your code. The first two radio buttons are bound to the same handler even though it's obvious they shouldn't be. SetLab3 isn't calling self.Show correctly, but then again, calling self.Show at all in ANY of these methods does not make sense. The wx.PySimpleApp construct is deprecated. You should be using wx.App now.

Now to actually answering the question itself. Yes, you can use pubsub for passing the information from the SettingFrame back to the MainPanel. Here is how to do it in wx 2.9 / newer pubsub:

import wx
import time

from wx.lib.pubsub import pub

class SettingsFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,size=(100,200))
        self.CenterOnParent()
        self.SetBackgroundColour('#e4e4e4')

        self.radio2 = wx.RadioButton(self, label="1 sec",pos=(40,45))
        self.Bind(wx.EVT_RADIOBUTTON, self.update_timer)

        self.radio2 = wx.RadioButton(self, label="5 sec",pos=(40,65))
        self.Bind(wx.EVT_RADIOBUTTON, self.update_timer)

        self.radio3 = wx.RadioButton(self, label="10 sec",pos=(40,85))
        self.Bind(wx.EVT_RADIOBUTTON, self.update_timer)

        extBtn = wx.Button(self, label="Exit",pos=(20,110))
        extBtn.Bind(wx.EVT_BUTTON, self.extFrame)

        self.choice = 1

    #----------------------------------------------------------------------
    def update_timer(self, event):
        """"""
        ctrl = event.GetEventObject()
        if ctrl.GetLabel() == "1 sec":
            self.choice = 1000
        elif ctrl.GetLabel() == "5 sec":
            self.choice = 5000
        elif ctrl.GetLabel() == "10 sec":
            self.choice = 10000

    def extFrame(self,event):
        pub.sendMessage("update_timer", message=self.choice)
        self.Close()

class MainPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent)
        self.frame = parent
        self.CenterOnParent()

        setBtn = wx.Button(self, label="Set",pos=(45,10))
        setBtn.Bind(wx.EVT_BUTTON, self.setFrame)

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)        
        self.redraw_timer.Start(milliseconds=1000)

        pub.subscribe(self.listener, "update_timer")

    def setFrame(self, event):
        SettingsFrame().Show()

    def on_redraw_timer(self, event):
        print "Test: "+time.ctime()

    def listener(self, message, arg2=None):
        self.redraw_timer.Stop()
        self.redraw_timer.Start(message)

class MainFrame(wx.Frame): 

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,size=(200,200))
        panel = MainPanel(self)
        self.CenterOnParent()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

Note that this example cleans up your code a bit too. You can read more about pubsub here:

You might also find this timer tutorial helpful:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top