单例模式
# -*- coding: utf-8 -*-import functoolsimport tkinter as tkdef just_one_instance(func):"""保证只能运行一个Python实例,方法是程序运行时监听一个特定端口,如果失败则说明已经有实例在跑。"""@functools.wraps(func)def f(*args, **kwargs):import sockettry:# 全局属性,否则变量会在方法退出后被销毁global ss = socket.socket()host = socket.gethostname()s.bind((host, 60124))except:print('程序已经在运行了')return Nonereturn func(*args, **kwargs)return f@just_one_instancedef run():tk.Tk().mainloop()if __name__ == '__main__':run()
单例模式下激活窗口
当运行了一个tkinter程序后,重新运行程序,使用上面代码可以拦住运行,那如何激活已经运行了的那个应用,让它跳出到桌面上呢?
改造单例代码
def just_one_instance(func):@functools.wraps(func)def f(*args, **kwargs):try:# 全局属性,否则变量会在方法退出后被销毁global ss = socket.socket()host = socket.gethostname()s.bind((host, 60124))except:# 拦截后,这里发送一段socket指令tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpCliSock.connect(('127.0.0.1', 60124))tcpCliSock.send("show".encode())tcpCliSock.close()return Nonereturn func(*args, **kwargs)return f
tkinter代码
# 监听重新打开,激活主页面self.recv_msg_thread = threading.Thread(target=self.recv_msg)self.recv_msg_thread.setDaemon(True)self.recv_msg_thread.start()def recv_msg(self):tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcpSerSock.bind(('127.0.0.1', 60124))tcpSerSock.listen(5)while True:tcpCliSock, addr = tcpSerSock.accept()while True:data = tcpCliSock.recv(1024)if not data:breakself.root.deiconify()self.root.wm_attributes('-topmost', 1)self.root.wm_attributes('-topmost', 0)tcpCliSock.close()
