0

サブプロセスまたはスレッドでコードを実行することについて多くのことを見てきましたが、モジュールとモジュールを使用するmultiprocessingthreading非常に簡単でした。ただし、GUI でこれを行うと、さらに複雑なレイヤーが追加されます。

私が理解していることから、複数のスレッド (またはプロセス) から GUI クラスを操作しようとすると、GUI クラスはそれを好みません。回避策は、作成したスレッドからグラフィックスを担当するスレッドにデータを送信し、そこでレンダリングすることです。

残念ながら、私が念頭に置いているシナリオでは、これはオプションではありません。私が作成した GUI を使用すると、ユーザーは独自のプロット コードを記述して実行することができます。これは、彼らがどのようにプロットするかを正確に制御できないことを意味します。また、それを望んでいません. (更新:これらのプロットは別のウィンドウに表示され、メインGUIのどこにも埋め込む必要はありません。私が望むのは、グラフィックライブラリの基礎となるスタックを共有せずに、メインGUIから分離して存在させることです。)

そこで今気になっているのは

ウィンドウシステムとの独自のつながりを持つまったく新しいインタープリターインスタンスでPythonコードの文字列を実行するクリーンな(っぽい)方法はありますか?


コメントへの応答:

現在のアプリケーションは次のように設定されています。単純な Python スクリプトが wxPython GUI (wx.App) をロードします。この GUI を使用して、ユーザーはシミュレーションをセットアップできます。その一部には、シミュレーションを実行し、結果を後処理するプレーン python でのスクリプトの作成が含まれます (通常、プロットの作成と表示が含まれます)。現時点では、スクリプト コードで exec() を呼び出すだけでこれを実行しています。これは問題なく動作しますが、シミュレーションの実行中に GUI がフリーズします。サブプロセスで埋め込みスクリプトを実行して実験しましたが、これも正常に動作し、作成したグラフを表示しようとするまで (通常は matplotlib の show() を使用) します。この時点で、複数のスレッドから操作できないため、wxPython、wx、gtk などのスタックの奥深くにあるライブラリが文句を言い始めます。希望する編成ほぼ同じですが、埋め込みスクリプトがメイン アプリケーションと GUI を共有する代わりに、独自の環境でグラフィックを表示したいと考えています。

明確にするために:

これは、「マルチスレッディング/マルチプロセッシングを行う方法」や「単一の wxpython GUI 内でマルチスレッディング/マルチプロセッシングを行う方法」についての質問ではありません。問題は、まったく新しいGUI をロードする GUIからスクリプトを開始する方法です。ウィンドウ マネージャにこのスクリプトを完全に別のアプリケーションとして認識させるにはどうすればよいですか?

最も簡単な方法は、どこかの一時フォルダーに生成してから、Python インタープリターへの非ブロック呼び出しを行うことですが、これにより通信がより困難になり、いつ一時ファイルを削除できるかを知るのが非常に難しくなります。これを行うための、よりクリーンで動的な方法があることを望んでいました。

4

4 に答える 4

1

Windowsでは、別のプロセスの親ウィンドウを使用してウィンドウを作成し、それに描画することができます。CreateWindowExのhWndParent引数を参照してください。

wxWindowsがそれを明示的に取得/設定することをサポートしている場合は、これで問題ありません。プラットフォームによっては、どのWindowsシステムでも同様のことが可能になる場合があります。

したがって、ユーザーがアプリウィンドウのハンドルを見つけることができるようにするだけで、ユーザーは、独自のプロセスで実行しながら、アプリに埋め込まれたビューをプロットするオプションを利用できるようになります。

于 2012-08-24T08:49:41.657 に答える
1

私はwxについてはあまり知りません.jython(Javaで実装されたPythonで、Javaを使用できます)とswingを使用しています。Swing には独自のワーカー スレッドがあり、GUI の更新を行う場合は、コードをランナブルにラップし、swing.invokelater.

wx にそのようなものがあるかどうかを確認できますが、作成したスレッドから GUI を操作することしか許可されていない場合は、同様のことを試してください。GUI のプロキシ オブジェクトを作成します。これにより、すべての呼び出しがスレッドに転送され、GUI に転送されます。

しかし、このようなプロキシは面倒です。「updateGui」関数を使用して、キューを介して返され、GUIスレッドで実行されるクラスを定義させてはどうでしょうか。

于 2012-08-24T09:35:01.237 に答える
1

サブプロセスを使用して「python.exe」を実行し、スクリプトをパイプするだけですか?

または、スクリプトを実行する新しいプロセスに (pickle 可能な) データを移動する場合は、multiprocessingパッケージで十分です。スクリプトを実行する関数/呼び出し可能オブジェクトを作成し、呼び出し可能オブジェクトをターゲットとしてProcessオブジェクトを作成するだけです。そうすれば、GUI の問題を発生させることなく、データを渡すことができるはずです。

いずれかでテキストをキャプチャするのは簡単ですが、サブプロセスはそれを可能にします。マルチプロセスを使用すると、Python オブジェクトをより簡単にやり取りできます。

于 2012-08-24T09:46:30.430 に答える
1

wxPython ランドでは、スレッドを使用する場合、スレッドセーフなメソッドを使用して GUI と通信する必要があります: wx.CallAfter、wx.CallLater、または wx.PostEvent。あなたの場合、長時間実行されるコードを別のスレッド/プロセスで実行し、処理が完了したら、結果を GUI に送信します。GUI は、新しいフレームをインスタンス化し、行きたい方向に応じて、matplotlib または PyPlot を使用してプロットを表示できます。FloatCanvas を使用してプロットを描画することもできると聞きました。

とにかく、新しいフレームを正しくインスタンス化すれば、N 個のフレームをインスタンス化して表示でき、問題ありません。wx でスレッドを使用するいくつかの例については、wxPython wiki を参照してください: http://wiki.wxpython.org/LongRunningTasks

于 2012-08-24T13:45:17.977 に答える