Limit the number of class instances using python

My Mainclass creates a simple QmainWindows like this:

 class mcManageUiC(QtGui.QMainWindow): def __init__(self): super(mcManageUiC, self).__init__() self.initUI() def initUI(self): self.show() 

And at the end of my file, I run it like this:

 def main(): app = QtGui.QApplication(sys.argv) renderManagerVar = mcManageUiC() sys.exit(app.exec_()) if __name__ == '__main__': main() 

My problem is that every time I launch it, it launches a new window. I would like to know if there is a way to detect the existence of a previous instance of a class in my script (to close the old one or not start a new one) or any other solutions?

Also, when compiling my code with py2exe, the same problem is with my .exe file on Windows; he launches a new window every time. Can I add something to setup.py for Windows so that I don’t act like that?

Is it possible, if so, how?

Note. I am using 64-bit compilation of Windows 7 with eclipse.

+4
source share
4 answers

There are several ways to do this; you can use the Class attribute to store all instances. If you do this, you might want to save them as weak links through the weakref module to prevent garbage collection problems:

 class MyClass(object): _instances=[] def __init__(self): if(len(self._instances) > 2): self._instances.pop(0).kill() #kill the oldest instance self._instances.append(self) def kill(self): pass #Do something to kill the instance 

This is a little ugly. You may also want to use some kind of Factory, which (conditionally) creates a new instance. This method is a bit more general.

 import weakref class Factory(object): def __init__(self,cls,nallowed): self.product_class=cls #What class this Factory produces self.nallowed=nallowed #Number of instances allowed self.products=[] def __call__(self,*args,**kwargs): self.products=[x for x in self.products if x() is not None] #filter out dead objects if(len(self.products) <= self.nallowed): newproduct=self.product_class(*args,**kwargs) self.products.append(weakref.ref(newproduct)) return newproduct else: return None #This factory will create up to 2 instances of MyClass #and refuse to create more until at least one of those #instances have died. factory=Factory(MyClass,2) i1=factory("foo","bar") #instance of MyClass i2=factory("bar","baz") #instance of MyClass i3=factory("baz","chicken") #None 
+2
source

You can limit the number of instances you want to create in your code by simply adding a counter:

 class A(object): ins = 0 # This is a static counter def __init__(self): if A.ins >= 1: # Check if the number of instances present are more than one. del self print "Failed to create another instance" #if > 1, del self and return. return A.ins += 1 print "Success",str(self) 

Try to do:

 lst = [] for i in range(1,101): a=A() lst.append(a) 
+1
source

you can monopolize a socket

 import socket try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except: "Network Error!" s.settimeout(30) try: s.connect(('localhost' , 123)) except: "could not open...already in use socket(program already running?)" 

I do not know if this is a good method, but I have used it in the past and solves this problem.

it was designed to prevent the program from starting when it was already not starting from the start of a new window from one single script that spawns multiple windows ...

0
source

Use the class variable:

 class mcManageUiC(QtGui.QMainWindow): singleton = None def __init__(self): if not mcManageUiC.singleton: #if no instance yet super(mcManageUiC, self).__init__() self.initUI() ... mcManageUiC.singleton = self else: ... def initUI(self): self.show() 
0
source

All Articles