3

PyQt アプリケーションでいくつかのグラフを表示する必要があるため、これらのコードを書き留めます。それは機能しますが、チャートを描くのに時間がかかり、メインウィンドウが「フリーズ」することがあります。

別のスレッドでそれを行うと解決するはずだと思います。しかし、どうすればそれができますか?または、「非ブロック」モードでグラフを描画する別の方法はありますか?

from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas   
from matplotlib.figure import Figure

class MplCanvas(FigureCanvas):

    def __init__(self):
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)

        # do something...
        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        # do something...

    def draw(self):
        # do something...
4

2 に答える 2

2

あなたはQThreadsあなたのQtアプリケーションで私たちを必要とします(フレームワークがあなたのためにすべての大変な仕事をするようにするため)

  1. 時間のかかる作業を (から派生したQObject)ワーカー クラスに入れます。

  2. プロットを呼び出しているクラスで、次のようなものを追加します

    self.thread = QtCore.QThread(parent=self)
    
    self.worker = Worker(parent=None)
    self.worker.moveToThread(self.thread)
    self.thread.start()
    

シグナル/スロットを介してワーカーと通信します。直接呼び出すと ( のようにself.worker.do_slow_stuff())、呼び出し元のスレッドで実行され、メイン イベント ループがブロックされてインターフェイスがフリーズします。

スレッド化を行う方法 (およびしない方法)の適切な説明(両方を読んでください..最初のものはデフォルトの動作を説明しています)QThread

于 2013-01-24T05:59:56.610 に答える
1

このような単純な用途のための Python スレッド化の基本は、非常に簡単です。

あなたがする必要があります

import threading

次に、単に x.draw() を呼び出す代わりに、スレッドを作成して次のように実行します。

draw_thread = threading.Thread(target=x.draw)
draw_thread.start()

これで、少なくとも 90% は成功するでしょう。ドキュメントを読んで、まだ実行中のスレッド、スレッドの待機などを検出できます。しかし、本質的には難しいことではありません。単純なインタラクティブなグラフィックであれば、これで十分かもしれません。

ただし、draw() がグローバルを参照する場合、競合状態が発生してプログラムが信頼できなくなる可能性があることに注意してください。これは、結合が良好で、インターフェイスがクリーンで、変更可能なグローバルへの参照がないコードを記述することのさらなる利点です (これらのリソースを保護するためにロックが使用されない限り)。

于 2013-01-24T02:42:00.103 に答える