SO的第一个问题。
当用户点击ListCtrl小部件时,它会生成EVT_LIST_ITEM_SELECTED事件。 但是,如果我想在显示给用户之前设置列表,以便突出显示多个项目(通过调用ListCtrl上的Select()),窗口小部件将生成相同的事件。我的应用程序错误地处理了此事件,就像它是真正的用户选择一样。
当wxPython使用消息传递时,我不能简单地设置一个标志(ignore_selection_events),然后再进行编程选择,然后再将其清除。在所有可能的情况下,在调用第一个EVT_LIST_ITEM_SELECTED处理程序/回调之前,该标志将被清除。
我试过的一些解决方案出了什么问题:
ListCtrl的成员允许关闭EVT_LIST_ITEM_SELECTED的生成。 我看了,我确定这不存在。
我可以使用wx.Timer来延迟在最后一次调用Select()后的一段时间内取消设置ignore_selection_event标志。 准确的时间容易出错。它可能不起作用(时间太短)或可能导致真正的用户选择丢失(计时器太长)。
应该可以使用PostEvent或ProcessEvent让ListCtrl在生成第一个EVT_LIST_ITEM_SELECTED之前生成一个特殊的ignore_selections事件,并在生成第一个EVT_LIST_ITEM_SELECTED之后生成另一个事件。 我尝试了这个但是忽略事件消息的回调没有按照我预期的顺序调用:
evt = MyEvent(myEVT_TOGGLE_SELECTION_IGNORE)
wx.PostEvent(self.list_ctl, evt) //this handler called fist
wx.CallAfter (self.list_ctl.Select, item, 1) //this handler called last (grrr)
evt = MyEvent(myEVT_TOGGLE_SELECTION_IGNORE)
wx.PostEvent(self.list_ctl, evt) //this handler called second
最后,我想到了暂时取消绑定EVT_LIST_ITEM_SELECTED的事件处理程序。这可能会遇到与使用标志相同的问题。即在wxPython转向异步处理Select()调用之前,处理程序将被替换,因此仍然会调用处理程序。 试过这个,它会让gui立即挂起。我尝试使用self.list_ctl.Bind(wx.EVT_LIST_ITEM_SELECTED, do_nothing)
,但没有使用CallAfter,在两种情况下,gui都会立即挂起。
好的,谢谢你!
更新
谢谢杰夫!根据我的尝试获得更多信息。
list_ctrl.SetItemState(item_index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) #works
list_ctrl.SetItemState(item_index, 0xFFFFFFFF, wx.LIST_STATE_SELECTED) #works
list_ctrl.SetItemState(item_index, 1, wx.LIST_STATE_SELECTED) # does NOT work
因此,使用state和mask args是这样的,你可以轻松地修改项状态,而不必先读取当前状态,或者在所需的修改位中,然后回写。
答案 0 :(得分:1)
试试SetItemState
。我在代码中使用以下内容取消选择项目:
self.ballotC.SetItemState(c, 0, wx.LIST_STATE_SELECTED)
我会尝试
self.ballotC.SetItemState(c, 1, wx.LIST_STATE_SELECTED)
或
self.ballotC.SetItemState(c, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
选择一个项目。有一些文档here。它不是那么清晰,所以你必须玩一会儿,直到你做对了。