Quantcast
Channel: Planet Python
Viewing all articles
Browse latest Browse all 22462

Mike Driscoll: wxPython: Ensuring Only One Instance Per Frame

$
0
0

The other day, I came across an interesting StackOverflow question where the fellow was trying to figure out how to open a sub-frame only once. Basically he wanted a single instance of the sub-frame (and other sub-frames). After digging around a bit on Google, I found an old thread from the wxPython Google Group that had an interesting approach to doing what was needed.

Basically it required a bit of meta-programming, but it was a fun little exercise that I thought my readers would find interesting. Here’s the code:

import wx
 
########################################################################class MyPanel(wx.Panel):
    """""" 
    #----------------------------------------------------------------------def__init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent) 
 
########################################################################class SingleInstanceFrame(wx.Frame):
    """""" 
    instance = None
    init = 0 
    #----------------------------------------------------------------------def__new__(self, *args, **kwargs):
        """"""ifself.instanceisNone:
            self.instance = wx.Frame.__new__(self)elifisinstance(self.instance, wx._core._wxPyDeadObject):
            self.instance = wx.Frame.__new__(self)returnself.instance 
    #----------------------------------------------------------------------def__init__(self):
        """Constructor"""printid(self)ifself.init:
            returnself.init = 1 
        wx.Frame.__init__(self, None, title="Single Instance Frame")
        panel = MyPanel(self)self.Show() 
 
########################################################################class MainFrame(wx.Frame):
    """""" 
    #----------------------------------------------------------------------def__init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="Main Frame")
        panel = MyPanel(self)
        btn = wx.Button(panel, label="Open Frame")
        btn.Bind(wx.EVT_BUTTON, self.open_frame)self.Show() 
    #----------------------------------------------------------------------def open_frame(self, event):
        frame = SingleInstanceFrame() 
if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

The meat of this code is in the SingleInstanceFrame class, specifically in the __new__ method. Here we check to see if the variable self.instance is set to None. If so, we create a new instance. We will also create a new instance if the user closes the frame, which will cause it to become a wxPyDeadObject. This is what the second part of the if statement is for. It checks to see if the instance has been deleted and if it has, it creates a new instance.

You will also notice that we have a variable called self.init. This is used to check if the instance has already been initialized. If so, __init__ will just return instead of re-instantiating everything. Anyway, I hope you found that enlightening. Happy coding!

Related Reading


Viewing all articles
Browse latest Browse all 22462

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>