【问题标题】:In linux, wx.PopupWindow don't get any mouse event when it popup from wx.Dialog?在linux中,wx.PopupWindow从wx.Dialog弹出时没有得到任何鼠标事件?
【发布时间】:2012-02-01 10:14:47
【问题描述】:


大家好。

我有一个基于 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,上述情况在 wxPython 2.8.x 的 windows 版本中也不会发生,
它只发生在 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())

【问题讨论】:

  • 也许您可以添加一些代码,以便人们可以尝试一下,看看它是否特定于您的系统?您也可以尝试在 wxPython 邮件列表中询问。

标签: python linux wxpython wxwidgets


【解决方案1】:

不使用 PopupWindow,只显示第二个 wx.Dialog。或者打开一个框架。使用 ListCtrl 等复杂的小部件时,PopupWindows 可能有点奇怪。

【讨论】:

  • 我尝试使用 wx.Dialog 和 wx.Frame 代替 wx.PopupWindow,但是从 wx.Dialog 生成的任何窗口(通过调用 ShowModal() 启动)也没有反应。这是针对 Linux 的 wxPython 或 wxWidget 的问题吗?
  • 我不这么认为。不过,我手边没有 Linux 机器。你能交叉发布到 wxPython 邮件列表吗?他们可以肯定地告诉你。
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多