0

我正在编写一个 pyGTK 程序,它(除其他外)将允许用户从列表中选择并运行第二个程序。我想启动用户选择的程序作为一个完全独立的进程,它有自己的主循环,但我不确定这样做是否安全。我进行了快速测试(见下文),它似乎是安全的,但我没有做很多 GUI 编程,所以我知道可能有些事情我没有想到。我找不到任何解决此问题的教程,所以我想在深入研究之前先问一下。

一旦第二个程序开始,这两个程序就不需要说话了。

这是我尝试的测试。

import gtk
import numpy as np

class TopGUI(gtk.Window):
    def __init__(self):
        super(TopGUI,self).__init__()
        parentLabel = gtk.Label('I am the father')
        newWindowBtn = gtk.Button('meet my brother')
        vBox1 = gtk.VBox(False,4)
        vBox1.pack_start(parentLabel, True, True, 4)
        vBox1.pack_start(newWindowBtn, True, True, 4)

        newWindowBtn.connect("clicked", self.on_clicked) # 0p3n Br07h3r loop on butt0n pre55

        self.add(vBox1)
        self.show_all()
        self.startItUp

    def on_clicked(self, leButton):
        broWin = SecondGUI()
        broWin.startItUp

    def startItUp(self):
        gtk.main()

class SecondGUI(gtk.Window):
    bigthing = None
    def __init__(self):
        super(SecondGUI,self).__init__()
        brotherLabel = gtk.Label('I am the 3\/1L U|\|kl3. I D3v0ur M3M0ry!')
        spinner = gtk.Spinner()
        vBox1 = gtk.VBox(True,4)
        vBox1.pack_start(brotherLabel, True, True, 4)
        vBox1.pack_start(spinner, True, True, 4)
        spinner.start()

        self.add(vBox1)
        self.show_all()
        self.bigthing = np.zeros([10000,10000])

    def startItUp(self):
        gtk.main()


fatherLoop = TopGUI()

对于后代,这是实现abarnert解决方案的测试代码的改进版本。

import gtk
import numpy as np
import multiprocessing

class TopGUI(gtk.Window):
    def __init__(self):
        super(TopGUI,self).__init__()
        parentLabel = gtk.Label('I am the father')
        newWindowBtn = gtk.Button('meet my brother')
        vBox1 = gtk.VBox(False,4)
        vBox1.pack_start(parentLabel, True, True, 4)
        vBox1.pack_start(newWindowBtn, True, True, 4)

        newWindowBtn.connect("clicked", self.on_clicked) # 0p3n Br07h3r loop on butt0n pre55
        self.connect("destroy", gtk.main_quit)

        self.add(vBox1)
        self.show_all()
        self.startItUp()

    def on_clicked(self, leButton):
        self.childProcess = multiprocessing.Process(target=child_main)
        self.childProcess.start()

    def startItUp(self):
        gtk.main()

class SecondGUI(gtk.Window):
    bigthing = None
    def __init__(self):
        super(SecondGUI,self).__init__()
        brotherLabel = gtk.Label('I am the 3\/1L U|\|kl3. I D3v0ur M3M0ry!')
        spinner = gtk.Spinner()
        vBox1 = gtk.VBox(True,4)
        vBox1.pack_start(brotherLabel, True, True, 4)
        vBox1.pack_start(spinner, True, True, 4)
        spinner.start()

        self.add(vBox1)
        self.show_all()
        self.bigthing = np.zeros([10000,10000])

        self.connect("destroy", gtk.main_quit)
        self.startItUp()

    def startItUp(self):
        gtk.main()

def parent_main():
    fatherLoop = TopGUI()

def child_main():
    broWin = SecondGUI()

if __name__ == '__main__':
    parent_main()
4

1 回答 1

2

我想启动用户选择的程序作为一个完全独立的进程,它有自己的主循环,但我不确定这样做是否安全。

是的,那将是安全的,实际上它可能正是您想要的。除非您竭尽全力(通过 fd 继承、共享内存、管道等),否则单独的进程不会共享任何内容。

但是您的代码没有这样做,甚至没有尝试这样做。那里没有任何东西可以启动子进程;您只需在同一个解释器中创建一个新对象。因此,一旦您启动第二个 GUI,它将最终运行自己gtk.main()的 GUI,使第一个 GUI 挂起,直到第二个退出。

但是您只是在各处引用self.startItUp(和broWin.startItUp)而不是调用self.startItUp(). 所以第二个 GUI 永远不会启动,一切都是“安全的”,从某种意义上说,什么都不做总是安全的。

您可能想使用multiprocessing. 首先,你不能只fatherLoop = TopGUI()在顶层做,因为那样每个进程都可能最终运行它。(它是否与实现/平台相关。)然后,您需要显式创建一个Process并为孩子启动它。所以,像这样:

class TopGUI(gtk.Window):
    # ...
    def on_clicked(self, leButton):
        self.child = multiprocessing.Process(target=child_main)
        self.child.start()
    # ...

def parent_main():
    fatherLoop = TopGUI()

def child_main():
    broWin = SecondGUI()

if __name__ == '__main__':
    parent_main()

我假设你要修复你的代码,以便构造 aTopGUI()或 aSecondGUI()调用self.startItUp()

于 2013-04-05T21:16:57.583 回答