首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

[d]wxPython的button点击响应事件为啥发生两次

2013-01-19 
[d]wxPython的button点击响应事件为什么发生两次本帖最后由 fibbery 于 2012-08-25 21:39:26 编辑使用的版

[d]wxPython的button点击响应事件为什么发生两次
本帖最后由 fibbery 于 2012-08-25 21:39:26 编辑 使用的版本信息为:
python:2.5.1
wxPython:wxPython2.8-win32-unicode-2.8.7.1-py25
代码如下:


import wx

class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Hello My World")
b = wx.Button(self, -1, "Create and Show a Frame", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Show()
def OnButton(self, evt):
dlg = wx.MessageDialog(self, 'Hello from Python and wxPython!',
'A Message Box',
wx.OK | wx.ICON_INFORMATION
#wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION
)
dlg.ShowModal()
dlg.Destroy()
evt.Skip()
def OnClose(self, evt):
dlg = wx.MessageDialog(self, 'Are you sure you want to close My World?',
'Closing...', wx.YES_NO | wx.ICON_QUESTION)
ret = dlg.ShowModal()
dlg.Destroy()
if ret == wx.ID_YES:
evt.Skip()

app = wx.App(0)
MyFrame()
app.MainLoop()

现在的问题是:我点击button之后对话框会出现两次,搞了好久,
实在是搜索不到答案了,请各位大侠帮忙看下,thks!!!---------------------
Double行动:
原帖分数:40
帖子加分:40

[解决办法]
代码看起来没问题,在我的机器上(linux+python2.7+wxpython2.8)运行也没问题。

对话框是两个一起出现?还是关上一个又出一个?

怀疑是鼠标灵敏度的问题。试试用键盘的回车键来打开/关上对话框。
[解决办法]
引用:
关键的问题是我不明白为什么我在frame中捕捉到了事件,然后skip,让事件抛向上层继续处理
但是frame的parent为空,按理说应该不会出现第二个弹出窗口啊,这才是我不明白的地方


我还是觉得这个问题不是skip引起的。在下面的代码中,onButton会改变事件的id,如果是同一个事件引起onButton运行两次,则会打印出连续的id。用你的有问题的环境组合运行它,看错误发生时输出是什么?


import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Hello My World")
        #panel = wx.Panel(self, -1)
        b = wx.Button(self, -1, "Create and Show a Frame", (50,50))
        self.Bind(wx.EVT_BUTTON, self.OnButton, b)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.Show()
    def OnButton(self, evt):
        print "before change id:", evt.GetId()
        evt.SetId(evt.GetId()+1)
        print "after change id:", evt.GetId()
        dlg = wx.MessageDialog(self, 'Hello from Python and wxPython!',
                                'A Message Box',
                                wx.OK 


[解决办法]
 wx.ICON_INFORMATION
                                #wx.YES_NO 
[解决办法]
 wx.NO_DEFAULT 
[解决办法]
 wx.CANCEL 
[解决办法]
 wx.ICON_INFORMATION
                                )
        dlg.ShowModal()
        dlg.Destroy()
        evt.Skip()
    def OnClose(self, evt):
        print evt.GetTimestamp()
        dlg = wx.MessageDialog(self, 'Are you sure you want to close My World?',
                                'Closing...', wx.YES_NO 
[解决办法]
 wx.ICON_QUESTION)
        ret = dlg.ShowModal()
        dlg.Destroy()
        if ret == wx.ID_YES:
            evt.Skip()

app = wx.App(0)
MyFrame()
app.MainLoop()



在我的机器上,稍慢一点的点击有时会引起两个对话框的情况,我的观察是:在鼠标按键没有抬起时,对话框就关闭了,露出主窗口的按钮(B)呈按下状态(因为按钮B充满了整个主窗口),按键再抬起,就形成了对B的一次点击,对话框又出现了。

你把按钮放到panel中,按钮就不再充满整个主窗口,从而和对话框的“ok”按钮没有重叠的部分,我上面描述的情况就被避免了,也就不会再有一个对话框弹出。
[解决办法]
引用:
为了避免一个按钮充满frame,我添加了两个按钮,这个时候,点击任意一个button都会
弹出两次窗口,输出的id为:
before change id: -202
after change id: -201
before change id: -202
after change id: -201


这说明onButton的两次调用是由两个不同的evt(两个不同的点击)引起的,否则输出应该是-202, -201, -201, -200,就像下面的代码演示的一样。下面的代码把button放到了panel中,然后让panel也响应EVT_BUTTON。

下面的代码在你的环境下应该产生类似于“-202, -201, -201, -200, -202, -201, -201, -200”的输出。

弄不懂第二次点击是怎么产生的。另外用回车键关闭对话框会有什么现象?


import wx

class MyFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Hello My World")
        panel = wx.Panel(self, -1)
        b = wx.Button(panel, -1, "Frame", (50,50))
#        c = wx.Button(self, -1, "Create", (150,50))
        self.Bind(wx.EVT_BUTTON, self.OnButton)
        panel.Bind(wx.EVT_BUTTON, self.OnButton)
        self.Bind(wx.EVT_CLOSE, self.OnClose)


        self.Show()
    def OnButton(self, evt):
        print "before change id:", evt.GetId()
        evt.SetId(evt.GetId()+1)
        print "after change id:", evt.GetId()
        dlg = wx.TextEntryDialog(self, 'Hello from Python and wxPython!',
                                'A Message Box','text',
                                wx.OK 
[解决办法]
 wx.ICON_INFORMATION
                                #wx.YES_NO 
[解决办法]
 wx.NO_DEFAULT 
[解决办法]
 wx.CANCEL 
[解决办法]
 wx.ICON_INFORMATION
                                )
        dlg.ShowModal()
        dlg.Destroy()
        evt.Skip()
    def OnClose(self, evt):
        print evt.GetTimestamp()
        dlg = wx.MessageDialog(self, 'Are you sure you want to close My World?',
                                'Closing...', wx.YES_NO 
[解决办法]
 wx.ICON_QUESTION)
        ret = dlg.ShowModal()
        dlg.Destroy()
        if ret == wx.ID_YES:
            evt.Skip()

app = wx.App(0)
MyFrame()
app.MainLoop()



热点排行