【问题标题】:wxpython: Why can't I check in wx.CheckListBox when Shift Key is down?wxpython:当 Shift 键按下时,为什么我不能签入 wx.CheckListBox?
【发布时间】:2018-12-06 17:13:39
【问题描述】:

我打算在按下 shift 键时进行一系列选择。但是,当按下 shift 键时,不会触发 wx.EVT_CHECKLISTBOX。以下是我的代码:

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "Different Frame", size=(300, 300))
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.prevIndex = None
        self.shift_down = False
        self.level = wx.CheckListBox(panel, -1)
        levels = ["%s" % i for i in range(9)]
        self.level.SetItems(levels)
        self.level.Bind(wx.EVT_CHECKLISTBOX, self.OnSelectLevel)
        self.level.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
        self.level.Bind(wx.EVT_KEY_UP, self.onKeyUp)

        panel.SetSizer(sizer)
        self.Centre()
        self.Show()

    def onKeyDown(self, event):
        print("onKeyDown")
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_SHIFT:
            self.shift_down = True
        else:
            event.Skip()

    def onKeyUp(self, event):
        print("onKeyUp")
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_SHIFT: 
            self.shift_down = False
        else:
            event.Skip()

    def OnSelectLevel(self, evt):
        print("OnSelectLevel")
        currindex = evt.GetInt()
        currCheckedItems = self.level.GetCheckedItems()
        if self.prevIndex != None and self.shift_down == True:
            if currindex > self.prevIndex:
                newrange = list(range(self.prevIndex, currindex))
            else:
                newrange = list(range(currindex, self.prevIndex, -1))
            newCheckedItems = currCheckedItems + newrange
            self.level.SetCheckedItems(newCheckedItems)
            self.prevIndex = currindex
            evt.Skip()

app = wx.App(0)
frame = MyFrame(None)
frame.Show()
app.MainLoop()

反正有没有触发事件 wx. EVT_CHECKLISTBOX 而 shift 键按下?谢谢。

【问题讨论】:

    标签: wxpython keyevent checklistbox


    【解决方案1】:

    您的属性self.prevIndex 永远不会被设置。 试试这个修改:

    def OnSelectLevel(self, evt):
        currindex = evt.GetInt()
        currCheckedItems = list( self.level.GetCheckedItems() )
        if self.prevIndex != None and self.shift_down == True:
            if currindex > self.prevIndex:
                newrange = list(range(self.prevIndex, currindex))
            else:
                newrange = list(range(currindex, self.prevIndex, -1))
            newCheckedItems = currCheckedItems + newrange
            self.level.SetCheckedItems(newCheckedItems)
        self.prevIndex = currindex
        evt.Skip()
    

    此外,使用wx.GetKeyState(wx.WXK_SHIFT) 来检查 OnSelectLevel 是否按下了 Shift 键更容易。

    一般来说,我总是建议使用好的调试器并在事件处理程序处设置断点。然后您可以交互式地检查并逐步执行。

    【讨论】:

    • @Dietmar Schwertberger:你说得对,prevIndex 永远不会被设置。但这里的问题是,当我按下 shift 并尝试检查一项时,该项目不会被检查(按下 shift 时无法打印文本“OnSelectLevel”)。
    • 请说明您的平台。在 Windows 上它工作正常。如果它在您的平台上不起作用,您可能必须找到一种解决方法(例如过滤事件并将修改后的事件发布到控件。也许,sizer 和复选框是更简单的解决方案......
    • 我在我测试的两个平台上遇到了同样的问题。一个是达尔文,python 3.6.5 Anaconda,4.0.3 osx-cocoa (phoenix) wxWidgets 3.0.5。另一个是Linux,Python 3.5.6, 4.0.3 gtk3 (phoenix) wxWidgets 3.0.5。
    • 在 Windows 上,wx 使用复选框的通用实现。请参阅此处获取源代码:github.com/wxWidgets/wxWidgets/blob/master/src/msw/checklst.cpp 该实现处理 EVT_LEFT_DOWN 而不检查 Shift。在 gtk 上,似乎可以使用本机 CheckListBox。
    • 如果原生小部件忽略 Shift-Clicks,那么您只有三种方法: - 尝试过滤事件并将非 Shift-Click 发布到小部件;我不能 100% 确定这是否可行 - 自己实现一个 CheckListBox 之类的小部件;也许使用 Windows 实现作为基础,但在 Python 中执行... - 使用不同的小部件,如对事件有更多控制的网格如果您自己找不到解决方案,我建议您在 wxPython 邮件中询问列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 2010-11-18
    • 1970-01-01
    相关资源
    最近更新 更多