Closing taskbaricon app from any frame/window

1,140 views
Skip to first unread message

Pedro Sequeira

unread,
Jul 8, 2019, 7:07:10 PM7/8/19
to wxPython-users
Hi,

I have this example that has a trayicon with a menu, in the menu one option is to close the app, which works, the other opens a new frame

I want to have a button on that new frame that closes "everything", so I tried to have it call the function inside the other classes that closes everything, but it is not working and I don't know how to fix it, I hve tried "Close", the actual function that closes everything, closing from the Menu function, destroy, and searched a lot, but I guess this is just some basic thing that I am messing up.. thanks for the help

(it should still work without the file for the icon image.. well, except the part that doesn't work :)

***

import wx, wx.adv

class Extra(wx.Frame):
    def __init__(self, parent, id, title, lingua):
        estilo = wx.CLIP_CHILDREN | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(750, 200), style=estilo)
        self.Centre()
        self.Show()

        wx.Button(self, 1, "OK", (20, 160))
        self.Bind(wx.EVT_BUTTON, self.Ok, id=1)
        wx.Button(self, 2, "Close", (500, 160))
        self.Bind(wx.EVT_BUTTON, self.CloseAll, id=2)

    def Ok(self, event):
        self.Close()
# --------------------------------------------------------------------------------------- the problem (maybe
    def CloseAll(self, event):
        MyFrame.Close()
# ---------------------------------------------------------------------------------------


class MyTaskBarIcon(wx.adv.TaskBarIcon):
    def __init__(self, frame):
        wx.adv.TaskBarIcon.__init__(self)

        self.frame = frame
        self.SetIcon(wx.Icon('toggle1.png', wx.BITMAP_TYPE_PNG), 'mytaskbaricon.py')
        self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=3)
        self.Bind(wx.EVT_MENU, self.OnExtra, id=4)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        menu.Append(3, 'Close')
        menu.Append(4, 'Extra')
        return menu

    def OnExtra(self, event):
        Extra(None, 50, 'titulo do frame? importa?', "ze")

    def OnTaskBarClose(self, *args):
        self.frame.Close()

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, (-1, -1), (290, 280))

        self.tskic = MyTaskBarIcon(self)
        self.Centre()
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def OnClose(self, *args):
        self.tskic.Destroy()
        self.Destroy()

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'mytaskbaricon.py')
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

app = MyApp(0)
app.MainLoop()


Tim Roberts

unread,
Jul 9, 2019, 12:59:55 AM7/9/19
to 'Khanh D Dang' via wxPython-users
On Jul 8, 2019, at 4:07 PM, Pedro Sequeira <sequeira...@gmail.com> wrote:
>
> I have this example that has a trayicon with a menu, in the menu one option is to close the app, which works, the other opens a new frame
>
> I want to have a button on that new frame that closes "everything", so I tried to have it call the function inside the other classes that closes everything, but it is not working and I don't know how to fix it, I hve tried "Close", the actual function that closes everything, closing from the Menu function, destroy, and searched a lot, but I guess this is just some basic thing that I am messing up.. thanks for the help

You are confusing a class with an instance of a class. If you want CloseAll in the Extra class to be able to close the MyFrame instance, then you have to pass that instance in. So, for example:

class Extra(wx,Frame):
def __init__(self, parent, id, title, lingua, frame):
self.frame = frame

def CloseAll(self, event):
self.frame.Close()

class MyTaskBarIcon…
def OnExtra(self, event):
Extra(None, 50, ”titulo do frame? importa?”, “ze”, self.frame )



Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Pedro Sequeira

unread,
Jul 10, 2019, 11:03:52 AM7/10/19
to wxPython-users
Thanks a lot Tim, it worked, I'll leave the full example in case it helps someone, and I'll also ask another thing, more out of curiosity since the problem i had is now fixed

If I open the new "Extra" frame, and then close the main frame, or select close on the tray menu, the tray and main frame will close, but the "Extra" one will remain open.

Then, if I click "OK" it goes away, and the app shuts down, but if i click "Close" there will be an error since the other stuff has been closed already: "RuntimeError: wrapped C/C++ object of type MyTaskBarIcon has been deleted"

My question is, is there a way to "link" everything so that when we close the main frame or using the tray menu the "Extra" frame will also close? (in case it was open


import wx, wx.adv

class Extra(wx.Frame):
    def __init__(self, parent, id, title, lingua, frame):
        estilo = wx.CLIP_CHILDREN | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP
        wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(750, 200), style=estilo)
        self.Centre()
        self.Show()
        self.frame = frame
        wx.Button(self, 1, "OK", (20, 160))
        self.Bind(wx.EVT_BUTTON, self.Ok, id=1)
        wx.Button(self, 2, "Close", (500, 160))
        self.Bind(wx.EVT_BUTTON, self.CloseAll, id=2)

    def Ok(self, event):
        self.Close()

    def CloseAll(self, event):
        self.Close()
        self.frame.FecharTudo()


class MyTaskBarIcon(wx.adv.TaskBarIcon):
    def __init__(self, frame):
        wx.adv.TaskBarIcon.__init__(self)

        self.frame = frame
        self.SetIcon(wx.Icon('toggle1.png', wx.BITMAP_TYPE_PNG), 'mytaskbaricon.py')
        self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=3)
        self.Bind(wx.EVT_MENU, self.OnExtra, id=4)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        menu.Append(3, 'Close')
        menu.Append(4, 'Extra')
        return menu

    def OnExtra(self, event):
        Extra(None, 50, 'titulo do frame? importa?', "ze", self.frame)

    def OnTaskBarClose(self, *args):
        self.frame.Close()

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, (-1, -1), (290, 280))

        self.tskic = MyTaskBarIcon(self)
        self.Centre()
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def FecharTudo(self, *args):
        self.tskic.Destroy()
        self.Destroy()

    def OnClose(self, *args):
        self.tskic.Destroy()
        self.Destroy()
        

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'mytaskbaricon.py')
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

app = MyApp(0)
app.MainLoop()

On Tuesday, 9 July 2019 05:59:55 UTC+1, Tim Roberts wrote:
Reply all
Reply to author
Forward
0 new messages