2009-08-16 8 views
2

私はgrowisofsを使ってPythonアプリケーションからisoを焼き付けています。私は2つの異なるファイルに2つのクラスを持っています。 GUI()(main.py)とBoxblaze()(core.py)です。 GUI()はウィンドウを構築し、すべてのイベントやものを処理し、Boxblaze()はGUI()が呼び出すすべてのメソッドを持っています。subprocess.callの出力をプログレスバーにパイプする

ユーザーがで燃焼させるデバイスを選択している、そしてファイルが燃焼させる際に今、私は次のコマンドを呼び出すメソッドを呼び出す必要があります: `

growisofs -use-the-force-luke=dao -use-the-force-luke=break:1913760 -dvd-compat -speed=2 -Z /burner/device=/full/path/to.iso 

このコマンドは、同様の出力を与える必要があります

Executing 'builtin_dd if=/home/nevon/games/Xbox 360 isos/The Godfather 2/alls-tgod2.iso of=/dev/scd0 obs=32k seek=0' 
/dev/scd0: "Current Write Speed" is 2.5x1352KBps. 
#more of the lines below, indicating progress. 
7798128640/7835492352 (99.5%) @3.8x, remaining 0:06 RBU 100.0% UBU 99.8% 
7815495680/7835492352 (99.7%) @3.8x, remaining 0:03 RBU 59.7% UBU 99.8% 
7832862720/7835492352 (100.0%) @3.8x, remaining 0:00 RBU 7.9% UBU 99.8% 
builtin_dd: 3825936*2KB out @ average 3.9x1352KBps 
/dev/burner: flushing cache 
/dev/burner: closing track 
/dev/burner: closing disc 

このコマンドは、Boxblaze()のburn()メソッドで実行されます。今私の質問は以下の通りです

def burn(self, file, device): 
    subprocess.call(["growisofs", '-dry-run', "-use-the-force-luke=dao", "-use-the-force-luke=break:1913760", "-dvd-compat", "-speed=2", "-Z", device +'='+ file]) 

  1. どのように出力(括弧内のパーセンテージ)から進捗状況を取得し、私のプログレスバーがあることができ、それは単に、このようになりますその進行に「追従」するように設定されていますか?私のプログレスバーは、次のような、GUI()クラスに呼び出されます。

    GET = builder.get_object

    self.progress_window = GET( "progressWindow")

    self.progressbar = GET( "プログレスバー")

  2. GUIを応答したままにするためにこのコマンドを実行する必要があります(プログレスバーを更新して、ユーザーが希望する場合は書き込みをキャンセルできるようにします)。もしそうなら、どのように私はそれを行うことができ、進捗バーに進行状況を引き渡すことができますか?興味のある方は


完全なコードはon Launchpad可能です。

bzr branch lp:boxblaze 

ああ、あなたは不思議に思った場合には、このアプリケーションはLinuxでのみ動作するように意図される - ので、クロスプラットフォームの互換性を心配しないでください:あなたはバザーがインストールされている場合は、単に実行します。

答えて

1

出力を取得するには、subprocess.Popenコールを使用する必要があります。 (stdout = subprocess.PIPE

(2番目の質問)

GUIフレームワークは、通常のループ内でのファイル記述子に選択することができない限り、あなたはおそらく、別のスレッドを必要としています。

バックグラウンドスレッドにパイプを読み込ませ、処理して(進捗を抽出する)、GUIスレッドに渡すことができます。

## You might have to redirect stderr instead/as well 
proc = sucprocess.Popen(command,stdout=subprocess.PIPE) 
for line in proc.stdout.readlines(): 
    ## might not work - not sure about reading lines 
    ## Parse the line to extract progress 
    ## Pass progress to GUI thread 

編集:

私はそれをテストCDの多くを無駄にしたくない怖いので、私はそれを実行していない、しかし、あなたがしていることで、それはないように見えるコメントinfoをstdoutに出力しますが、stderrに出力します。

コマンドラインで直接サンプルコマンドを実行し、stdoutとstderrを別のファイルにリダイレクトすることをお勧めします。

growisofs [options] >stdout 2>stderr 

次に、stdoutに出てくるものとstderrに出てくるものを考え出すことができます。

stderrに必要なものがある場合は、stdout=subprocess.PIPEstderr=subprocess.PIPEに変更し、それがうまくいくかどうかを確認してください。

EDIT2:

あなたは正しくスレッドを使用していない - あなたはそれを開始する必要がある - それを直接実行していません。また

: - 初期化子の呼び出しは、初期化子にする必要があります -

gtk.gdk.threads_init() 
threading.Thread.__init__(self) 

は非常に奇妙であると私はあなたがそれgtkのスレッドにする必要があると思いませんか?

あなたはrun()メソッドを呼び出す方法は、それ自身奇妙です:

オブジェクトを介して
core.Burning.run(self.burning, self.filechooser.get_filename(), self.listofdevices[self.combobox.get_active()]) 

コールインスタンスメソッド:

self.burning.run(self.filechooser.get_filename(), self.listofdevices[self.combobox.get_active()]) 

(しかし、あなたは__init__()メソッドを持っている必要があります)

あなたが歩く前にあなたは走っているようです。いくつかのシンプルなスレッディングコードを書いてみて、growisofsを実行して出力を解析し、単純なGTK +バックグラウンドスレッディングコードを作成し、それらをまとめてみてください。 実際には、単純なオブジェクト指向コードを書くのが最初です。メソッドとオブジェクトを最初に理解できるようにしてください。

Pythonで作成するすべてのクラスは、新しいスタイルのクラスでなければなりません。初期化子などからスーパークラスの初期化プログラムを呼び出す必要があります。

+0

私はそれが何を意味しているかを完全に理解しているかどうかはわかりません。これは私がそれ(http://pastebin.com/m6b1bdff6)を実装しようとした方法ですが、私が(端末に)取得している唯一の出力は次のとおりです: /dev/scd0: "現在の書き込み速度"は2.5x1352KBpsです。 –

+0

私が探している情報はスタンダードを経由しているようです。しかし、今では、すべてが画面に表示されるので、私の解析はうまくいかないようです(pastebinのリンクを参照)。 GUIはまだフリーズしています。 core.py→http://pastebin.com/m586398c8 main.pu→http://pastebin.com/m28658de 実際には、-dry-runフラグをgrowisofsコマンドに追加して試すことができますDVDを無駄にすることなく。 シバン全体を見るには、次のコマンドを実行してください: bzr branch lp:boxblaze –

+0

申し訳ありませんが、私のアプリケーションの実行結果を含めるのを忘れていました。これは次のとおりです。 http://pastebin.com/m6e55585a –

0

サブプロセスからの読み取りにタイムアウトを渡すことはできますか? my subProcess moduleがそのデザイン入力として使用されたので、あなたができると思います。これを使ってgrowiso.read(.1)を実行し、outdata(または多分errdata)のパーセンテージを解析して表示することができます。

0

別のスレッドからコマンドを実行し、gobject.idle_add呼び出しでguiを更新する必要があります。今あなたがクラス「バーニング」を持っていますが、あなたはそれが間違って使用している、このように使用する必要があります。

self.burning = core.Burning(self.filechooser.get_filename(), self.listofdevices[self.combobox.get_active()], self.progressbar) 
self.burning.start() 

は明らかにあなたがcore.Burningを変更する必要があります。

def set_progress_bar_fraction(self, fraction): 
    self.progress_bar.set_fraction(fraction) 

はその後、すべての割合の更新は、このようにそれを呼び出す:スレッド hereとPyGTKの上 gobject.idle_add(self.set_progress_bar_fraction, fraction)

詳細情報あなたはこのような関数を作ることができるので、 は、その後、あなたはプログレスバーにアクセスする必要があります。

2

を使用すると、サブプロセスオブジェクトのstdoutおよびstderrに接続されているパイプで出力を監視できます。コールバックが呼び出されたときに

proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
stdout_id = glib.io_add_watch(proc.stdout, glib.IO_IN|glib.IO_HUP, stdout_cb) 
stderr_id = glib.io_add_watch(proc.stderr, glib.IO_IN|glib.IO_HUP, stderr_cb) 

そして、それは条件をチェックし、パイプからのすべてのデータを読み込み、プログレスバーを更新するための情報を得るためにそれを処理しなければなりません。もしアプリケーションがioをバッファリングするならば、ptyを使って端末に接続していると考えることに騙さなければならないかもしれないので、一度に1行ずつ出力します。

関連する問題