QThreadをGUIアプリケーションから正しく終了させるには?

QThreadクラスでは self.terminate()、GUIクラスでは self.thread.terminate()を使用してみました。どちらの場合でも self.wait()を入れてみました。ただし、次の2つのシナリオがあります。

1)スレッドがまったく終了せず、GUIがフリーズしてスレッドが終了するのを待つ。スレッドが終了すると、GUIはフリーズし、すべて正常に戻ります。

2)スレッドは実際に終了しますが、同時にアプリケーション全体がフリーズします。

また、 self.thread.exit()を使って試してみました。喜びはありません。

さらに明確にするために、GUIの中にユーザーの中止ボタンを実装しようとしています。これは、任意の時点でスレッドの実行を終了します。

前もって感謝します。

編集:

以下は run()メソッドです:

def run(self):
    if self.create:
        print "calling create f"
        self.emit(SIGNAL("disableCreate(bool)"))
        self.create(self.password, self.email)
        self.stop()            
        self.emit(SIGNAL("finished(bool)"), self.completed)

def stop(self):
     #Tried the following, one by one (and all together too, I was desperate):
     self.terminate()
     self.quit()
     self.exit()
     self.stopped = True
     self.terminated = True
     #Neither works

次に、スレッドを中止するためのGUIクラスのメソッドを示します。

def on_abort_clicked(self):
     self.thread = threadmodule.Thread()
     #Tried the following, also one by one and altogether:
     self.thread.exit()
     self.thread.wait()
     self.thread.quit()
     self.thread.terminate()
     #Again, none work
3
ありがとう、しかし、これは実際に問題を解決するのに役立つわけではありません。
追加された 著者 Bo Milanovich,
まあ、それは確かに私が探しているものではありません。
追加された 著者 Bo Milanovich,
注:self.terminate ===(self.terminated = true)、それ以上はありません。すべての実装の99%
追加された 著者 TheHorse,
スレッドを安全に終了する方法は1つしかありません。すべてのタスクを終了させます。これを実行するには、ハードタスクを実行する前にthread.terminatedをチェックする必要があります。
追加された 著者 TheHorse,

1 答え

QThread :: terminateのQtドキュメントから:

警告:この機能は危険で、その使用はお勧めしません。ザ   スレッドはコードパスの任意のポイントで終了することができます。スレッドにすることができます   データの変更中に終了しました。スレッドにはチャンスがありません   つまり、それ自体の後でクリーンアップし、保持されているミューテックスなどをロック解除します。要するに、   この機能は絶対に必要な場合にのみ機能します。

スレッド戦略を考え直すことは、おそらくもっと良い考えです。 QThread :: quit()を使用して、この方法でスレッドを終了させるのではなく、スレッドが正常終了するように通知します。実際にスレッド内からthread.exit()を呼び出すには、run()の実装方法に応じてスレッドを実行する必要があります。スレッド実行メソッドのコードを共有したいのであれば、なぜ動作しないのかを示唆するかもしれません。

5
追加された
ありがとね。私はポストにコードを追加しました。
追加された 著者 Bo Milanovich,
私もそれを試みた。多少動作しました(GUIはフリーズしませんが、スレッドは終了しません)。しかし、奇妙なことがちょうど起こった。スレッド内のすべての def stop(self)コードとGUIの def on_abort_clicked(self)コードを削除して書き換えました。スレッドの stop()関数に self.terminate()を置き、GUIクラスの self.thread.stop()しました。それは魅力のように働く。 AFAIK、それは私が試した最初のもので、以前はうまくいかなかった。私はおそらく何かを逃した。
追加された 著者 Bo Milanovich,
うーん。そして、私は、 self.create()メソッドがスレッドで時間のかかるメソッドであると想定していますか?一般的には、 self.terminated(){(遅い操作部分)} のようなものではありません。残念ながら、私はPythonについてよく分かりませんが、スレッドチュートリアルがあるようですが、ここで助けて
追加された 著者 docsteer,