4

Μy Mainclass 创建一个QmainWindows像这样的简单对象:

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

        self.initUI()

    def initUI(self):
        self.show()

在我的文件末尾,我像这样启动它:

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


if __name__ == '__main__':
    main()

我的问题是每次我获取它时,它都会启动一个新窗口。我想知道是否有一种方法可以检测我的脚本中是否存在先前的类实例(以便我关闭旧的或避免启动新的),或任何其他解决方案?

此外,在使用 py2exe 编译我的代码时,我的 .exe 文件在 Windows 上也存在同样的问题;它每次都会启动一个新窗口。我可以在 setup.py 中添加一些内容以使 Windows 不这样做吗?

有可能吗,如果是,那怎么办?

注意:我使用的是 Windows 7 64bit 与 eclipse 编译。

4

4 回答 4

2

有几种方法可以做到这一点,您可以使用 Class 属性来存储所有实例 - 如果您这样做,您可能希望通过weakref模块将它们存储为弱引用以防止垃圾收集问题:

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

不过这有点难看。您可能还想考虑使用某种工厂(有条件地)创建一个新实例。这种方法更通用一些。

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
于 2012-07-12T18:52:46.853 回答
1

您可以通过添加计数器来限制要在代码中创建的实例数量:

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)

尝试通过以下方式运行:

lst = []
for i in range(1,101):
 a=A()
 lst.append(a)
于 2016-08-29T07:33:10.353 回答
0

使用类变量:

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()
于 2012-07-12T18:52:06.467 回答
0

你可以独占一个套接字

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?)"

不知道这是否是一个好方法,但我过去曾使用过它,它解决了这个问题

这旨在防止在程序已经运行时启动程序,而不是从生成多个窗口的单个脚本中启动新窗口...

于 2012-07-12T18:49:39.307 回答