Создать EVT_LIST_ITEM_FOCUSED при обновлении ListCtrl - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть 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()

Этот код напечатан "apple is сосредоточено" на запуск программы с Unix и MacOS. На Windows ничего не печатается, потому что событие не вызвано. Я хочу получить сообщение «Яблоко сфокусировано» на Windows.

Ограничения:

  • Я хочу использовать событие, потому что я намерен на Skip() это на панель выше в иерархии ie.
  • Я хочу установить это событие с текстом элемента по своему выбору, чтобы программа могла напечатать «Нет фокуса», если в ListCtrl. Таким образом, вызов self.list_ctrl.Focus(0) не работает, так как он ничего не делает, когда нет предметов.

Спасибо за помощь и хорошего дня.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Я предоставляю код ниже с оговорками.

Ваш пример кода и пояснения противоречат друг другу.
Вы имеете в виду пропуск события на более высокую панель, но в вашем примере такого кода нет. Таким образом, мы остаемся в положении, когда у нас есть заявленное требование, но мы не знаем, как, почему или когда оно должно быть выполнено.

Существует четкое различие между Сосредоточенным и Выбранным. Я полагаю, что в этих обстоятельствах вам лучше использовать Selected.

Для записи, несмотря на ваш комментарий, с listctrl без элементов попробуйте Linux либо self.list_ctrl.Select(0) или self.list_ctrl.Focus(0), оба взломают sh ваш код 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 голосов
/ 10 апреля 2020

Хорошо, поэтому я нашел способ обойти проблему, избавившись от одного ограничения (я хотел 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)

У меня есть более чистые способы сделать это, мне интересно.

...