除非具有焦点,否则wx.Dialog中的ESC键不会触发ID_CANCEL按钮

时间:2014-08-19 08:47:20

标签: python wxpython wxwidgets

根据文档,在wxPython中创建并与ShowModal一起显示的对话框应该通过搜索具有ID_CANCEL的按钮并模拟点击(即触发其EVT_BUTTON事件)来处理转义(ESC)键。

除了我的一个对话框之外,其他所有内容都有效。经过 lot 的调试后,我发现了取消按钮 - 或任何其他按钮! - 应该有重点。换句话说,只要我在我创建的其中一个按钮上调用.SetFocus(),ESC键就可以正常工作。

有人知道这里发生了什么吗?使用ShowModal()显示的对话框不能自动获得焦点吗?他们应该吗?或者我误解了什么?

在下面的示例代码中,取消注释b.SetFocus()行以查看差异:

import wx
class MainWindow(wx.Frame):
    def __init__(self, parent):
        super(MainWindow, self).__init__(parent)
        self.Show()
        d = SomeDialog(self)
        d.ShowModal()
        self.Destroy()
class SomeDialog(wx.Dialog):
    def __init__(self, parent):
        super(SomeDialog, self).__init__(parent)
        button = wx.Button(self, wx.ID_CANCEL, 'Cancel')
        button.Bind(wx.EVT_BUTTON, self.action_cancel)
        #button.SetFocus()
    def action_cancel(self, e):
        self.EndModal(wx.ID_CANCEL)
if __name__ == '__main__':
    app = wx.App(False)
    frame = MainWindow(None)
    app.MainLoop()

更新:在linux(Fedora 20,Gnome)上运行时会发生这种情况

1 个答案:

答案 0 :(得分:2)

您可以调用对话框的SetFocus()方法来设置焦点:

import wx

class MainWindow(wx.Frame):

    def __init__(self, parent):
        super(MainWindow, self).__init__(parent)
        self.Show()
        d = SomeDialog(self)
        d.ShowModal()
        self.Destroy()

class SomeDialog(wx.Dialog):

    def __init__(self, parent):
        super(SomeDialog, self).__init__(parent)
        button = wx.Button(self, wx.ID_CANCEL, 'Cancel')
        button.Bind(wx.EVT_BUTTON, self.action_cancel)
        self.SetFocus()

    def action_cancel(self, e):
        self.EndModal(wx.ID_CANCEL)

if __name__ == '__main__':
    app = wx.App(False)
    frame = MainWindow(None)
    app.MainLoop()

这适用于Kubuntu 14.04,包含wxPython 2.8.12.1和Python 2.7.6。但是,我怀疑当你将焦点设置到对话框时,它可能会将焦点传递给它的第一个子节点,就像wx.Panel一样。我不知道为什么Linux会以这种方式运行,但我同意@ nepix32和@VZ,这应该可以在没有SetFocus()的情况下工作。您可以将其称为解决方法,但您应该将其报告为错误。 wxPython website上有一个链接,您可以在其中提交错误报告。