wxPython:从另一个wxApp调用wxApp

2 投票
2 回答
1503 浏览
提问于 2025-04-17 05:39

可以从一个wxApp运行另一个wxApp吗?我想在另一个wxApp的方法中调用我写的一个程序(叫做DataDeck),就像它是一个插件一样。

大概是这样的:

def on_datadeck_btn_click(self, event):
        import datadeck.main
        datadeck.main.run()
        event.Skip()

其中 datadeck.main.run() 是一个wxApp的经典启动方式:

def run():
    app = DataDeck(0)
    app.SetAppName("DataDeck")
    app.MainLoop()

现在,它第一次正确打开DataDeck并且可以使用,但在我关闭它之后,第二次再打开DataDeck就不行了。这会导致整个程序卡住。

更新:根据@Mike Driscoll的回答,我进一步了解了情况,并找到了以下解决方案:

我在datadeck中添加了一个“入口点”:

def run_as_plugin():
    #[do some stuff related to XRC layouts and sysout redirection]
    MainGUI = datadeck.gui.maingui.MainGUI()

在这里,MainGUI()的构造函数会自动显示wxFrame。现在我的应用程序表现得就像是调用它的wxApp的一个组件。

因此,我将应用程序的方法修改为如下:

def on_datadeck_btn_click(self, event):
    import datadeck.main
    datadeck.main.run_as_plugin()
    event.Skip()

其实非常简单!我只需要修改处理标准输出重定向的对象(这部分不在这个问题讨论范围内,我就不详细说了),然后一切就正常工作了。

2 个回答

0

这是完全可行的。我不太明白为什么你会遇到问题。
这个例子运行得很好:

--main.py--

import wx

class MainFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, title='Main', size=(353,270))
        button= wx.Button(self, -1, 'call app', pos=(10,10), size=(-1,30))
        self.Bind(wx.EVT_BUTTON, self.capp, button)

    def capp(self, event):
        import datadeck
        datadeck.run()

if __name__ == '__main__':
    app = wx.App(0)
    frame = MainFrame(None)
    frame.Show()
    app.MainLoop()

--datadeck.py--

import wx

class DDFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, title='DDFrame', size=(353,270))
        button = wx.Button(self, -1, 'print something', pos=(100,100), size=(-1,30))
        self.Bind(wx.EVT_BUTTON, self.say_hello, button)

    def say_hello(self, event):
        print 'something'

class DataDeck(wx.App):
    def OnInit(self):
        frame = DDFrame(None)
        frame.Show()
        return True

def run():
    app = DataDeck(1)
    app.SetAppName("DataDeck")
    app.MainLoop()

如果你按下“调用应用程序”按钮,就会打开一个新的窗口。你可以打开任意多个窗口。
创建的应用程序/窗口是相互独立的。你可以关闭任何一个,而不会影响其他窗口。而且系统不会卡顿。

1

在一个程序里只能有一个 wx.App。根据我在网上看到的,不能在同一个脚本里同时运行两个 wx.App 对象。不过,你可以试着用 subprocess 模块来打开一个新的进程。你可以看看 Editra,里面有一些关于插件的例子。Editra 是和 wxPython 一起提供的,或者你也可以单独下载。

撰写回答