2017-10-18 7 views
0

ボタンを押すと、時間がかかるコードが実行されます。それが実行されている間、私はボタンがそれ以上のクリックに反応するのを避けたい。コードが完了すると、ボタンを再度有効にして、さらにクリックを処理する必要があります。私が使用していることをやろうとしているpyqt:QPushButtonの複数のクリックを無効にする方法は?

self.btn.blockSignals(True) 
    self.btn.setEnabled(False) 
    ... code ... 
    self.btn.blockSignals(True) 
    self.btn.setEnabled(False) 

しかしをまだ、私は急速にこのボタンを10回クリックすると、コードが10回実行されます...実際には

私は」時間のかかるコードを別のスレッドに移動する。 (編集:が、それでも問題は同じである - 私は??と思い、それを解決して現実にaccepted answerを参照してください。。。)

何かが実行されている間、どのように私はボタンにクリックをブロックしたり、無視していますか?あなたがスレッドで長時間走っコードを置く場合は、スレッドが開始されると、制御ができるようになる、メインイベントループに戻ることができ

import time 
import sys 
from PyQt4 import QtGui 

class Example(QtGui.QWidget): 

    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 

    def initUI(self): 
     grid = QtGui.QGridLayout() 
     self.setLayout(grid) 
     self.btn = QtGui.QPushButton('Count') 
     grid.addWidget(self.btn, 1, 1) 
     self.txt1 = QtGui.QTextEdit() 
     grid.addWidget(self.txt1, 1, 2) 
     self.btn.clicked.connect(self.click) 
     self.count = 0 
     self.show() 

    def click(self): 
     # Here I want to block any further click in the button, but it is 
     # not working - clicking it 10 times quickly will run this 10 times... 
     self.btn.blockSignals(True) 
     self.btn.setEnabled(False) 
     time.sleep(2) # time consuming code... 
     self.count += 1 
     self.txt1.append(str(self.count)) 
     self.repaint() 
     self.btn.setEnabled(True) 
     self.btn.blockSignals(False) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 
+0

私はPyQtは精通していないが、私は、次のリンクが見つかりました: [リンク](https://stackoverflow.com/questions/14087066/disablingを-qpushbutton-before-a-task) 'self.btn.setEnabled(False)'の下に 'QCoreApplication :: processEvents()'を追加する必要があるかもしれません。 – Spezi94

+0

私のシステムでは、 'processEvents'は動作しませんが、スレッドは動作します。 – ekhumoro

+0

あなたは新しいスレッドにコードを移動することを意味しますか?シグナルをブロックすべきか(False)もスレッドに移動する必要がありますか? – Raf

答えて

1

は、ここに私のコードの最小バージョンですすぐに更新するGUI。ここで

はあなたの例に基づいて基本的なデモです:

import sys 
from PyQt4 import QtGui, QtCore 

class Thread(QtCore.QThread): 
    def run(self): 
     QtCore.QThread.sleep(2) 

class Example(QtGui.QWidget): 
    def __init__(self): 
     super(Example, self).__init__() 
     self.initUI() 

    def initUI(self): 
     grid = QtGui.QGridLayout() 
     self.setLayout(grid) 
     self.btn = QtGui.QPushButton('Count') 
     grid.addWidget(self.btn, 1, 1) 
     self.txt1 = QtGui.QTextEdit() 
     grid.addWidget(self.txt1, 1, 2) 
     self.btn.clicked.connect(self.click) 
     self.thread = Thread() 
     self.thread.finished.connect(lambda: self.btn.setEnabled(True)) 
     self.show() 

    def click(self): 
     self.txt1.append('click') 
     if not self.thread.isRunning(): 
      self.btn.setEnabled(False) 
      self.thread.start() 

if __name__ == '__main__': 

    app = QtGui.QApplication(sys.argv) 
    ex = Example() 
    sys.exit(app.exec_()) 
+0

華麗な、ありがとう!私はこの重要なコンセプトが欠けていました。時間のかかる作業でメインイベントループをブロックしないでください。 – Raf

関連する問題