2016-08-09 13 views
1

Qtベースの複雑なPythonアプリケーションを使用しています。これはPySide.QtCore.QTimer.singleShot(int、slot)タイマーを使用してスレッド内のスロットの実行を遅延させます。このタイマーの仕組みについては混乱しています。PySide.QtCore.QTimer.singleShotがタイムアウトメソッドを呼び出す方法

ここにMWEがあります。この例では、QThreadをサブクラス化してrun()を再実装する方法を使用します。

import PySide 
import time 

class SubClassThread(PySide.QtCore.QThread): 

     def run(self): 
       print('called SubClassThread.run()') 
       self.delayed_print() 

     def delayed_print(self): 
       print('called SubClassThread.delayed_print()') 
       PySide.QtCore.QTimer.singleShot(1000, self.print_things) 
       time.sleep(2) 
       print('end of delayed_print()') 

     def print_things(self): 
       print('called print_things') 

私はこれをテストするために使用していたコード(test.pyそれを呼び出す):

import sys 
import time 

import PySide 

from timertester import SubClassThread 

print('Test: QThread subclassing') 
app = PySide.QtCore.QCoreApplication([]) 
sct = SubClassThread() 
sct.finished.connect(app.exit) 
sct.start() 
sys.exit(app.exec_()) 

python test.pyの出力:

Test: QThread subclassing 
called SubClassThread.run() 
called SubClassThread.delayed_print() 
end of delayed_print() 
を私はtimertester.pyと呼ばれるファイルに次のように置きます

興味があるのは、QTimer.singleShotに渡された呼び出し可能コードが決して呼び出されないようだということです(出力にはcalled print_things()はありません!)あなたはこれを流すことができます。私はQtフレームワークの単純な要素が欠けていると感じています。私と一緒に耐えてください - 私はこれに対する答えを探して時間を費やしました。

答えて

1

デフォルトの実装QThread.run()は、スレッドの独自のイベントループを開始するQThread.exec()を呼び出します。 A QTimerは、実行中のイベントループを必要とし、その信号のtimeout()が開始されたスレッドで送出されます。run()の実装はイベントループを開始しないため、タイマーは何も行いません。

+0

この返信は正しい軌道に乗るので、私はそれに小切手を渡しています。私は自分の答えを追加して、人々が最終的にそのトリックをしたコードを見ることができるようにします。 – lensonp

1

@ekhumoroが指摘したように、run()の再実装でexec_()を呼び出すことができませんでした。これが主な問題でした。 exec_()呼び出しをどこに置くか、そして作業が終了したときにスレッドを適切に終了する方法を知りました。ここで動作するコードです。

クラス定義、timertester.py

import PySide 

class SubClassThread(PySide.QtCore.QThread): 

     def __init__(self,parent=None): 
       print('called SubClassThread.__init__()') 
       super(SubClassThread,self).__init__(parent) 

     def run(self): 
       print('called SubClassThread.run()') 
       self.delayed_print() 
       self.exec_() 

     def delayed_print(self): 
       print('called SubClassThread.delayed_print()') 
       PySide.QtCore.QTimer.singleShot(1000, self.print_things) 
       print('end of delayed_print()') 

     def print_things(self): 
       print('called print_things') 
       self.quit() 

アプリケーション、test.py

import sys 

import PySide 

from timertester import SubClassThread 

print('Test: QThread subclassing') 

# instantiate a QApplication 
app = PySide.QtCore.QCoreApplication([]) 

# instantiate a thread 
sct = SubClassThread() 

# when the thread finishes, make sure the app quits too 
sct.finished.connect(app.quit) 

# start the thread 
# it will do nothing until the app's event loop starts 
sct.start() 

# app.exec_() starts the app's event loop. 
# app will then wait for signals from QObjects. 
status=app.exec_() 

# print status code and exit gracefully 
print('app finished with exit code {}'.format(status)) 
sys.exit(status) 

そして、python test.pyの最後に、出力:

Test: QThread subclassing 
called SubClassThread.__init__() 
called SubClassThread.run() 
called SubClassThread.delayed_print() 
end of delayed_print() 
called print_things 
app finished with exit code 0 

私はQTimersについて学びました。タイマーがまだrの間にdelayed_print()の呼び出しが終了するunningを呼び出し、タイマーによって呼び出されたメソッドにquit()を入れると、そのメソッドが呼び出されるまでアプリは終了しません。

このコードまたはこの単純なアプリケーションに関連するQtの側面についてさらにご意見がありましたら、投稿してください!私は初心者のためにPyQt/PySideの情報にアクセスするのに苦労しました。

関連する問題