3

だから私は糸脱毛に問題があります。私のプログラムで遭遇しているものと同様の例を含めました。次のコードを実行すると、メニューの[終了]ボタンが押された後にのみ「hello」が出力されます。subprocess.call()でハングしているようです。何が悪いのかわかりません!

また、私はPythonでのスレッド化の経験がなく、言語全体に慣れていないので、構造上の欠陥やPythonプログラミング規則について遠慮なく怒鳴ってください。:)

ありがとう!

import threading
import subprocess

import gtk

class TestDaemon:
    def __init__(self):

        # start thread here
        cmdman = CommandManager()
        threading.Thread(target=cmdman.run, args=('CmdThread', 1)).start()

        self.icon = gtk.StatusIcon()
        self.icon.set_from_stock(gtk.STOCK_ABOUT)
        self.icon.set_visible(True)

        self.menu = gtk.Menu()
        self.menu_item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        self.menu_item.connect('activate', self.quit_app, self.menu)
        self.menu.append(self.menu_item)

        self.icon.connect('popup-menu', self.popup_menu, self.menu)
        self.icon.set_visible(True)

        gtk.main()

    def quit_app(self, widget, data = None):
        gtk.main_quit()

    def popup_menu(self, widget, button, time, data = None):
        if button == 3 and data:
            data.show_all()
            data.popup(None, None, gtk.status_icon_position_menu,
                       3, time, self.icon)

class CommandManager:
    def __init__(self):
        pass

    def run(self, *args):
        subprocess.call('echo "hello"', shell=True)

if __name__ == '__main__':
    TestDaemon()

編集:subprocess.call()の前にsys.stdout.write()を追加すると、sys.stdout.write()は実行されますが、subprocess.call()は実行されません。

4

2 に答える 2

3

(最初にコメントとして投稿されました):

終了する前にスレッドに参加します。

class TestDaemon:
    def __init__(self):

        # start thread here
        cmdman = CommandManager()
        self.cmdThread = threading.Thread(target=cmdman.run, args=('CmdThread', 1))
        self.cmdThread.daemon = True
        self.cmdThread.start()

        ...

    def quit_app(self, widget, data = None):
        self.cmdThread.join()
        gtk.main_quit()

スレッドをデーモンに設定するのは、メインスレッドが何らかの例外を発生させ、join()が呼び出されない場合です。

于 2012-06-02T20:44:30.603 に答える
0

gtk.mainloop()代わりに使用する必要がありgtk.main()、それが機能するはずです。

ここでの問題はgtk.main()、他のスレッドをブロックして実行させないことです。おそらくGILを解放しません。

于 2012-06-02T18:28:24.757 に答える