我刚刚开始使用wxPython,这就是我想要做的事情:
a)显示一个框架(里面有面板)和该面板上的一个按钮。 b)当我按下按钮时,会弹出一个对话框(我可以从一个选项中选择)。 c)当我按下确定对话框时,对话框应该消失(销毁),但原始的Frame + Panel +按钮仍然存在。 d)如果我再次按下该按钮,将重新出现该对话框。
我的代码如下。 不幸的是,我得到相反的效果。也就是说,
a)选择对话框首先显示(即,不会点击任何按钮,因为从不显示TopLevelframe +按钮)。
b)当我在对话框中单击“确定”时,将显示带有按钮的框架。
c)再次单击按钮无效(即,对话框不再显示)。
我做错了什么?看起来,只要帧被初始化(甚至在调用.Show()之前),对话框就会被初始化并自动显示。
我在WindowsXP上使用Eclipse + Pydev和Python 2.6进行此操作
import wx
import MyDialog #This is implemented in another file: MyDialog.py
class TopLevelFrame(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id,"Test",size=(300,200))
panel=wx.Panel(self)
button=wx.Button(panel, label='Show Dialog', pos=(130,20), size=(60,20))
# Bind EVENTS --> HANDLERS.
button.Bind(wx.EVT_BUTTON, MyDialog.start(self))
# Run the main loop to start program.
if __name__=='__main__':
app=wx.PySimpleApp()
TopLevelFrame(parent=None, id=-1).Show()
app.MainLoop()
import wx
def start(parent):
inputbox = wx.SingleChoiceDialog(None,'Choose Fruit', 'Selection Title',
['apple','banana','orange','papaya'])
if inputbox.ShowModal()==wx.ID_OK:
answer = inputbox.GetStringSelection()
inputbox.Destroy()
答案 0 :(得分:2)
有很多方法可以做到这一点,但要对代码进行最少量的更改,
将def start(parent):
更改为
def start(parent, evt):
将button.Bind(wx.EVT_BUTTON, MyDialog.start(self))
更改为
button.Bind(wx.EVT_BUTTON, lambda evt: MyDialog.start(self, evt))
也就是说,Bind中的第二个参数需要是一个带有事件的函数,并且需要在单击按钮时创建对话框。 lambda
使得这个函数也可以使用parent和evt(您也可以使用functools.partial作为版本> 2.5),然后单击该按钮时,将调用start
来创建对话框。
我不太确定您的代码中发生了什么,但似乎您正在调用start
并在初始调用Bind时创建对话框,然后从start传递返回值,{ {1}}要绑定。
注1
更详细地说,在这里使用lambda的原因是Bind应该有一个像None
这样的形式,其中Bind(event, handler)
是wx.PyEventBinder,就像wx.EVT_BUTTON一样,event
是< em> function 就像foo(evt),其中evt是wx.Event或wx.CommandEvent。 (这里没有递归,因为你只是说当事情发生时要做什么,但事情还没有发生,所以事件还没有被创建。当事件发生时,它将由wx表示.Event,它将包含有关事件的信息,例如鼠标点击时的位置等。)
注2 在我的回答中,我试图以最小的变化回答你的问题,因为我认为这是最简单的。也许下面的代码更清晰(也许通常最清楚的是处理创建它们的小部件中的事件):
handler