Wxpython passing data from one frame to another - python

I have a text control, a choice control, and a button on one from. I would like to pass the values of both the text control and the choice control to another frame when button is pressed. In the on_press method in the code below, I returned both values as a list. How can I access this list in PanelTwo. Here's the code:
import wx
class PanelOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
box = wx.BoxSizer(wx.VERTICAL)
self.label = wx.StaticText(self,label = "Your Name:" ,style = wx.ALIGN_CENTRE)
box.Add(self.label, 1 , wx.EXPAND |wx.ALIGN_CENTER_HORIZONTAL |wx.ALL, 20)
self.inputTxtOne = wx.TextCtrl(self,wx.ID_ANY,value='')
box.Add(self.inputTxtOne, 1 , wx.EXPAND |wx.ALIGN_CENTER_HORIZONTAL |wx.ALL, 20)
languages = ['ZIRA', 'DAVID']
chlbl = wx.StaticText(self,label = "Voice control",style = wx.ALIGN_CENTRE)
box.Add(chlbl,1,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
self.choice = wx.Choice(self,choices = languages)
box.Add(self.choice,1,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
btn = wx.Button(self, label='Submit',style=wx.TRANSPARENT_WINDOW)
btn.SetFont(wx.Font(15,wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL))
btn.Bind(wx.EVT_BUTTON, self.on_press)
box.Add(btn,1,wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL,5)
self.SetSizer(box)
btn.Bind(wx.EVT_BUTTON, self.on_press)
def on_press(self,event):
name = self.inputTxtOne.GetValue()
voice_choice = self.choice.GetValue()
nv_list = [name,voice_choice]
parent_frame = self.GetParent()
parent_frame.Close()
frame = FrameTwo()
frame.Show()
return nv_list
class PanelTwo(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
box = wx.BoxSizer(wx.VERTICAL)
self.label = wx.StaticText(self,label = "Your Name is "+name ,style = wx.ALIGN_CENTRE)
box.Add(self.label, 1 , wx.EXPAND |wx.ALIGN_CENTER_HORIZONTAL |wx.ALL, 20)
self.SetSizer(box)
class FrameOne(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="First Frame")
panel = PanelOne(self)
self.Show()
class FrameTwo(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Second Frame")
panel = PanelTwo(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = FrameOne()
app.MainLoop()

There are several errors in your code. Let's go step by step.
First of all, the variable called "name" in PanelOne, must be part of the class instead of a local variable of the "on_press" method:
Change:
name = self.inputTxtOne.GetValue()
voice_choice = self.choice.GetValue()
by:
# Notice the use of self. In this way, we can access it from anywhere in the class
self.name = self.inputTxtOne.GetValue()
# What version of wx are you using? Get the choices value with GetSelection() method.
voice_choice = self.choice.GetSelection()
Now we need to access this variable from another class (PanelTwo). For this, we will pass an instance of the PanelOne class to the second frame (Frame2) and we will store it as a member variable (with the use of self, as we saw in the previous example).
# When you instantiate the Frame2 in PanelOne must pass the self instance of PanelOne
frame = FrameTwo(self)
Then in init method in Frame2:
def __init__(self, parent):
wx.Frame.__init__(self, None, title="Second Frame")
#Now the reference to PanelOne is a member varialble of class Frame2.
self.panelOne = parent
#Pass Frame2 instance (self) to PanelTwo in constructor:
panel = PanelTwo(self)
# Rest of your code...
Finally in PanelTwo:
class PanelTwo(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self)
# parent is Frame2.
# panelOne is a public and member variable of Frame2 that references to PanelOne instance.
# name is a member and accesible variable of PanelOne.
print(parent.panelOne.name)
A recommendation: use WxGlade for make best code. With it you can learn a lot about how things are done in wxpython.
Good luck!

Related

Why can't you call object attributes within __init__?

I'm trying to understand why you can call an object's attribute within a class' method, but not within it's constructor. For example:
class Panel1(wx.Panel):
#include Frame in the constructor
def __init__(self, parent, frame):
wx.Panel.__init__(self, parent)
#set up so objects assigned in Frame (and it's children) can be called
self.frame = frame
button = wx.Button(self, label='Test')
#button.Bind(wx.EVT_BUTTON, lambda event: self.onButton(event))
button.Bind(wx.EVT_BUTTON, self.onButton)
pprint(vars(self.frame))
def onButton(self, event):
print("Button pressed.")
pprint(vars(self.frame))
#the following fails in the constructor as panel2 for some reason is not callable
a = self.frame.panel2.a
print("123: " + str(a))
Could someone point me to a link that explains why this isn't possible in the constructor?
Thanks!
*****EDIT****
Below is functional code to help explain my question better. If you try to call Panel2 attributes via the parent within Panel1's constructor, it fails. But it works fine when done inside Panel1's onButton method. I'd like to understand why.
import wx
from pprint import pprint
class Panel1(wx.Panel):
#include Frame in the constructor
def __init__(self, parent, frame):
wx.Panel.__init__(self, parent)
self.frame = frame
self.strPanel1 = "Panel1 string"
self.intPanel1 = 0
button = wx.Button(self, label='Test')
button.Bind(wx.EVT_BUTTON, self.onButton)
self.textbox = wx.TextCtrl(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
sizer.Add(self.textbox, 0, wx.ALL, 5)
sizer.Add(button, 0, wx.ALL, 5)
#pprint self.frame attributes fail here
def onButton(self, event):
#but not here!?!
print("Panel1 button pressed.")
pprint(vars(self.frame))
Panel2str = self.frame.panel2.strPanel2
print(Panel2str)
Panel2int = self.frame.panel2.intPanel2
print(str(Panel2int))
#Panel2 button press counter
self.frame.panel2.intPanel2 += 1
self.frame.panel2.trigger()
def trigger(self):
print("Panel1 has been triggered")
class Panel2(wx.Panel):
#include Frame in the constructor
def __init__(self, parent, frame):
wx.Panel.__init__(self, parent)
self.frame = frame
self.strPanel2 = "Panel2 string"
self.intPanel2 = 0
button = wx.Button(self, label='Test')
button.Bind(wx.EVT_BUTTON, self.onButton)
self.textbox = wx.TextCtrl(self)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
sizer.Add(self.textbox, 0, wx.ALL, 5)
sizer.Add(button, 0, wx.ALL, 5)
#pprint self.frame attributes fail here
def onButton(self, event):
#but not here!?!
print("Panel2 button pressed.")
pprint(vars(self.frame))
Panel1str = self.frame.panel1.strPanel1
print(Panel1str)
Panel1int = self.frame.panel1.intPanel1
print(str(Panel1int))
#Panel1 button press counter
self.frame.panel1.intPanel1 += 1
self.frame.panel1.trigger()
def trigger(self):
print("Panel2 has been triggered")
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="My Frame")
#Spliiting the frame
splitter = wx.SplitterWindow(self)
#Send frame to children
self.panel1 = Panel1(splitter, self)
self.panel2 = Panel2(splitter, self)
splitter.SplitVertically(self.panel1, self.panel2, 0)
splitter.SetMinimumPaneSize(200)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(splitter, 1, wx.EXPAND)
self.SetSizer(sizer)
if __name__ == '__main__':
app = wx.App()
frame = Frame()
frame.Show()
frame.Centre()
app.MainLoop()
Below is functional code to help explain my question better. If you try to call Panel2 attributes via the parent within Panel1's constructor, it fails.
It fails, because at the time your Panel1.__init__ is called, frame.panel2 is not set yet. Look at your Frame class:
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="My Frame")
#Spliiting the frame
splitter = wx.SplitterWindow(self)
#Send frame to children
self.panel1 = Panel1(splitter, self)
self.panel2 = Panel2(splitter, self)
...
When your Panel1 is initialized, panel2 is not set yet. It will only be set once Panel1 is done initializing and has been assigned to frame.panel1. If you absolutely need to access panel2 into Panel1.__init__, then you could make it so that your Panel1 take care of it. For example:
class Panel1:
def __init__(self, frame):
# Initialize panel2 and assign it to our frame
frame.panel2 = Panel2(frame)
# Now we can do whatever with panel2
frame.panel2
class Panel2:
def __init__(self, frame):
pass
class Frame:
def __init__(self):
# This initialize panel1, and internally initialize panel2
self.panel1 = Panel1(self)
frame = Frame()

wx.Frame error when calling one script from another

The following is a bit of copied code from another question, it works fine as a standalone app, but the pop-up right-click menu references frame_1 which is not available if "if name == 'main':" is false, as it is when the program is called by another. What should this reference be changed to?
Thanks.
import wx
import sys
sys.path.append("..")
from ObjectListView import ObjectListView, ColumnDefn
### 2. Launcher creates wxMenu. ###
menu_titles = [ "Open",
"Properties",
"Rename",
"Delete" ]
menu_title_by_id = {}
for title in menu_titles:
menu_title_by_id[ wx.NewId() ] = title
class Track(object):
"""
Simple minded object that represents a song in a music library
"""
def __init__(self, title, artist, album):
self.title = title
self.artist = artist
self.album = album
def GetTracks():
"""
Return a collection of tracks
"""
return [
Track("Sweet Lullaby", "Deep Forest", "Deep Forest"),
Track("Losing My Religion", "U2", "Out of Time"),
Track("En el Pais de la Libertad", "Leon Gieco", "Leon Gieco"),
]
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.Init()
def Init(self):
self.InitModel()
self.InitWidgets()
self.InitObjectListView()
def InitModel(self):
self.songs = GetTracks()
def InitWidgets(self):
panel = wx.Panel(self, -1)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(panel, 1, wx.ALL | wx.EXPAND)
self.SetSizer(sizer_1)
self.myOlv = ObjectListView(panel, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_2.Add(self.myOlv, 1, wx.ALL | wx.EXPAND, 4)
panel.SetSizer(sizer_2)
self.Layout()
def InitObjectListView(self):
self.myOlv.SetColumns([
ColumnDefn("Title", "left", 120, "title"),
ColumnDefn("Artist", "left", 100, "artist"),
ColumnDefn("Album", "left", 100, "album")
])
self.myOlv.SetObjects(self.songs)
self.myOlv.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.RightClick)
def RightClick(self, event):
# record what was clicked
self.list_item_clicked = self.myOlv.GetSelectedObject()
menu = wx.Menu()
menu.Bind(wx.EVT_MENU, self.MenuSelectionCb)
for (id_, title) in menu_title_by_id.items():
### 3. Launcher packs menu with Append. ###
menu.Append(id_, title)
### 5. Launcher displays menu with call to PopupMenu, invoked on the source component, passing event's GetPoint. ###
# self.frame.PopupMenu( menu, event.GetPoint() )
frame_1.PopupMenu(menu, event.GetPoint())
menu.Destroy() # destroy to avoid mem leak
def MenuSelectionCb(self, event):
# do something
operation = menu_title_by_id[ event.GetId() ]
target = self.list_item_clicked.title
print 'Perform "%(operation)s" on "%(target)s."' % vars()
class MyPopupMenu(wx.Menu):
def __init__(self, parent):
super(MyPopupMenu, self).__init__()
self.parent = parent
mmi = wx.MenuItem(self, wx.NewId(), 'Minimize')
self.AppendItem(mmi)
self.Bind(wx.EVT_MENU, self.OnMinimize, mmi)
cmi = wx.MenuItem(self, wx.NewId(), 'Close')
self.AppendItem(cmi)
self.Bind(wx.EVT_MENU, self.OnClose, cmi)
def OnMinimize(self, e):
self.parent.Iconize()
def OnClose(self, e):
self.parent.Close()
if __name__ == '__main__':
app = wx.App(True)
wx.InitAllImageHandlers()
frame_1 = MyFrame(None, -1, "ObjectListView Track Test")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()
If you are going to import your code into another module, then you will just need to instantiate that frame in your new main application's code. Let's save your code as olv_tracks.py. Now import it like I do in the following code:
import wx
import olv_tracks
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title='Main App')
panel = wx.Panel(self)
self.Show()
# show other frame
frame = olv_tracks.MyFrame(None, -1, "ObjectListView Track Test")
frame.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Now you just instantiate the frame the same way you did in your code.
Also, you need to change the reference to frame_1 in your RightClick method to self. So instead of frame_1.PopupMenu(menu, event.GetPoint()), it should be self.PopupMenu(menu, event.GetPoint())

Custom event listeners for wxpython widgets

as in the title, is it possible to add a custom event listener for wx widget and if so, how? More particularly I am trying to add one which listens to the changes of SelStart and SelEnd attributes of wx.Slider.
Thanks!
Below is the code for custom listener for wx.slider, I am calling it inside other listener's handler.
You can call this customize listener from the point where SelStart and SelEnd changing.
import wx
import wx.lib.newevent
DialogRespondEvent, EVT_DIALOG_RESPOND_EVENT = wx.lib.newevent.NewEvent()
class Mywin(wx.Frame):
def __init__(self, parent, title):
super(Mywin, self).__init__(parent, title = title,size = (250,150))
self.InitUI()
def InitUI(self):
pnl = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.Bind(EVT_DIALOG_RESPOND_EVENT, self.testing)
self.sld = wx.Slider(pnl, value = 10, minValue = 1, maxValue = 100,
style = wx.SL_HORIZONTAL|wx.SL_LABELS)
vbox.Add(self.sld,1,flag = wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border = 20)
self.sld.Bind(wx.EVT_SLIDER, self.OnSliderScroll)
self.txt = wx.StaticText(pnl, label = 'Hello',style = wx.ALIGN_CENTER)
vbox.Add(self.txt,1,wx.ALIGN_CENTRE_HORIZONTAL)
pnl.SetSizer(vbox)
self.Centre()
self.Show(True)
def testing(self,evt):
print "you can do whatever you want here"
def OnSliderScroll(self, e):
obj = e.GetEventObject()
val = obj.GetValue()
font = self.GetFont()
font.SetPointSize(self.sld.GetValue())
self.txt.SetFont(font)
evt = DialogRespondEvent()
wx.PostEvent(self, evt)
ex = wx.App()
Mywin(None,'Slider demo')
ex.MainLoop()

How to link multiple wx.Dialogs in wxPython

I want to make a game in wxPython (no other modules) and I want to make it so that you can enter some values in popup screens before the game starts, and then the game will be drawn on a canvas which in turn is drawn on a panel, which is bound to the main game.
I made the gamescreen with all fancy stuff (works solo)
I made the input screens
But I cannot link them.
How do I start the game so it will open a dialog box, then on the closure of it open another one, and then open the game ?
I tried the following, but it will not open my canvas:
# makes a game by showing 2 dialogs
# after dialogs have been answered, starts the game by drawing the canvas.
# imports
import wx
import Speelveld3
# globals
SCRWIDTH = 950
SCRHEIGHT = 700
# dialogbox class
class MyDialog1(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent)
self.username = wx.TextCtrl(self)
self.okButton = wx.Button(self, wx.ID_OK, "OK")
class MyDialog2(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent)
self.canvasWidth = wx.TextCtrl(self)
self.okButton = wx.Button(self, wx.ID_OK, "OK")
# main class
class Game(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, title='My game', size=(SCRWIDTH, SCRHEIGHT))
self.username = ""
self.canvasWidth = 10
# hide the frame for now
self.Hide()
def OnInit(self):
#Make your dialogs
dlg1 = MyDialog1(self)
#if the user pressed "OK" (i.e. NOT "Cancel" or any other button you might add)
if dlg1.ShowModal() == wx.ID_OK:
#get the username from the dialog
self.username = dlg1.username.GetValue()
#clean up the dialog (AFTER you get the username)
dlg1.Destroy()
dlg2 = MyDialog2(self)
#if the user pressed "OK" (i.e. NOT "Cancel" or any other button you might add)
if dlg2.ShowModal() == wx.ID_OK:
#get the username from the dialog
self.canvasWidth = dlg2.canvasWidth.GetValue()
#clean up the dialog (AFTER you get the username)
dlg2.Destroy()
# Now that you have your settings, Make the gameboard
# THIS PART IS STILL BROKEN!
# I can paste the whole board class (structure of it is taken from the tetris tutorial)
# but that seems a bit much tbh...
self.gameBoard = Board.Board(self)
self.gameBoard = SetFocus()
self.gameBoard.start()
self.Centre()
self.Show(True) #show the frame
if __name__ == '__main__':
# how can I start the game here?
app = wx.App()
frame = Game()
board = Speelveld3.Speelveld(frame)
board.start()
frame.Show()
app.MainLoop()
You've double posted, and the lack of any wx.Dialog in your sample code suggests to me that you haven't even looked at a tutorial yet, but I will give you the benefit of the doubt.
First, if you want to return information from a dialog, the easiest way is to define a custom dialog. Define a new class that inherits from wx.Dialog and then set it up just like you would a normal panel or a frame. It seems to me that you will need two of these. They'll look something like this:
class MyDialog1(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self, parent)
self.username = wx.TextCtrl(self) #this is where users will enter their username
self.okButton = wx.Button(self, wx.ID_OK, "OK") #Note that I'm using wx.ID_OK. This is important
Now, for the logic you want. Pretty much every object in wxPython that you actually see has the functions Show() and Hide() (API here). You don't want to show your frame until AFTER the dialogs are finished, so in your __init__(), call Hide(). I'm also initializing a variable, username, which is where I will store the data from my dialog.
class Game(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(SCRWIDTH, SCRHEIGHT))
self.username = ""
self.Hide() #don't show the frame just yet
#self.Hide() is the exact same as self.Show(False)
Now, for your dialogs. Like Mike Driscoll suggested, you call your dialogs BEFORE making your canvas. wx.Dialogs are launched using ShowModal(). By setting the ID of self.okButton to the constant wx.ID_OK, wxPython recognizes that the dialog should be closed after the button in clicked. You should also be aware of wx.ID_CANCEL.
def OnInit(self):
#Make your dialogs
dlg1 = MyDialog1(self)
if dlg1.ShowModal() == wx.ID_OK:
#if the user pressed "OK" (i.e. NOT "Cancel" or any other button you might add)
self.username = dlg1.username.GetValue() #get the username from the dialog
dlg1.Destroy() #clean up the dialog (AFTER you get the username)
#do this again for your second dialog
#Now that you have your settings, Make the gameboard
self.gameBoard = Board.Board(self)
self.gameBoard = SetFocus()
self.gameBoard.start()
self.Centre()
self.Show(True) #show the frame
In your OnInit you just need to call your dialogs and show them modally BEFORE you create your Board instance. Then it should work correctly.
EDIT (6-28-12): Here's some code:
import wx
########################################################################
class MyDlg(wx.Dialog):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Dialog.__init__(self, None, title="I'm a dialog!")
lbl = wx.StaticText(self, label="Hi from the panel's init!")
btn = wx.Button(self, id=wx.ID_OK, label="Close me")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(lbl, 0, wx.ALL, 5)
sizer.Add(btn, 0, wx.ALL, 5)
self.SetSizer(sizer)
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
# show a custom dialog
dlg = MyDlg()
dlg.ShowModal()
dlg.Destroy()
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, evt):
pdc = wx.PaintDC(self)
try:
dc = wx.GCDC(pdc)
except:
dc = pdc
rect = wx.Rect(0,0, 100, 100)
for RGB, pos in [((178, 34, 34), ( 50, 90)),
(( 35, 142, 35), (110, 150)),
(( 0, 0, 139), (170, 90))
]:
r, g, b = RGB
penclr = wx.Colour(r, g, b, wx.ALPHA_OPAQUE)
brushclr = wx.Colour(r, g, b, 128) # half transparent
dc.SetPen(wx.Pen(penclr))
dc.SetBrush(wx.Brush(brushclr))
rect.SetPosition(pos)
dc.DrawRoundedRectangleRect(rect, 8)
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Example frame")
# show a MessageDialog
style = wx.OK|wx.ICON_INFORMATION
dlg = wx.MessageDialog(parent=None,
message="Hello from the frame's init",
caption="Information", style=style)
dlg.ShowModal()
dlg.Destroy()
# create panel
panel = MyPanel(self)
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
frame.Show()
app.MainLoop()

Using the same handler for multiple wx.TextCtrls?

I'm having a bit of trouble with a panel that has two wxPython TextCtrls in it. I want either an EVT_CHAR or EVT_KEY_UP handler bound to both controls, and I want to be able to tell which TextCtrl generated the event. I would think that event.Id would tell me this, but in the following sample code it's always 0. Any thoughts? I've only tested this on OS X.
This code simply checks that both TextCtrls have some text in them before enabling the Done button
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title,
wx.DefaultPosition, wx.Size(200, 150))
self.panel = BaseNameEntryPanel(self)
class BaseNameEntryPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.entry = wx.TextCtrl(self, wx.NewId())
self.entry2 = wx.TextCtrl(self, wx.NewId())
self.donebtn = wx.Button(self, wx.NewId(), "Done")
self.donebtn.Disable()
vsizer = wx.BoxSizer(wx.VERTICAL)
vsizer.Add(self.entry, 1, wx.EXPAND|wx.GROW)
vsizer.Add(self.entry2, 1, wx.EXPAND|wx.GROW)
vsizer.Add(self.donebtn, 1, wx.EXPAND|wx.GROW)
self.SetSizer(vsizer)
self.Fit()
self.entry.Bind(wx.EVT_KEY_UP, self.Handle)
self.entry2.Bind(wx.EVT_KEY_UP, self.Handle)
def Handle(self, event):
keycode = event.GetKeyCode()
print keycode, event.Id # <- event.Id is always 0!
def checker(entry):
return bool(entry.GetValue().strip())
self.donebtn.Enable(checker(self.entry) and checker(self.entry2))
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1, "Hello from wxPython")
frame.Show(True)
self.SetTopWindow(frame)
return True
app = MyApp(0)
app.MainLoop()
You could try event.GetId() or event.GetEventObject() and see if either of these work.
Another approach to this is to use lambda or functools.partial to effectively pass a parameter to the handler. So, for example, sub in the lines below into your program:
self.entry.Bind(wx.EVT_KEY_UP, functools.partial(self.Handle, ob=self.entry))
self.entry2.Bind(wx.EVT_KEY_UP, functools.partial(self.Handle, ob=self.entry2))
def Handle(self, event, ob=None):
print ob
And then ob will be either entry or entry2 depending on which panel is clicked. But, of course, this shouldn't be necessary, and GetId and GetEventObject() should both work -- though I don't (yet) have a Mac to try these on.

Categories