Related
I've read so many questions similar to this but I'm caving in and making my own because nothing is working. Basically, I want to have my wx.StaticText have vertically centered text while resizing with the window. My understanding is that existing solutions don't work because I care about the background of the StaticText, and so I cannot simply vertically center the label itself in a sizer. I also see that it requires messy subclassing to have a transparent-background StaticText, so overlaying it on a panel sounds difficult.
Here is a minimal example (in my project the sizer has several other things in it):
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
sizer=wx.BoxSizer(wx.VERTICAL)
label = wx.StaticText(self, -1, 'PLEASE VERTICALLY CENTER ME ;(', style=wx.ALIGN_CENTRE | wx.ST_NO_AUTORESIZE)
label.SetMinSize((300,300))
label.SetBackgroundColour((255,0,0))
sizer.Add(label, 1, wx.EXPAND | wx.ALL, 10)
self.SetSizerAndFit(sizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()
Despite that, it's hard to accept it's not simple to vertically center text. What is the easiest way to have the text in the label be vertically centered?
Solution:
catalin's answer gave the concept necessary! Here is a full snippet for anyone else who encounters this problem. I added a button below the StaticText to demonstrate the vertical sizer remaining in control. The vertical sizer could be removed altogether if your application doesn't need it.
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
sizer=wx.BoxSizer(wx.VERTICAL) # "main" sizer
panel = wx.Panel(self) # panel just for centering label
panel.SetBackgroundColour((255,0,0))
label = wx.StaticText(panel, -1, 'PLEASE VERTICALLY CENTER ME ;(', style=wx.ALIGN_CENTRE | wx.ST_NO_AUTORESIZE)
hsizer=wx.BoxSizer(wx.HORIZONTAL) # sizer for the panel
hsizer.Add(label, 1, wx.ALIGN_CENTER_VERTICAL)
panel.SetSizer(hsizer)
sizer.Add(panel, 1, wx.EXPAND)
btn = wx.Button(self, -1, 'Button')
sizer.Add(btn, 0, wx.EXPAND)
self.SetSizerAndFit(sizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()
In c++ a quick way would look like this:
wxPanel* p = new wxPanel(this); // you don't need to put it in a sizer if it's the only child
p->SetBackgroundColour({ 255, 0, 0 }); // this will be inherited by children
wxStaticText* label = new wxStaticText(p, wxID_ANY, "PLEASE VERTICALLY CENTER ME ;(");
wxSizer* s = new wxBoxSizer(wxHORIZONTAL); // for vertical one, you'd need stretch-spacers, and could not use wxALIGN_CENTER_VERTICAL, see below
s->Add(label, wxSizerFlags(1).Align(wxALIGN_CENTER_VERTICAL));
p->SetSizer(s);
Mind that if you want the text to wrap upon resize, wxStaticText will probably not resize correctly, and you might need to replace it with something else.
Another example of the sizer concept.
The frame is broken up into component parts, with each part assigned its relevant sizer.
The component sizers are then put within a main (self) sizer, to put it all together.
In this case the components are text, that needs to be centered and a set of buttons to the right, vertically stacked.
Obviously, components and arrangements differ but the concept of breaking the design into parts, which is then assembled for final presentation, remains the same.
Indeed, complicated components often need to have the same principle applied, leaving you with a series of sub-assemblies before the final one, in the main sizer.
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
mainsizer=wx.BoxSizer(wx.HORIZONTAL) # "main" sizer
tsizer=wx.BoxSizer(wx.HORIZONTAL) # "text" sizer
bsizer=wx.BoxSizer(wx.VERTICAL) # "button" sizer
panel = wx.Panel(self) # panel for label
button_panel = wx.Panel(self) # panel for buttons
panel.SetBackgroundColour((190,0,0))
button_panel.SetBackgroundColour((160,0,0))
label = wx.StaticText(panel, -1, 'PLEASE VERTICALLY CENTER ME ;(')
btn1 = wx.Button(button_panel,-1, 'Button 1')
btn2 = wx.Button(button_panel,-1, 'Button 2')
btn3 = wx.Button(button_panel,-1, 'Button 3')
btn4 = wx.Button(button_panel,-1, 'Button 4')
tsizer.AddSpacer(10)
tsizer.Add(label, 0, wx.CENTER)
tsizer.AddSpacer(10) # Ensure gap between text and buttons
bsizer.Add(btn1)
bsizer.Add(btn2)
bsizer.Add(btn3)
bsizer.Add(btn4, 0, wx.BOTTOM, 35) # With space below
panel.SetSizer(tsizer)
button_panel.SetSizer(bsizer)
mainsizer.Add(panel, proportion=1, flag=wx.EXPAND) # panel to grow when resized
mainsizer.Add(button_panel, proportion=0, flag=wx.EXPAND) # panel to fill available space
self.SetSizerAndFit(mainsizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()
Completely new to wxpython so my question is on this thread (Embedding a matplotlib figure inside a WxPython panel)
How would I add an entry box for the user to enter a value or string? Say 6.0 instead of 3.0 in the xrange value and they click compute again? Or they enter a string that imports a file?
Second question, how can I make 2 tabs for the plots? Tab 1 has a plot and tab 2 has another plot?
Thank you for any help
So I got the tabs part to work with this code, but now unsure how to give users the ability to input data for the plots.
import wx
import wx.aui
import matplotlib as mpl
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as mplCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as mplToolbar
# initialization code: create a basic Wx application
app = wx.PySimpleApp()
framelist = [] # list of frames (windows) created here
def MakePlotWindow(DisableDelete=False, size=(600,600), **kw):
''' Create a plot window with an empty notebook widget for plots includes a sizer at top
for placement of wx widgets
Input:
size: the dimensions of the plot window in pixels (defaults to 600x600)
other keyword args for wx.Frame are allowed
Output:
returns the name of the created panel (<panel>)
Use <panel>.Parent to access the frame
Note that <panel>.topsizer is a sizer above the plot where wx objects can be placed
and <panel>.bottomsizer is a sizer below the plot where wx objects can be placed
'''
kw["size"] = size
plotter = PlotNotebook(id, DisableDelete, **kw)
global framelist
framelist.append(plotter.frame)
return plotter
def ShowPlots():
'''Call ShowPlots after all plots are defined to cause the plots to be displayed
and to enter the event loop so that widgets respond to mouse clicks, etc.
'''
for frame in framelist:
frame.Show()
app.MainLoop()
class PlotNotebook(wx.Panel):
''' defines a panel in a independent frame (window). Call from MakePlotWindow'''
def __init__(self, id, DisableDelete=False, **kw):
self.frame = wx.Frame(None, **kw) # create a frame
wx.Panel.__init__(self, self.frame) # create the panel
# note the above places this panel inside the new frame
# create a notebook widget:
if DisableDelete:
self.nb = wx.aui.AuiNotebook(
self,
style=wx.aui.AUI_NB_DEFAULT_STYLE ^ wx.aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
# turns off the delete tab
)
else:
self.nb = wx.aui.AuiNotebook(self)
sizer = wx.BoxSizer(wx.VERTICAL) # create a sizer for the notebook
self.topsizer = wx.BoxSizer(wx.HORIZONTAL) # a place for misc wx items
sizer.Add(self.topsizer, 0, wx.EXPAND) # place the widget box in the sizer
sizer.Add(self.nb, 1, wx.EXPAND) # place the notebook in the sizer
self.bottomsizer = wx.BoxSizer(wx.HORIZONTAL) # a place for misc wx items
sizer.Add(self.bottomsizer, 0, wx.EXPAND) # place the widget box in the sizer
self.SetSizer(sizer) # associate the sizer with the panel created by class
def AddPlotTab(self,name="plot"):
'''Adds a plot tab to the panel
Input:
name: a string that is placed on the plot tab
Output:
returns the wx.Panel object that contains the the new plot. Note that
<panel>.figure is the plot figure
<panel>.canvas is the plot canvas
<panel>.toolbar is the toolbar object
<panel>.topsizer is a sizer above the plot where wx objects can be placed
'''
page = Plot(self.nb)
self.nb.AddPage(page,name)
return page
def ReusePlotTab(self,name="plot"):
'''Reuses a plot tab on the panel, if a tab with the selected name exists. Uses the
first one if more than one such tab exists. Creates a tab with the name, if one is
not found.
Input:
name: a string that is placed on the plot tab
Output:
returns the wx.Panel object that contains the the new plot. Note that
<panel>.figure is the plot figure
<panel>.canvas is the plot canvas
<panel>.toolbar is the toolbar object
<panel>.topsizer is a sizer above the plot where wx objects can be placed
'''
for PageNum in range(self.nb.GetPageCount()):
if name == self.nb.GetPageText(PageNum):
Page = self.nb.GetPage(PageNum)
return Page
return self.AddPlotTab(name) # not found, create a new tab
def RaisePlotTab(self,name="plot"):
'''Raises a plot tab on the panel so that the plot is visible. Uses the
first one if more than one such tab exists. Does nothing if no such tab is found'''
for PageNum in range(self.nb.GetPageCount()):
if name == self.nb.GetPageText(PageNum):
self.nb.SetSelection(PageNum)
return
class Plot(wx.Panel):
''' Defines a panel containing a plot etc to be placed in a notebook widget
Note that this is expected to be called only from PlotNotebook.AddPlotTab
'''
def __init__(self, parent, id = -1, dpi = None, **kwargs):
wx.Panel.__init__(self, parent, id=id, **kwargs)
# create a figure with an associated canvas & toolbar
self.figure = mpl.figure.Figure(dpi=dpi)
self.canvas = mplCanvas(self, -1, self.figure) # wxPanel object containing plot
self.toolbar = mplToolbar(self.canvas) # toolbar object
self.toolbar.Realize()
self.topsizer = wx.BoxSizer(wx.HORIZONTAL) # a place for misc wx items
# put the canvas, toolbar & topsizer in a sizer and associate the sizer
# with self (the main panel)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.topsizer,0,wx.EXPAND)
sizer.Add(self.canvas,1,wx.EXPAND)
sizer.Add(self.toolbar, 0 , wx.LEFT | wx.EXPAND)
self.SetSizer(sizer)
if __name__ == "__main__":
from numpy import arange, sin, pi
# create the first plot window
plotter = MakePlotWindow(size=(700,700), DisableDelete=True,)
plotter.Parent.SetTitle("Title for 1st Plot Window")
# add a plot to the window with a straight line
page1 = plotter.AddPlotTab('Plot1')
t = arange(0.0, 3.0, 0.01)
s = sin(2 * pi * t)
page1.figure.gca().plot(t,s,color='red')
# code to respond to a key press inside the window
#page1.figure.gca().set_title("Press any key inside plot") # plot title
#page1.figure.canvas.mpl_connect('key_press_event', onKeyPress)
# create a second plot on the 1st window and raise it
page2 = plotter.AddPlotTab('Plot2')
page2.figure.gca().plot(range(10),[i**2 for i in range(10)],'+-')
plotter.RaisePlotTab('Plot2')
# everything is done, display the plots and start the event loop
ShowPlots()
I am writing a small app that works very well on linux, but I have some trouble on windows. Here is the code sample:
import wx
#####################################################################
class Main(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="StackOverflow", pos=wx.DefaultPosition, size=(800,600))
self.SetMinSize( self.GetSize() )
p = wx.Panel(self)
nb = wx.Notebook(p)
page1 = AddToCollection(nb)
page2 = CollectionStatistics(nb)
nb.AddPage(page1, "Page 1")
nb.AddPage(page2, "Page 2")
# finally, put the notebook in a sizer for the panel to manage
# the layout
sizer = wx.BoxSizer()
sizer.Add(nb, 1, wx.EXPAND)
p.SetSizer(sizer)
#########################################################################
class CollectionStatistics(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
#########################################################################
class AddToCollection(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.v1_qty_list = [str(x) for x in range(9)]
self.v2_qty_list = [str(x) for x in range(9)]
self.sizername = wx.GridBagSizer(5, 5)
self.sizername.AddGrowableCol(0,0)
self.name_txt = wx.StaticText(self, label="Enter Name :")
self.sizername.Add(self.name_txt,(2,0),(1,1),wx.EXPAND)
self.name = wx.TextCtrl(self,style=wx.TE_PROCESS_ENTER,value=u"")
self.sizername.Add(self.name,(3,0),(1,1),wx.EXPAND)
self.Bind(wx.EVT_TEXT_ENTER, self.OnPressEnter, self.name)
self.SetSizerAndFit(self.sizername)
self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )
##########################################################################
def OnPressEnter(self,event):
self.selected_name = self.name.GetValue()
self.AddToCol()
##########################################################################
def AddToCol(self):
self.sizerAdd = wx.GridBagSizer(5, 5)
self.sizerAdd.AddGrowableCol(0, 0)
self.name.Enable(False)
### Expansion
self.expansion = wx.Choice(self, -1, choices=['test 1', 'test 2'])
self.expansion.SetSelection(0)
self.sizerAdd.Add(self.expansion,(5,0),(1,6),wx.EXPAND)
### Quantities txt
self.v1_txt = wx.StaticText(self, label="V1 Quantity :")
self.sizerAdd.Add(self.v1_txt,(7,0),(1,1),wx.EXPAND)
self.v2_txt = wx.StaticText(self, label="V2 Quantity :")
self.sizerAdd.Add(self.v2_txt,(8,0),(1,1),wx.EXPAND)
### Quantities choices
self.v1_qty = wx.Choice(self, -1, choices=self.v1_qty_list)
self.v1_qty.SetSelection(0)
self.sizerAdd.Add(self.v1_qty,(7,5),(1,1),wx.EXPAND)
self.v2_qty = wx.Choice(self, -1, choices=self.v1_qty_list)
self.v2_qty.SetSelection(0)
self.sizerAdd.Add(self.v2_qty,(8,5),(1,1),wx.EXPAND)
### Ok Button
self.Add_btn = wx.Button(self, -1, "Add")
self.Add_btn.Bind(wx.EVT_BUTTON, self.OnAdd)
self.sizerAdd.Add(self.Add_btn,(9,5),(1,1),wx.EXPAND)
### Reset Button
self.Reset_btn = wx.Button(self, -1, "Reset")
self.Reset_btn.Bind(wx.EVT_BUTTON, self.OnResetPanel)
self.sizerAdd.Add(self.Reset_btn,(9,4),(1,1),wx.EXPAND)
self.SetSizerAndFit(self.sizerAdd)
self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )
######################################################################
def OnResetPanel(self,event):
### Kill all children
self.expansion.Destroy()
self.v1_txt.Destroy()
self.v1_qty.Destroy()
self.v2_txt.Destroy()
self.v2_qty.Destroy()
self.Add_btn.Destroy()
self.Reset_btn.Destroy()
### Reinitialise sizer
self.name.Enable(True)
self.name.SetValue("")
######################################################################
def OnAdd(self,event):
print 'Add'
self.OnResetPanel(self)
######################################################################
######################################################################
if __name__ == "__main__":
app = wx.App()
Main().Show()
app.MainLoop()
Basically, I have a TextCtrl in a first sizer which is waiting for an entry. Once the user hits enter, several objects appear in a second sizer.
The issue on windows seems to come from the use of the two gridbagsizers (sizername and sizerAdd). After pressing enter (waited event in the __init__), the objects defined within the sizerAdd do not appear. When I extend the window where the script is running, these objects appear magically !
Any idea ?
EDIT : The code is now runnable
I think the problem in your code is these two lines at the end of your AddToCol method:
self.SetSizerAndFit(self.sizerAdd)
self.SetSizeHints(-1,self.GetSize().y,-1,self.GetSize().y )
At this point, you're changing the sizer of the AddToCollection panel from self.sizername to self.sizerAdd. The Enter Name: label and the textbox however are still within the self.sizername sizer. However, this sizer isn't the sizer for any window, nor has it been added to any other sizer.
Generally, in wxPython, every sizer should be set as the sizer for a window, or be added to another sizer. This other sizer would then be the sizer for a window, or be contained within another sizer, and so on. In your case, your self.sizername sizer ends up being neither, and in this situation I would expect unpredictable behaviour. If your code works on Linux then I would say that it happens to work by accident.
I can think of a few things you could do here:
Add self.sizerAdd as a child of self.sizername. This can be done by replacing the two lines above with
self.sizername.Add(self.sizerAdd,(4,0),(1,1),wx.EXPAND)
self.sizername.Layout()
In AddToCol, add the widgets directly to the self.sizername sizer instead of adding them to self.sizerAdd.
Create a wx.BoxSizer() with vertical orientation, set that to be the sizer for the AddToCollection panel, and add the self.sizername and self.sizerAdd sizers to your BoxSizer.
In all three cases, after creating the new widgets you will need to call the Layout() method on the top-level sizer, be it either self.sizername or the top-level BoxSizer. The code snippet under option 1 includes this line already.
Additionally, you may need to modify your OnResetPanel() method. If you chose options 1 or 3, you will need to remove the self.sizerAdd sizer from whichever sizer you added it to. For example, in option 1, you would add the line
self.sizername.Remove(self.sizerAdd)
Another approach would be for your AddToCol method to create all the widgets within a Panel and add that to the main panel at the end. Your AddToCol method would then need to create a child panel, add the extra controls as children of this panel instead of the main panel (self), set the sizer of the child panel to self.sizerAdd and finally add this panel to the self.sizername sizer.
def AddToCol(self):
self.sizerAdd = wx.GridBagSizer(5, 5)
self.sizerAdd.AddGrowableCol(0, 0)
self.name.Enable(False)
self.child_panel = wx.Panel(self)
### Expansion
self.expansion = wx.Choice(self.child_panel, -1, choices=['test 1', 'test 2'])
self.expansion.SetSelection(0)
self.sizerAdd.Add(self.expansion,(5,0),(1,6),wx.EXPAND)
# Create other widgets as before but with the parent set to self.child_panel
# instead of self.
self.child_panel.SetSizer(self.sizerAdd)
self.sizername.Add(self.child_panel,(4,0),(1,1),wx.EXPAND)
self.sizername.Layout()
You would then also need to replace the line
self.sizername.Remove(self.sizerAdd)
in OnResetPanel() with the two lines:
self.sizername.Remove(self.child_panel)
self.child_panel.Destroy()
One thing which bugged me about my approach 1 above was that I saw the widgets briefly appear in the top-left corner before appearing in the correct place. This adaptation fixes this problem and so makes the GUI behave itself a bit better. I couldn't reproduce your black area issue you mention in your comment, but hopefully this approach fixes your problem as well.
I have a wxPython GUI which looks like this:
As you can see there are three "columns", each enclosed in a wx.StaticBox. I want to disable all the buttons, text box, and radio buttons within a column. I tried using .Disable on the static box but it had no effect. Is there an easy way to disable everything within a static box?
A wx.StaticBox is not actually a container, it's just:
a rectangle drawn around other panel items to denote a logical grouping of items.
So, the only way you can do this with StaticBox is to keep track of the widgets you've logically grouped together, and call Disable on all of them.
Or, alternatively, you can put the widgets into any of the actual container widgets (like windows and sizers) instead, and then just Disable the container.
Make the StaticBoxSizer into a class attribute if you haven't already (i.e. self.mySizer instead of just mySizer). Then you can use its GetChildren() method to return the widgets. Next you just loop through the widgets and Disable them. Something like this should do it:
children = self.mySizer.GetChildren()
for child in children:
child.Disable()
You might have to add a check in the loop to make sure it's a button or a text control. I recommend using Python's isinstance for that.
Here is a working example:
"""
Demonstration on how to disable / enable all objects within a sizer
Reinhard Daemon / Austria
08.10.2019
"""
import wx
class MainWindow(wx.Frame):
def __init__(self, parent=None):
wx.Frame.__init__(self, parent, -1,
title='Disable / Enable all Widgets within a Sizer',size=(500,200))
self.Move((50,50))
panel = wx.Panel(self)
# layout (sizers, boxes,...):
top_sizer = wx.BoxSizer(wx.VERTICAL)
widget_box = wx.StaticBox(panel, id=-1,
label='Widgets, which are controlled')
widget_box.SetBackgroundColour("yellow")
control_box = wx.StaticBox(panel, -1,
label='Widgets, which controll')
control_box.SetBackgroundColour("yellow")
self.widget_sizer = wx.StaticBoxSizer(widget_box, wx.HORIZONTAL)
control_sizer = wx.StaticBoxSizer(control_box, wx.HORIZONTAL)
# create the widgets:
widget_1 = wx.TextCtrl(panel, value='Text 1')
widget_2 = wx.RadioButton(panel, label='Radio 1')
widget_3 = wx.RadioButton(panel, label='Radio 2')
widget_4 = wx.Button(panel, label='Button 1')
widget_disable = wx.Button(panel, label='DISABLE')
self.widget_enable = wx.Button(panel, label='ENABLE', pos = (100,50))
# add the widgets to the layout:
self.widget_sizer.Add(widget_1)
self.widget_sizer.Add(widget_2)
self.widget_sizer.Add(widget_3)
self.widget_sizer.Add(widget_4)
control_sizer.Add(widget_disable)
control_sizer.Add(self.widget_enable)
# finalize the layout:
top_sizer.Add(sizer=self.widget_sizer, flag=wx.CENTER | wx.EXPAND)
top_sizer.AddSpacer(30)
top_sizer.Add(control_sizer, 0, wx.CENTER | wx.EXPAND)
panel.SetSizer(top_sizer)
panel.Fit()
# bindings:
widget_disable.Bind(wx.EVT_BUTTON, self.on_button_disable)
self.widget_enable.Bind(wx.EVT_BUTTON, self.on_button_enable)
def on_button_disable(self, evt):
children = self.widget_sizer.GetChildren()
for child in children:
print(child.GetWindow(),end='')
try:
child.GetWindow().Enable(False)
print(' DISABLED')
except:
print(' ERROR')
def on_button_enable(self, evt):
children = self.widget_sizer.GetChildren()
for child in children:
print(child.GetWindow(),end='')
try:
child.GetWindow().Enable(True)
print(' ENABLED')
except:
print(' ERROR')
if __name__ == "__main__":
app = wx.App()
view1 = MainWindow()
view1.Show()
app.MainLoop()
I have a set of images available. If I click on one of those images is there a way to determine which of the images has been clicked on in wxPython?
You will almost certainly have to calculate it for yourself. The most straight-forward method would be to use a mouse event like wx.EVT_LEFT_DOWN and grab the mouse's coordinates in the event handler. Then use that information to tell you where on your wxPython window you clicked. Each of your image widgets or DCs or whatever you're using can report it's size and position, so if the mouse coordinates are in X image's boundaries, you know it's been clicked on. You might also be able to use the HitTest() method, depending on what you're using to show the images.
EDIT: Here is how you would do it if you were using a wx.StaticBitmap, which actually lets you attach an wx.EVT_LEFT_DOWN to it:
import wx
class PhotoCtrl(wx.Frame):
def __init__(self):
size = (400,800)
wx.Frame.__init__(self, None, title='Photo Control', size=size)
self.panel = wx.Panel(self)
img = wx.EmptyImage(240,240)
self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.BitmapFromImage(img),
name="emptyImage")
imageCtrl2 = wx.StaticBitmap(self.panel, wx.ID_ANY,
wx.BitmapFromImage(img),
name="anotherEmptyImage")
self.imageCtrl.Bind(wx.EVT_LEFT_DOWN, self.onClick)
imageCtrl2.Bind(wx.EVT_LEFT_DOWN, self.onClick)
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5)
mainSizer.Add(imageCtrl2, 0, wx.ALL, 5)
self.panel.SetSizer(mainSizer)
self.Show()
#----------------------------------------------------------------------
def onClick(self, event):
""""""
print event.GetPosition()
imgCtrl = event.GetEventObject()
print imgCtrl.GetName()
if __name__ == '__main__':
app = wx.App(False)
frame = PhotoCtrl()
app.MainLoop()
you dont tell us anything about how you are displaying your images? are you blitting them right on the dc? are you creating panels for them? etc... properly setting up your project is important. basically you give us zero information to help you with.
Keeping all that in mind, something like this would work fine (this is called a self contained code example, you should always provide one with your questions, to make it easier for people to help you)
import wx
a = wx.App(redirect=False)
f= wx.Frame(None,-1,"Some Frame",size = (200,200))
sz = wx.BoxSizer(wx.HORIZONTAL)
def OnClick(evt):
print "Clicked:",evt.GetId()-10023
for i,img in enumerate(["img1","img2","img3"]):
id = 10023+i
p = wx.Panel(f,-1)
sz.Add(p)
sz1 = wx.BoxSizer()
p.Bind(wx.EVT_LEFT_UP,OnClick)
bmp = wx.Image(img).ConvertToBitmap()
b = wx.StaticBitmap(p,-1,bmp)
sz1.Add(b)
p.SetSizer(sz1)
f.SetSizer(sz)
f.Layout()
f.Fit()
f.Show()
a.MainLoop()
Keep in mind I didnt test it... but theoretically it should work...