I’ve yet to actually try this on GTK, but the code is recreating my application’s layout in the same order as my app does it, and binds the events as it does, so it should be a faithful recreation. The problem’s in the GUI - you can ignore the other classes, they’re just there in case it’s some kind of focus problem. I’ve tried using SetFocus() on the Frame too, but no luck there.
#!/usr/bin/python
import wx
from wx.lib import scrolledpanel as scrolled
class GUI(wx.Frame):
def init(self, parent):
wx.Frame.init(self, parent, size=(1024, 786))
cpanel = ControlPanel(self)
spanel = SidePanel(self)
box = wx.BoxSizer(wx.HORIZONTAL) # position windows side-by-side
box.Add(cpanel, 0, wx.EXPAND)
box.Add((1, 1), 2, wx.EXPAND)
box.Add(spanel, 0, wx.EXPAND)
self.SetSizer(box)
ac = []
hotkeys = ["a", "b", "c", "d", "e", "f", "g"]
for x, item in enumerate(hotkeys):
_id = wx.NewId()
ac.append((wx.ACCEL_NORMAL, ord(item.upper()), _id))
self.Bind(wx.EVT_MENU, self.accel, id=_id)
tbl = wx.AcceleratorTable(ac)
self.SetAcceleratorTable(tbl)
self.Bind(wx.EVT_CHAR_HOOK, self.hotkey)
def hotkey(self, evt):
print 'hotkey'
def accel(self, evt):
print 'accelerator'
class SidePanel(wx.Panel):
def init(self, parent):
wx.Panel.init(self, parent, size=(170, -1), style=wx.RAISED_BORDER)
self.cp = wx.CollapsiblePane(self, style=wx.CP_DEFAULT_STYLE |
wx.CP_NO_TLW_RESIZE)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
csizer = wx.BoxSizer(wx.VERTICAL)
self.cp.GetPane().SetSizer(csizer)
self.tabs = wx.Notebook(self.cp.GetPane())
self.thumbs = Thumbs(self.tabs)
self.tabs.AddPage(self.thumbs, "Thumbnails")
csizer.Add(self.tabs, 1, wx.EXPAND)
sizer.Add(self.cp, 1, wx.EXPAND)
self.cp.Expand()
class Thumbs(scrolled.ScrolledPanel):
def init(self, parent):
scrolled.ScrolledPanel.init(self, parent, size=(170, -1),
style=wx.VSCROLL | wx.RAISED_BORDER)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(self.sizer)
self.SetScrollRate(0, 250)
btn = wx.BitmapButton(self, size=(150, 150))
text = wx.StaticText(self, label=“Tab 1”)
self.sizer.Add(text, flag=wx.ALIGN_CENTER | wx.TOP, border=5)
self.sizer.Add(btn, flag=wx.TOP | wx.LEFT, border=6)
class ControlPanel(wx.Panel):
def init(self, parent):
wx.Panel.init(self, parent)
sizer = wx.GridSizer(cols=1, hgap=1, vgap=2)
sizer.Add(wx.Button(self, label=“Thing”), 0)
sizer.Add(wx.Button(self, label=“Thing”), 0)
box = wx.BoxSizer(wx.VERTICAL)
box.Add(sizer, 0, wx.ALL, 4)
self.SetSizer(box)
self.SetAutoLayout(True)
box.Fit(self)
class TestApp(wx.App):
def OnInit(self):
frame = GUI(None)
frame.Show(True)
return True
if name == ‘main’:
app = TestApp()
app.MainLoop()
···
2009/11/12 Robin Dunn robin@alldunn.com
On 11/11/09 4:52 AM, Steven Sproat wrote:
Hi Rob,
2009/11/7 Robin Dunn <robin@alldunn.com mailto:robin@alldunn.com>
On 11/6/09 8:02 PM, Steven Sproat wrote:
>
>
> This works great on Windows, but on GTK nothing happens, my lambda
> method is not called.
Are you sure that some widget within the frame has the keyboard focus?
You might try adding a timer event that prints the results of
wx.Window.FindFocus() to verify where the focus is.
I just done some testing on Linux:
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
self.timer.Start(200)
def on_timer(self, event):
print wx.Window.FindFocus()
and it seems that my GUI frame never receives focus. At first starting
my program, without clicking anything, I get many “None” printed. I
click on a toggle button in my left-hand panel and the focus is given to
the GenericToggleBitmapButton, and then back to None
It seems that mouse-overing the bitmap buttons gives them focus, too.
Anyway, I put self.SetFocus() into the last line of my Frame’s init
method, and now the Frame is reported as having focus, but if I click on
a button then it returns to None again.
but my accelerators are still not firing.
I also noticed that my EVT_HOOK doesn’t work:
Probably the same issue with focus.
I tried giving the Frame the wx.WANTS_CHARS style, but it made no
difference. I’m pretty stumped with this, it’s the first an error is
happening on Linux that works on Windows (it’s usually the other way
around!)
The wx.WANTS_CHARS style won’t have any effect, as it’s only used on MSW.
Can you reduce this problem to a small sample? In every case I’ve tried
once the focus is in the frame or some widget within the frame then it
stays there.
–
Robin Dunn
Software Craftsman
http://wxPython.org