在ListCtrl更新时生成EVT_LIST_ITEM_FOCUSED

问题描述 投票:0回答:2

我有一个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()放到层次结构中更高的面板上。
  • 我想使用我选择的项目文本来设置此事件,因此,如果ListCtrl中没有项目,程序可以打印“ No focus”。因此,调用self.list_ctrl.Focus(0)不起作用,因为在没有项目的情况下它不会执行任何操作。

感谢您的帮助,祝您度过愉快的一天。

wxpython listctrl
2个回答
1
投票

我在下面的代码中提供了保留。

您的示例代码和说明相互矛盾。您指的是将事件跳过到更高的面板,但是您的示例没有这样的代码。因此,我们处于有明确要求的位置,但不知道如何,为什么或何时实施该要求。

[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()

0
投票

[好,所以我找到了一种方法,通过摆脱一个约束来解决此问题(如果需要,我想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)

我很感兴趣,您有更清洁的方法。

© www.soinside.com 2019 - 2024. All rights reserved.