大家好。
我有一个基于 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没有响应。
如果wx.Dialog是通过调用Show()打开的,
上述情况就不会发生,wx.PopupWindow和wx.ListCtrl可以正常工作。
但是,在 Windows 版本的 wxPython 2.8.x 中,即使我们通过调用 ShowModal() 显示 wx.Dialog,上述情况也不会发生,
只有在 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())
最佳答案
不使用 PopupWindow,而是显示第二个 wx.Dialog。或者打开一个框架。对于像 ListCtrl 这样的复杂小部件,PopupWindows 可能有点奇怪。
关于python - 在linux中,wx.PopupWindow从wx.Dialog弹出时没有得到任何鼠标事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9094086/