wxPython:确保只有一个面板实例打开
wxPython: Ensure only one instance of a panel is open
我正在编写一个多window、多框架的应用程序。对于每一个打开的新 window/frame,应该有并且只有一个 window 的实例。我希望用户能够在这些 windows 之间快速切换,所以 ShowModal()
不起作用。我试过使用 SingleInstanceChecker
,但我无法让它工作,因为它更多地用于应用程序而不是框架。我应该如何做到这一点?
我做了一些 Google-Fu 并找到了这个旧线程:
使用它作为我的模板,我将这个小脚本放在一起,它似乎可以在我的 Linux 盒子上运行:
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()
除了 Mike 的回答之外,我还找到了另一种方法来做到这一点,所以我想我会 post 它以防万一有人需要它。
SingleInstanceChecker
实际上对 wx.Frames 和 wx.Panels 有效。它的工作方式与在 App 中的工作方式相同。
将这段代码放入面板的 __init__
函数中
self.instance = wx.SingleInstanceChecker(self.name)
然后,在实例化面板时调用:
if panel.instance.IsAnotherRunning():
wx.MessageBox("Another instance is running!", "ERROR")
return
它的工作原理与您期望的完全一样。
我正在编写一个多window、多框架的应用程序。对于每一个打开的新 window/frame,应该有并且只有一个 window 的实例。我希望用户能够在这些 windows 之间快速切换,所以 ShowModal()
不起作用。我试过使用 SingleInstanceChecker
,但我无法让它工作,因为它更多地用于应用程序而不是框架。我应该如何做到这一点?
我做了一些 Google-Fu 并找到了这个旧线程:
使用它作为我的模板,我将这个小脚本放在一起,它似乎可以在我的 Linux 盒子上运行:
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()
除了 Mike 的回答之外,我还找到了另一种方法来做到这一点,所以我想我会 post 它以防万一有人需要它。
SingleInstanceChecker
实际上对 wx.Frames 和 wx.Panels 有效。它的工作方式与在 App 中的工作方式相同。
将这段代码放入面板的 __init__
函数中
self.instance = wx.SingleInstanceChecker(self.name)
然后,在实例化面板时调用:
if panel.instance.IsAnotherRunning():
wx.MessageBox("Another instance is running!", "ERROR")
return
它的工作原理与您期望的完全一样。