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

标签 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没有响应。

如果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/

相关文章:

python - 从大型数据集中提取唯一数据

Python曲线拟合使用相对偏差而不是绝对偏差进行优化

Python:用于快速全屏 jpg/png 显示的 OSX 库

crash - ArcGIS 10 + wxPython:在ArcMap python命令窗口中键入 'import wx'时,ArcGIS崩溃

python - 如何检测 Pandas 时间序列中的间隙和连续周期

python - python停止异常传递

javaagent 选项不会扩展波形符,但为什么不呢

xml - 从两个不同内容之间的 XML 文件中获取数据

linux - 如何知道当前进程数以及哪个进程派生了最多进程?

grid - WxPython:如何获取wx网格中显示单元格的范围?