我有一个ListCtrl,可以使用各种项目进行自我更新。为此,我将其清空,然后添加几项。
然后,我想捕捉EVT_LIST_ITEM_FOCUSED事件。在Windows,Unix和MacOS上,它可以正常工作。
最后,我想在更新列表后捕获事件。在Unix和MacOS上会自动发生这种情况,但在Windows上并非如此。这就是为什么我想在“ update()”方法的末尾生成一个事件。
代码示例:
import wx
class MainFrame(wx.Frame):
def __init__(self):
super().__init__(None)
self.Show()
# Create the ListCtrl
self.list_ctrl = wx.ListCtrl(self, style=wx.LC_REPORT)
self.list_ctrl.AppendColumn("Column")
# Bind the event to the callback function
self.Bind(wx.EVT_LIST_ITEM_FOCUSED, self.on_focus, self.list_ctrl)
# Fill the list with fruits
self.update(["apples", "bananas", "pears"])
def update(self, name_list):
"""Refill the ListCtrl with the content of the list."""
# Empty the ListCtrl
self.list_ctrl.DeleteAllItems()
# Refill it
for element in name_list:
self.list_ctrl.Append([element])
def on_focus(self, event):
"""Print what is currently focused."""
focused = event.GetItem().GetText()
if focused == "":
print("No focus.")
else:
print(f"{focused} is focused.")
app = wx.App()
main_frame = MainFrame()
app.MainLoop()
在Unix和MacOS程序的开始处,此代码打印“ apples focus”。在Windows上,它不打印任何内容,因为未触发事件。我想要的是在Windows上收到消息“苹果已聚焦”。
约束:
Skip()
放到层次结构中更高的面板上。self.list_ctrl.Focus(0)
不起作用,因为在没有项目的情况下它不会执行任何操作。感谢您的帮助,祝您度过愉快的一天。
我在下面的代码中提供了保留。
您的示例代码和说明相互矛盾。您指的是将事件跳过到更高的面板,但是您的示例没有这样的代码。因此,我们处于有明确要求的位置,但不知道如何,为什么或何时实施该要求。
[Focused]和[Selected]之间有明显区别。我建议在这种情况下,最好使用Selected。
为了记录,尽管有您的评论,但如果列表项没有项目,请在self.list_ctrl.Select(0)
或self.list_ctrl.Focus(0)
的Linux上尝试都将使代码SetItemState(): invalid list ctrl item index in SetItem
崩溃。
import wx
class MainFrame(wx.Frame):
def __init__(self):
super().__init__(None)
self.some_sets = {
"fruits": ["apples", "bananas", "pears"],
"instruments": ["flutes", "drums", "guitars"],
"empty": [],
}
self.list_ctrl = wx.ListCtrl(self, style=wx.LC_REPORT)
self.list_ctrl.AppendColumn("Column")
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_focus, self.list_ctrl)
#self.update("empty")
self.update("fruits")
self.Show()
def update(self, set_name):
"""Refill the ListCtrl."""
# Empty the ListCtrl
self.list_ctrl.DeleteAllItems()
# Refill it
for element in self.some_sets[set_name]:
self.list_ctrl.Append([element])
if self.list_ctrl.GetItemCount():
#self.list_ctrl.Focus(0)
self.list_ctrl.Select(0)
else:
self.on_focus(None)
def on_focus(self, event):
"""Do something."""
if event:
focused = event.GetItem().GetText()
print(f"{focused} is Selected.")
else:
print("No focus.")
app = wx.App()
main_frame = MainFrame()
app.MainLoop()
[好,所以我找到了一种方法,通过摆脱一个约束来解决此问题(如果需要,我想Skip()
该事件)。
这是我使用的代码。
def update(self, name_list):
"""Refill the ListCtrl with the content of the list."""
self.list_ctrl.DeleteAllItems()
for element in name_list:
self.list_ctrl.Append([element])
# Call the callback functions
if self.list_ctrl.GetItemCount() == 0:
# Our custom one if there's no item in the list
self.on_focus_custom(None)
else:
# Else the classic function
self.list_ctrl.Focus(0)
def on_focus(self, event):
"""Call the on_focus_custom method with proper arguments."""
focused = event.GetItem().GetText()
if focused == "":
self.on_focus_custom(None)
else:
self.on_focus_custom(focused)
def on_focus_custom(self, focused):
"""Print what is currently focused."""
if focused is None:
print("No focus.")
else:
print(f"{focused} is focused.")
# Here, we can't skip the event, because we haven't one.
# So here a mediocre solution I found.
# Thats a method I defined in the upper Panel.
# self.GetParent().on_focus_custom(focused)
我很感兴趣,您有更清洁的方法。