0

I'm converting an old tkinter program to wxPython. One of the things from tk that I used liberally was tk.IntVar() and the like. Is there anything in wx that provides similar functionality?

Specifically, I'd like to be able to define module-level variables such as myvar = tk.StringVar(). Then when those variables are updated, have one or more UI elements update based on the new variable value just like what would happen with:

self.score = tk.Entry(self, textvariable=myvar.get())
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
dthor
  • 1,749
  • 1
  • 18
  • 45
  • no theres not ... but its not necessary ... just treat your widget like your stringvar or whatever `my_text.SetValue("asdasdad")` – Joran Beasley Oct 29 '14 at 17:07
  • Ok, but if the widget is deep within a frame/panel hierarchy, won't the namespace stuff be a pain? Like `MainFrame.Panel1.Panel2.SubPanel.my_text.SetValue("asasdasd")`? – dthor Oct 29 '14 at 17:16
  • Though I guess I can set `my_subpanel = MainFrame.Panel1.Panel2.SubPanel` and then do `my_subpanel.my_text.SetValue("asasdasd")` – dthor Oct 29 '14 at 17:18
  • no thats not usually how you do it ... (although it would work) – Joran Beasley Oct 29 '14 at 17:20

1 Answers1

2

here is how you would normally organize your app .... globals tend to be a bad idea

class MyNestedPanel(wx.Panel):
     def __init__(self,*a,**kw):
         ...
         self.user = wx.TextCtrl(self,-1)
      def SetUser(self,username):
         self.user.SetValue(username)

class MyMainPanel(wx.Panel):
      def __init__(self,*a,**kw):
          ...
          self.userpanel = MyNestedPanel(self,...)
      def SetUsername(self,username):
           self.userpanel.SetUser(username)

class MainFrame(wx.Frame):
      def __init__(self,*a,**kw):
           ...
           self.mainpanel = MyMainPanel(self,...)
      def SetUsername(self,username):
           self.mainpanel.SetUsername(username)

a = wx.App()
f = MainFrame(...)
f.Show()
a.MainLoop()

although you can make helper functions

def set_widget_value(widget,value):
    if hasattr(widget,"SetWidgetValue"):
        return widget.SetWidgetValue(value) 
    if isinstance(widget,wx.Choice):
       return widget.SetStringSelection(value)
    if hasattr(widget,"SetValue"):
        return widget.SetValue(value)
    if hasattr(widget,"SetLabel"):
        return widget.SetLabel(value)
    else:
       raise Exception("Unknown Widget Type : %r"%widget)

def get_widget_value(widget):
     if hasattr(widget,"GetWidgetValue"):
        return widget.GetWidgetValue() 
     if isinstance(widget,wx.Choice):
        return widget.GetStringSelection()
     if hasattr(widget,"GetValue"):
        return widget.GetValue()
     if hasattr(widget,"GetLabel"):
        return  widget.GetLabel()
     else:
       raise Exception("Unknown Widget Type : %r"%widget)

class WidgetManager(wx.Panel):
      def __init__(self,parent):
         self._parent = parent
         wx.Panel.__init__(self,parent,-1)
         self.CreateWidgets()
      def CreateWidgets(self):
         #create all your widgets here
         self.widgets = {}
      def SetWidgetValue(self,value):
         if isinstance(value,dict):
            for k,v in value.items():
               set_widget_value(self.widgets.get(k),v)
         else:
            raise Exception("Expected a dictionary but got %r"%value)
      def GetWidgetValue(self):
          return dict([(k,get_widget_value(v))for k,v in self.widgets])

and then use them like this https://gist.github.com/joranbeasley/37becd81ff2285fcc933

Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • Thanks, that seems to be close to what I want. However, after additional research, I've decided to go with a Publisher/Subscriber design pattern (specifically from PyPubSub http://pubsub.sourceforge.net/ - they have examples specifically for wx, so it was easy). – dthor Oct 30 '14 at 19:06