Контрол, прописанный в классе, принимает атрибуты лишь при инициации экземпляра класса с его участием

Класс Parameters отрабатывает сеттеры и геттеры класса GroupControls. Сам GroupControls задуман как пользовательский элемент управления. Для упрощения восприятия кода я убрал из класса контрола все лишнее, то есть отработку событий и дополнительные элементы управления.

ВОПРОСЫ:

  1. Почему виртуальные параметры класса у меня принимают/отдают значения, но не меняют их у "реального" объекта, прописанного в классе. В данном случае кнопке не навязывается новая надпись.
  2. Как сделать, чтобы передача все же происходила?

P.S. Прошу не указывать на бессмысленность действия (навязывания кнопке надписи). Мне нужно просто разобраться с ПРИНЦИПОМ передачи данных извне контролам внутри класса.

import wx


class Parameters:
    def __init__(self, name):
        self.__name = name
 
    def __get__(self, instance, owner):
        print('Проход через GET. Новое значение ', instance.__dict__[self.__name])
        return instance.__dict__[self.__name]
 
    def __set__(self, instance, value):
        print('Проход через SET. Значение заменено на %s'  % (value))
        instance.__dict__[self.__name] = value

class GroupControls(wx.Control):
    ID=Parameters('ID')
    textbtn=Parameters('textbtn')
 
    def __init__(self, parent, ID=0, textbtn='Название'):
        """Constructor"""
        wx.Control.__init__(self, parent, pos = wx.DefaultPosition, size=(177,33), style=wx.BORDER_NONE )

        self._ID=id
        self._textbtn=str(textbtn)
        
        self.btn = wx.Button(self, id=ID, label=textbtn, name="one",
                             pos=(2,5), size=(80,25) )


class Form(wx.Frame):
    
    def __init__(self):
        wx.Frame.__init__(
            self, None, title="Проба", style=wx.DEFAULT_FRAME_STYLE, size=(200,200),pos =(400,400))
        panel = wx.Panel(self, wx.ID_ANY, size=(200,200) , style=wx.CENTRE)

        
        sizer = wx.BoxSizer(wx.VERTICAL)

        
        
        self.but1=GroupControls(panel, ID=0, textbtn='Январь')
        
        sizer.Add(self.but1, 0, wx.ALL,0)
        
        
        self.but2=GroupControls(panel,ID=1, textbtn='Февраль' )
        sizer.Add(self.but2, 0, wx.ALL, 0)

        self.butSet = wx.Button(panel, label='Передать', name="one")
        
        self.butSet.Bind(wx.EVT_BUTTON, self.onButton)
        sizer.Add(self.butSet, 0, wx.ALL, 1)
        self.SetSizer(sizer)

        

    def onButton(self, event):
        self.butSet.SetLabel('Передано')
        
        self.but1.textbtn='Декабрь'
        print('Запрос из формы - ', self.but1.textbtn)
        #print(self.ccc.textbtn)
        


if __name__ == "__main__":
    app = wx.App(False)
    frame = Form()
    
    frame.Show()
    app.MainLoop()

Ответы (1 шт):

Автор решения: gil9red

Я так понимаю, вопрос к Parameters и почему оно не меняет значение кнопки при изменении его через Parameters.

Причина в том, что в self.btn (wx.Button) значение в label передается из параметра конструктора, т.е. строка. А меняете вы у значение у textbtn, который никак не связан с self.btn.

Не смог придумать как извернуться с Parameters, чтобы оно меняло значение в self.btn, поэтому предлагаю решение через property.

Поменяйте GroupControls на этот, тогда при self.but1.textbtn='Декабрь' будет вызван @textbtn.setter def textbtn(self, value).

Пример:

class GroupControls(wx.Control):
    def __init__(self, parent, ID=0, textbtn='Название'):
        super().__init__(parent, pos=wx.DefaultPosition, size=(177, 33), style=wx.BORDER_NONE)

        self._ID = ID
        self.btn = wx.Button(self, id=self._ID, label=textbtn, name="one", pos=(2, 5), size=(80, 25))

    @property
    def textbtn(self):
        return self.btn.Label

    @textbtn.setter
    def textbtn(self, value):
        self.btn.Label = value

Скриншот:

введите сюда описание изображения

→ Ссылка