在linux中,wx.PopupWindow从wx.Dialog弹出时没有得到任何鼠标事件?

时间:2012-02-01 10:14:48

标签: python linux wxpython wxwidgets


大家好。

我有一个基于wxPython 2.8.x的小python GUI程序。
它创建一个wx.Dialog小部件并通过调用ShowModal()来显示该对话框 在某些情况下,wx.Dialog将显示一个wx.PopupWindow,里面有一个wx.ListCtrl。
wx.PopupWindow正确显示,但是麻烦来了 wx.ListCtrl及其父窗口小部件wx.PopupWindow无法接收任何鼠标事件,
这导致wx.ListCtrl和wx.PopupWindow在用户生成任何鼠标操作时没有响应。

如果通过调用Show()打开wx.Dialog,则上述情况不会发生,wx.PopupWindow和wx.ListCtrl正常工作。

但是,即使我们通过调用ShowModal()来显示wx.Dialog,也不会在Windows版本的wxPython 2.8.x中发生上述情况,这只发生在Linux上。

有什么建议吗?

感谢。

这是我的源代码。
它可能太长但很容易测试上述情况(只需复制和粘贴)。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import wx



class TestPopupWindow(wx.PopupWindow): # modify here to change different Widget
    def __init__(self, *args, **kwargs):
        super(TestPopupWindow, self).__init__(*args, **kwargs)
        self.SetSize((200, 200))

        self.testButton = wx.Button(self, label='Test')

        self.testButton.Bind(wx.EVT_BUTTON, self.__onEvtButton, self.testButton)

        self.Show()

    def __onEvtButton(self, event):
        event.Skip()
        print 'PopupWindow: test button pushed!'
        self.Hide()


class TestDialog(wx.Dialog):
    def __init__(self, *args, **kwargs):
        wx.Dialog.__init__(self, *args, **kwargs)

        panel = wx.Panel(self)
        panel.SetAutoLayout(True)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Fit(panel)
        sizer.SetSizeHints(panel)
        panel.SetSizer(sizer)

        for i in xrange(2):
            ctrl = wx.TextCtrl(panel)
            sizer.Add(ctrl, 0, wx.ADJUST_MINSIZE|wx.EXPAND, 0)
        for i in xrange(2):
            ctrl = wx.ComboBox(panel)
            sizer.Add(ctrl, 0, wx.ADJUST_MINSIZE|wx.EXPAND, 0)

        self.openPopupWindowButton = wx.Button(panel, label='Open PopupWindow')
        sizer.Add(self.openPopupWindowButton, 0, 0, 0)

        standardDialogButtonSizer = wx.StdDialogButtonSizer()
        self.standardDialogButtonSizerOK = wx.Button(panel, wx.ID_OK)
        standardDialogButtonSizer.AddButton(self.standardDialogButtonSizerOK)
        self.standardDialogButtonSizerCancel = wx.Button(panel, wx.ID_CANCEL)
        standardDialogButtonSizer.AddButton(self.standardDialogButtonSizerCancel)
        standardDialogButtonSizer.Realize()
        sizer.Add(standardDialogButtonSizer, 0, wx.EXPAND, 0)

        panel.Layout()

        # event binding
        self.openPopupWindowButton.Bind(wx.EVT_BUTTON, self.__onEvtButtonOpenPopupWindow, self.openPopupWindowButton)

        self.popupWindow = None

    # event handler
    def __onEvtButtonOpenPopupWindow(self, event):
        event.Skip()

        if self.popupWindow is not None:
            self.popupWindow.Close()
        self.popupWindow = TestPopupWindow(self)



class TestFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        panel = wx.Panel(self)
        panel.SetAutoLayout(True)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Fit(panel)
        sizer.SetSizeHints(panel)
        panel.SetSizer(sizer)

        self.openButton = wx.Button(panel, label='Open Dialog')
        sizer.Add(self.openButton, 0, 0, 0)

        self.openPopupWindowButton = wx.Button(panel, label='Open PopupWindow')
        sizer.Add(self.openPopupWindowButton, 0, 0, 0)

        panel.Layout()

        # event binding
        self.openButton.Bind(wx.EVT_BUTTON, self.__onEvtButtonOpen, self.openButton)
        self.openPopupWindowButton.Bind(wx.EVT_BUTTON, self.__onEvtButtonOpenPopupWindow, self.openPopupWindowButton)

        self.Show()

        self.popupWindow = None

    # event handler
    def __onEvtButtonOpenPopupWindow(self, event):
        event.Skip()

        if self.popupWindow is not None:
            self.popupWindow.Close()
        self.popupWindow = TestPopupWindow(self)

    def __onEvtButtonOpen(self, event):
        event.Skip()
        dialog = TestDialog(self, title='TestDialog')
        result = dialog.ShowModal()
        if result == wx.ID_OK:
            print >>sys.stderr, 'OK!'
        else:
            print >>sys.stderr, 'Cancel!'



def main(argv=sys.argv[:]):
    app = wx.PySimpleApp()
    frame = TestFrame(None, title='TestFrame', style=wx.TAB_TRAVERSAL|wx.DEFAULT_FRAME_STYLE)
    app.SetTopWindow(frame)
    app.MainLoop()
    return 0



if __name__ == '__main__':
    sys.exit(main())

1 个答案:

答案 0 :(得分:0)

不要使用PopupWindow,只需显示第二个wx.Dialog。或者打开一个框架。对于像ListCtrl这样复杂的小部件,PopupWindows可能有些奇怪。