sawyermclane
sawyermclane

Reputation: 1066

wxPython: Ensure only one instance of a panel is open

I'm writing a multi-window, multi-frame application. For every new window/frame that is opened, there should be one and only one instance of that window. I want the user to be able to quickly switch between these windows, so ShowModal() does not work. I've tried using SingleInstanceChecker, but I can't get it to work as it's more for Apps than for frames. How should I accomplish this?

Upvotes: 1

Views: 871

Answers (2)

sawyermclane
sawyermclane

Reputation: 1066

I found another way to do this in addition to Mike's answer, so I figured I'd post it in case anyone needed it.

SingleInstanceChecker does in fact work for wx.Frames and wx.Panels. It works the same way as it would in an App.

Put this snipped of code in the __init__ function of your Panel

self.instance = wx.SingleInstanceChecker(self.name)

Then, when instantiating your panel, call this:

    if panel.instance.IsAnotherRunning():
      wx.MessageBox("Another instance is running!", "ERROR")
      return

And it works exactly like you would expect it to.

Upvotes: 2

Mike Driscoll
Mike Driscoll

Reputation: 33071

I did a bit of Google-Fu and found this old thread:

Using that as my template, I put together this little script and it appears to work on my Linux box:

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):
        """"""
        if self.instance is None:
            self.instance = wx.Frame.__new__(self)
        elif isinstance(self.instance, wx._core._wxPyDeadObject):
            self.instance = wx.Frame.__new__(self)
        return self.instance

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        print id(self)
        if self.init:
            return
        self.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()

Upvotes: 1

Related Questions