0

私は Quickly (Python + GTK アプリケーションの迅速な開発のために Canonical が作成したプログラム) をいじっていますが、開発を開始しているこの特定のアプリは、少なくとも 1 つのインターフェイスが「稼働」し、 DHCP によって割り当てられたデフォルト ルート。

これまでの私のコードは次のとおりです。

import gettext
import subprocess
import time
from multiprocessing import Process, Queue, current_process
from gettext import gettext as _
gettext.textdomain('launcher')

import gtk
import logging
logger = logging.getLogger('launcher')

from launcher_lib import Window
from launcher.AboutLauncherDialog import AboutLauncherDialog
from launcher.PreferencesLauncherDialog import PreferencesLauncherDialog

# See launcher_lib.Window.py for more details about how this class works
class LauncherWindow(Window):
    __gtype_name__ = "LauncherWindow"

    def finish_initializing(self, builder): # pylint: disable=E1002
        """Set up the main window"""
        super(LauncherWindow, self).finish_initializing(builder)

        self.AboutDialog = AboutLauncherDialog
        self.PreferencesDialog = PreferencesLauncherDialog

        self.ui.status_label.set_text("Waiting for the interface to come up")
        while True:
            if subprocess.call(["/sbin/ifconfig | grep Bcast"], shell=True) == 0 and subprocess.call(["netstat -rn | grep UG | grep 0.0.0.0"], shell=True) == 0:
                break
        self.ui.status_label.set_text("Loaded")

# There is more code after this, but this should be all that I 
# need to get the GUI to show a status line saying the interface
# is up... right???

さて、これで問題ありませんが、アプリケーションの起動がブロックされているため、プロセスが true を返すまでハングしているように見えます。

私がやりたいことは、これを別のプロセスにプッシュすることですが、私はPythonの初心者であり、マルチプロセッシングライブラリを見つけましたが、そうではないようです生成されたプロセスから再利用できるものに self.ui.status_label をプッシュできるようにします。

たとえば、次のような変数を定義しますか?

# after line:
logger = logging.getLogger('launcher')
# add this
status_label = None

そして、次のように参照します。

# after line:
self.PreferencesDialog = PreferencesLauncherDialog
# add this
status_label = self.ui.status_label
# Then set it like this:
status_label.set_text("Waiting for the interface to come up")

または、ステータスウィンドウの更新のみを処理する新しいクラスを作成する必要がありますか (そうであれば、どうすればよいですか)、または...設定したいときはいつでも self.ui.status_label をスローする必要がありますか? 私はこれをやってみました:

def update_status(me):
    me.ui.status_label.set_text("Update me!")
    return True

# And then in the finish_initializing() code
update_status(self)

しかし、それはちょうど言った

NameError: global name 'self' is not defined

私は最善を尽くしていますが、今は非常に混乱しています。また、前述したように、Python は私がよく知っている言語ではありませんが、試してみます :)

PS、これには「迅速に」タグを付ける必要があると思いますが、そのタグを作成する評判はまだありません。

4

1 に答える 1

2

マルチプロセッシング モジュールではなく、スレッド モジュールを使用します: http://docs.python.org/library/threading.html

この理由は、新しいスレッドがメイン プログラムと同じコンテキストで実行されるため、サブプロセスが異なるコンテキストを持つ間、データを交換するのがはるかに簡単になるからです。これを行う方法は、run() メソッド (InterfaceListener など) を提供する小さなクラスを作成することです。次に、InterfaceListener クラスのコンストラクターで、必ずラベルを渡して保存してください。次に、run メソッドでインターフェイスが起動するのを待ち、起動したらラベルを更新します。何かのようなもの:

class InterfaceListener(object):
    def __init__(self, label):
        self.__label = label

    def run(self):
        while True:
            if  subprocess.call(["/sbin/ifconfig | grep Bcast"], shell=True) == 0 and
                subprocess.call(["netstat -rn | grep UG | grep 0.0.0.0"], shell=True) == 0:
                break
        self.__label.set_text("Loaded")

次に、上記の finish_initializing メソッドで、最初の self.ui.status_label.set_text の直後に、次のようなものを追加します。

t = threading.Thread(target=InterfaceListener(self.ui.status_label))
t.start()

私はこれをテストしていないので、適応する必要があるかもしれません。もう 1 つのオプションは、while True ループを使用するのではなく、Timer オブジェクトを使用して定期的にインターフェイスをチェックすることです。

于 2011-11-16T23:23:54.707 に答える