Search code examples
pythonwxpythonwxwidgets

Buttons disappearing after creation


I need to programatically create a button each time an event happens. I've got the call coming through with pubsub, the button is created but instantly disappears afterwards (sort of blinks on a panel).

class panel_one (wx.Panel) :

def __init__(self, parent) :
    """Constructor"""
    super().__init__(parent)
    pub.subscribe(self.my_listener, "panel_listener")
    self.btns = 1
    self.new_btn = ''
    wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.Size (1280, 150),
                       style=wx.TAB_TRAVERSAL)

    self.sbSizer4 = wx.StaticBoxSizer (wx.StaticBox (self, wx.ID_ANY, u"label"), wx.HORIZONTAL)

    self.m_button24 = wx.Button (self.sbSizer4.GetStaticBox (), wx.ID_ANY, u"Tech", wx.DefaultPosition,
                                 wx.Size (100, 100), 0)
    self.m_button24.Bind(wx.EVT_BUTTON, self.ShowTech)
    self.sbSizer4.Add (self.m_button24, 0, wx.ALL, 5)

    self.m_button241 = wx.Button (self.sbSizer4.GetStaticBox (), wx.ID_ANY, u"Info", wx.DefaultPosition,
                                  wx.Size (100, 100), 0)
    self.m_button241.Bind(wx.EVT_BUTTON, self.ShowInfo)
    self.sbSizer4.Add (self.m_button241, 0, wx.ALL, 5)

    self.SetSizer (self.sbSizer4)
    self.Layout ()

def my_listener(self, message):
    self.ButtonPost(message)

def ButtonPost(self, label) :
    self.new_btn = wx.Button (self.sbSizer4.GetStaticBox (), wx.ID_ANY, label, wx.DefaultPosition,
                                  wx.Size (100, 100))
    self.new_btn.Show()
    self.btns += 1
    self.sbSizer4.Add(self.new_btn, 0, wx.CENTER|wx.ALL, 5)
    self.sbSizer4.Layout()

I tried to refresh and/or update the panel and/or frame.

Any thoughts?

Edit: So i did a thing where I create them manually with another button, tried calling the listener and or the function it calls. Result: Panel

class panel_three (wx.Panel) :
# TECH
def __init__(self, parent) :
    super().__init__(parent)
    pub.subscribe(self.my_listener, "switch_panel")
    pub.subscribe(self.my_listener1, "new_call")
    wx.Panel.__init__ (self, parent, id=wx.ID_ANY, pos=(0, 150), size=wx.Size (1280, 874),
                       style=wx.TAB_TRAVERSAL)
    self.bSizer10 = wx.BoxSizer(wx.HORIZONTAL)
    self.testtrigger = wx.Button(self, wx.ID_ANY, u"MANUAL", wx.DefaultPosition,
                                 wx.Size (100, 50), 0)
    self.bSizer10.Add(self.testtrigger, 0, wx.ALL, 5)
    self.testtrigger.Bind(wx.EVT_BUTTON, lambda event: self.my_listener1('manually\ncreated'))
    self.SetSizer(self.bSizer10)
    self.Layout()

def ButtonPost(self, label) :
    new_btn = wx.Button(self, wx.ID_ANY, label, wx.DefaultPosition,
                                 wx.Size (100, 50), 0)
    self.bSizer10.Add(new_btn, 0, wx.ALL, 5)
    self.bSizer10.Layout()
    self.Update()

def my_listener(self, message):
    self.SwitchPanel(message)

def my_listener1(self, message):
    self.ButtonPost(message)

def SwitchPanel(self, which):
    if which == 'TECH':
        self.Show()
    else:
        self.Hide()

Solution

  • So to repeat:

    When I press a button in Frame A it triggers an event doing bunch of things among which it is supposed to create a button in Frame B with a certain name, communication happening through pypubsub.

    The problem:

    The event is triggered , pypubsub event gets posted from Frame A, recieved in Frame B, button gets created and instantly disappears.

    Posting to pypubsub was called from within a handler triggered by a button such as:

    def handler(self, event):
        # do some stuff
        self.postnewbutton(self, arg1, arg2)
        # do some other stuff
    

    The solution:

    I could either create another binding straight to the button and make the function get the params some other way or just create a new thread for it in a thread handler.

    I now realize how jank my design is.