我正在教自己(Wx)Python而且卡住了。我想创建一个子窗口,它在我的TestFrame中有一组重复的信息,其中包含我的大部分代码。问题是,它只在我的代码中显示一个小部件。我试图弄清楚以下内容,对我来说很重要。
**请注意,此代码是this页面的扩展名。*
感谢您的帮助。如果你允许/适当的话,我愿意通过Paypal向你赢得5美元的奖金。
import wx
class AddBox(wx.Window):
def __init__(self, parent):
wx.Window.__init__(self, parent)
pbox = wx.BoxSizer(wx.VERTICAL)
controlback = wx.Button(self, label="Back")
controlforward = wx.Button(self, label="Forward")
pbox.AddMany([(controlback, 1, wx.ALL), (controlforward, 1, wx.ALL)])
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, size=(1000, 550))
self.Bind(wx.EVT_SIZE, self.OnSize)
pbox0 = wx.BoxSizer(wx.VERTICAL)
controlback0 = wx.Button(self, label="Back0")
controlforward0 = wx.Button(self, label="Forward0")
pbox0.AddMany([(controlback0, 1, wx.ALL), (controlforward0, 1, wx.ALL)])
pbox2 = wx.BoxSizer(wx.VERTICAL)
self.scrolling_window = wx.ScrolledWindow( self )
self.scrolling_window.SetScrollRate(1,6)
self.scrolling_window.EnableScrolling(True,True)
self.sizer_container = wx.BoxSizer( wx.VERTICAL )
self.sizer = wx.BoxSizer( wx.VERTICAL )
self.sizer_container.Add(self.sizer,1,wx.CENTER,wx.EXPAND)
self.child_windows = []
for i in range(0,8):
wind = AddBox(self.scrolling_window)
self.sizer.Add(wind, 0, wx.CENTER|wx.ALL, 5)
self.child_windows.append(wind)
self.scrolling_window.SetSizer(self.sizer_container)
#self.Layout() #not needed?
pbox2.AddMany([(self.sizer_container, 1, wx.ALL)])
def OnSize(self, event):
self.scrolling_window.SetSize(self.GetClientSize())
if __name__=='__main__':
app = wx.PySimpleApp()
f = TestFrame()
f.Show()
app.MainLoop()
答案 0 :(得分:1)
这里的代码非常复杂,难以理解。你几乎不需要使用wx.Window。事实上,在使用wxPython的近6年中,我从未直接使用它。 PySimpleApp也已弃用。无论如何,我清理了一堆代码并在下面重新做了。我不确定这是不是你要找的东西。另请注意,我将ScrolledWindow替换为ScrolledPanel,因为我认为后者更容易使用:
import wx
import wx.lib.scrolledpanel as scrolled
class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, size=(1000, 550))
panel = wx.Panel(self)
mainSizer = wx.BoxSizer(wx.VERTICAL)
pbox0 = wx.BoxSizer(wx.VERTICAL)
controlback0 = wx.Button(panel, label="Back0")
controlforward0 = wx.Button(panel, label="Forward0")
pbox0.Add(controlback0, 0, wx.ALL)
pbox0.Add(controlforward0, 0, wx.ALL)
mainSizer.Add(pbox0)
self.scrolling_window = scrolled.ScrolledPanel( panel )
self.scrolling_window.SetAutoLayout(1)
self.scrolling_window.SetupScrolling()
self.sizer = wx.BoxSizer( wx.VERTICAL )
self.child_windows = []
for i in range(0,8):
wind = self.addBox()
self.sizer.Add(wind, 0, wx.CENTER|wx.ALL, 5)
self.scrolling_window.SetSizer(self.sizer)
mainSizer.Add(self.scrolling_window, 1, wx.EXPAND)
panel.SetSizer(mainSizer)
def addBox(self):
pbox = wx.BoxSizer(wx.VERTICAL)
controlback = wx.Button(self.scrolling_window, label="Back")
controlforward = wx.Button(self.scrolling_window, label="Forward")
pbox.AddMany([(controlback, 0, wx.ALL), (controlforward, 0, wx.ALL)])
return pbox
def OnSize(self, event):
self.scrolling_window.SetSize(self.GetClientSize())
if __name__=='__main__':
app = wx.App(False)
f = TestFrame()
f.Show()
app.MainLoop()
您还应该查看窗口小部件检查工具。它可以帮助您找出这样的布局问题:http://wiki.wxpython.org/Widget%20Inspection%20Tool
编辑:我认为上面的代码处理了第1和第2项。对于#3,请参阅我去年写的以下文章:http://www.blog.pythonlibrary.org/2011/09/20/wxpython-binding-multiple-widgets-to-the-same-handler/
基本上你在循环中绑定然后在事件处理程序中,你可以使用event.GetEventObject()返回调用小部件并设置其值或其他。至于你的第四个问题,我会说不,你不需要OnSize方法。你几乎不需要在wxPython中覆盖它,我当然没有在我的示例代码中。
答案 1 :(得分:0)
我现在只回答3:为每个动态创建的小部件分配一个ID,将此ID存储在字典中({id:widget})并将回调函数作为lambda函数传递或使用functools.partial将ID传递给“真正的”回调。 (当然你可以直接在lambda函数上传递小部件,但是我喜欢在某个地方创建小部件的实例,如果我需要在某个时候访问它们的话)
def __init__(...):
self.event_dispatch = dict()
...
for id in xrange(500, 508):
wind = AddBox(self.scrolling_window, id)
...
self.event_dispatch[id] = wind
self.scrolling_window.Bind(wx.MY_EVENT, lambda evt: self.on_event(evt, id), id=id)
def on_event(event, id):
widget = self.event_dispatch[id]
# do something with widget