How to allow only one instance of a certain class?

If we execute the code below, a window with a button inside will be created, which whenever clicked will open another window (Window2)... How to make a second instance of Window2 not allowed? I want to do this without using modal ().

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from gi.repository import Gtk

class Main(Gtk.Window):
    def __init__(self):
        button = Gtk.Button('Click')
        Gtk.Window.__init__(self, title = 'Main Window')
        button.connect('clicked', Window2)
        self.connect('delete-event', Gtk.main_quit)
        self.set_default_size(300, 200)
        self.add(button)
        self.show_all()

class Window2(Gtk.Window):
    def __init__(self, widget):
        button = Gtk.Button('Exit')
        Gtk.Window.__init__(self, title = 'Window2')
        button.connect('clicked', Gtk.main_quit)
        self.set_default_size(300, 200)
        self.add(button)
        self.show_all()


if __name__ == '__main__':
    Main()
    Gtk.main()
Author: Lucas Lima, 2014-07-01

3 answers

In the general case, one answer is to use Singleton, as pointed out by Diego Vieira in the comments. In your specific case, I believe it is enough to change the behavior of the button so as not to create a window every time:

class Main(Gtk.Window):
    def __init__(self):
        self.window2 = None     # Cria-se uma referência no self para a janela

        button = Gtk.Button('Click')
        Gtk.Window.__init__(self, title = 'Main Window')
        button.connect('clicked', self.mostrar_janela)    # Mostra-a quando clicar no botão
        self.connect('delete-event', Gtk.main_quit)
        self.set_default_size(300, 200)
        self.add(button)
        self.show_all()

    def mostrar_janela(self):
        if not self.window2:
            self.window2 = Window2()
        # else mostrar janela ?
 3
Author: mgibsonbr, 2017-04-13 12:59:43

I found a solution until feasible to the issue of allowing only one instance of certain window in Gtk

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from gi.repository import Gtk

class Main(Gtk.Window):
    def __init__(self):
        button = Gtk.Button('Click')
        Gtk.Window.__init__(self, title = 'Main Window')
        button.connect('clicked', self.run_window2)
        self.connect('delete-event', Gtk.main_quit)
        self.set_default_size(300, 200)
        self.add(button)
        self.show_all()

    def run_window2(self, widget):
        try:
            #Chama a janela para frente, se a janela ainda não existe,
            #ocorre um AttributeError, passando então para o except e assim criando a janela. 
            self.window2.present()
        except:
            self.window2 = Window2()

class Window2(Gtk.Window):
    def __init__(self):
        button = Gtk.Button('Exit')
        Gtk.Window.__init__(self, title = 'Window2')
        button.connect('clicked', Gtk.main_quit)
        self.set_default_size(300, 200)
        self.add(button)
        self.show_all()


if __name__ == '__main__':
    Main()
    Gtk.main()
 0
Author: Marcio Luís, 2015-01-11 15:06:51

Without wanting to demean the other answers and although they are correct and solve the specific case, perhaps in an even better way, also without going into merits if singleton is a good design standard or not my suggestion is for other cases in general.

How to allow only one instance of a certain class?

In other words:

How to create a singleton in python?

Using metaclasses:

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Window(object):
    __metaclass__ = Singleton

Or in Python 3

class Window(metaclass=Singleton):
    pass

And finally if you want __init__ to be called every time the class is called add:

    else:
        cls._instances[cls].__init__(*args, **kwargs)

Source: shamelessly inspired by https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python

 0
Author: tovmeod, 2017-05-23 12:37:23