Не привязывайте запись файла в Bind to wx. Пуговицы в петле - PullRequest
0 голосов
/ 19 июня 2020

Приветствую уважаемое сообщество!

У меня следующая задача: Мне нужно создать панель с кнопками, названия которых взяты из файла (all_classes). При нажатии на каждую метку кнопки должны быть записаны в другом файле (selected_classes). Мне удалось создать кнопки в l oop и расположить их на панели, но событие записи к кнопке не привязано и не понимаю почему.

all_classes = open('data/yolo2/yolo2.names', 'r').read().split()
chosen_classes = open('chosen_classes', 'w')

deltaxSize, deltaySize, c = 0, 0, 0
        for k, obj_class in enumerate(all_classes):
            self.buttons.append(wx.Button(self.panel, label=f'{obj_class}', pos=(50 + deltaxSize, 20 + deltaySize),
                                       size=(100, 20)))
            self.Bind(wx.EVT_BUTTON, lambda event: chosen_classes.write(f'{obj_class}\n'), self.buttons[k])
            deltaySize += 20
            c += 1
            if c == 30:
                deltaxSize += 100
                deltaySize, c = 0, 0

Пробовал вместо записи в лямбда просто печатает, чтобы проверить, что происходит, но дает странный результат: когда вы нажимаете любую кнопку, отображается только последняя метка:

deltaxSize, deltaySize, c = 0, 0, 0
        self.buttons = []
        for k, obj_class in enumerate(all_classes):
            self.buttons.append(wx.Button(self.panel, label=f'{obj_class}', pos=(50 + deltaxSize, 20 + deltaySize),
                                       size=(100, 20)))
            self.Bind(wx.EVT_BUTTON, lambda event: print(f'{obj_class}\n'), self.buttons[k])
            deltaySize += 20
            c += 1
            if c == 30:
                deltaxSize += 100
                deltaySize, c = 0, 0

То же самое происходит, если вы заменяете obj_class в f- линия с self.buttons [k]. GetLabelText () В то же время, если вы обращаетесь к каждой кнопке отдельно вне l oop, вы можете распечатать этикетку, но файл все равно не будет записывать. Я, по общему признанию, совершенно озадачен, если кто-нибудь может что-то подсказать, буду бесконечно благодарен. Спасибо.

1 Ответ

0 голосов
/ 19 июня 2020

Вам удалось немного усложнить ваше решение.
Использование sizer упростит задачу, и поскольку единственное, что запускается event, - это событие кнопки, и все они делают то же самое, мы нужно всего bind один раз.
Выбрать кости из следующего, это должно помочь.

import wx

all_classes = ["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"]
chosen_classes = open('chosen_classes.txt', 'w')

class ButtonPanel(wx.Panel):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(self.sizer)
        self.parent = parent

        for k, obj_class in enumerate(all_classes):
            self.add_button(obj_class)
        self.Bind(wx.EVT_BUTTON, self.OnButton)
        self.parent.Layout()

    def add_button(self, obj_class):
        self.sizer.Add(wx.Button(self, label=f'{obj_class}'), 0, wx.EXPAND, 0)

    def OnButton(self,event):
        obj = event.GetEventObject()
        label = obj.GetLabel()
        chosen_classes.write(label+" Pressed\n")
        print(label)

class MyPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.button_panel = ButtonPanel(self)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.button_panel, 0, wx.EXPAND, 0)
        self.SetSizer(sizer)

class MyFrame(wx.Frame):
    def __init__(self, *args):
        super().__init__(*args)
        panel = MyPanel(self)


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

app.MainLoop()

enter image description here

...