2017-03-14 6 views
0

私はサーバー上でリモートスクリプトを実行するプログラムを書いています。だから、私はバーで進捗状況を示す必要がありますが、何とかコードを実行すると、GUIがフリーズし始めます。私はQThreadとSIGNALを使用しましたが、残念ながらsuccedeedはできませんでした。スレッドによるPyQt進捗バーの更新

以下は私のコードです。私はこの方法をupdateProgressBar見て期待してい

class dumpThread(QThread): 

    def __init__(self): 
     QThread.__init__(self) 

    def __del__(self): 
     self.wait() 

    def sendEstablismentCommands(self, connection): 

     # Commands are sending sequently with proper delay-timers # 

     connection.sendShell("telnet localhost 21000") 
     time.sleep(0.5) 
     connection.sendShell("admin") 
     time.sleep(0.5) 
     connection.sendShell("admin") 
     time.sleep(0.5) 
     connection.sendShell("cd imdb") 
     time.sleep(0.5) 
     connection.sendShell("dump subscriber") 

     command = input('$ ') 

    def run(self): 
     # your logic here    
     # self.emit(QtCore.SIGNAL('THREAD_VALUE'), maxVal) 
     self.sendEstablismentCommands(connection)  

class progressThread(QThread): 

    def __init__(self): 
     QThread.__init__(self) 

    def __del__(self): 
     self.wait() 


    def run(self): 
     # your logic here 
     while 1:  
      maxVal = 100 
      self.emit(SIGNAL('PROGRESS'), maxVal) 

class Main(QtGui.QMainWindow): 
    def __init__(self): 
     QtGui.QMainWindow.__init__(self) 
     self.ui = Ui_MainWindow() 
     self.ui.setupUi(self) 
     self.ui.connectButton.clicked.connect(self.connectToSESM) 



    def connectToSESM(self): 
     ## Function called when pressing connect button, input are being taken from edit boxes. ## 
     ## dumpThread() method has been designed for working thread seperate from GUI. ## 

     # Connection data are taken from "Edit Boxes" 
     # username has been set as hardcoded 

     ### Values Should Be Defined As Global ### 
     username = "ntappadm" 
     password = self.ui.passwordEdit.text() 
     ipAddress = self.ui.ipEdit.text() 

     # Connection has been established through paramiko shell library 
     global connection 

     connection = pr.ssh(ipAddress, username, password) 
     connection.openShell() 
     pyqtRemoveInputHook() # For remove unnecessary items from console 

     global get_thread 

     get_thread = dumpThread() # Run thread - Dump Subscriber 
     self.progress_thread = progressThread() 

     self.progress_thread.start() 
     self.connect(self.progress_thread, SIGNAL('PROGRESS'), self.updateProgressBar) 

     get_thread.start()  




    def updateProgressBar(self, maxVal): 

     for i in range(maxVal): 
      self.ui.progressBar.setValue(self.ui.progressBar.value() + 1) 
      time.sleep(1) 
      maxVal = maxVal - 1 

      if maxVal == 0: 
       self.ui.progressBar.setValue(100) 

    def parseSubscriberList(self): 
     parsing = reParser() 

    def done(self): 
     QtGui.QMessageBox.information(self, "Done!", "Done fetching posts!") 




if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    main = Main() 
    main.show() 
    sys.exit(app.exec_()) 

はSIGNALと呼ばれ、そのプロセスは、別々のスレッドを通過しました。私はどこに行方が見つからないのか分かりません。

ありがとうございました

+0

のようなプログレスバーを書く方が良いでしょうか?進歩することができます:progress_update = QtCore.Signal(int)? – nuriselcuk

+0

1. 'progressThread'の目的は何ですか?あなたはワーカースレッドを持っており、それに応じてGUIを更新したいので、3番目のスレッドの必要性がわかりません。 2.なぜあなたは 'updateProgressBar'にループを持っていますか?なぜ、各繰り返しの間に 'maxVal'を減らすのですか?そして、なぜあなたはそこに 'time.sleep'を持っていますか?もちろん、あなたのメインスレッドが眠った場合にはフリーズします。また、 'updateProgressBar'への各呼び出しは' maxVal'が最後の反復のためにゼロであるので 'self.ui.progressBar.setValue(100)'を実行することになります。 –

答えて

1

実際には2つの問題があります。私が気づいたことの1つは、シリアルポートからの読み込みのようなIO操作にPythonスレッドを使用しないと、Pythonスレッドが貪欲であるということです。スレッドに計算やIO関連でないものを実行するように指示すると、スレッドはすべての処理を行い、メインスレッド/イベントループを実行させたくありません。 2番目の問題は、信号が遅いことです...非常に遅いです。私はあなたがスレッドから信号を出して非常に速くすると、プログラムを大幅に遅くすることがあることに気付きました。

問題の中心にあるスレッドは、すべての時間を占めており、非常に高速で信号を発信しているため、スローダウンが発生します。

わかりやすく使いやすくするために、新しいスタイルの信号とスロットを使用します。 http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html

class progressThread(QThread): 

    progress_update = QtCore.Signal(int) # or pyqtSignal(int) 

    def __init__(self): 
     QThread.__init__(self) 

    def __del__(self): 
     self.wait() 


    def run(self): 
     # your logic here 
     while 1:  
      maxVal = 100 
      self.progress_update.emit(maxVal) # self.emit(SIGNAL('PROGRESS'), maxVal) 
      # Tell the thread to sleep for 1 second and let other things run 
      time.sleep(1) 

は、新しいスタイルの信号

... 
self.progress_thread.start() 
self.process_thread.progress_update.connect(self.updateProgressBar) # self.connect(self.progress_thread, SIGNAL('PROGRESS'), self.updateProgressBar) 
... 

EDIT 申し訳ありませんが、別の問題があるに接続します。シグナルが関数を呼び出すと、その関数に永遠に残ることはできません。その関数は、メインイベントループで実行されている別のスレッドで実行されておらず、メインイベントループは、その関数を終了するまで実行を待機します。

アップデートの進行状況が1秒間スリープしてループを繰り返します。ぶら下がりはこの機能にとどまることから来ています。

def updateProgressBar(self, maxVal): 

    for i in range(maxVal): 
     self.ui.progressBar.setValue(self.ui.progressBar.value() + 1) 
     time.sleep(1) 
     maxVal = maxVal - 1 

     if maxVal == 0: 
      self.ui.progressBar.setValue(100) 

私が、信号に整数を定義することができますどのように

class progressThread(QThread): 

    progress_update = QtCore.Signal(int) # or pyqtSignal(int) 

    def __init__(self): 
     QThread.__init__(self) 

    def __del__(self): 
     self.wait() 


    def run(self): 
     # your logic here 
     while 1:  
      maxVal = 1 # NOTE THIS CHANGED to 1 since updateProgressBar was updating the value by 1 every time 
      self.progress_update.emit(maxVal) # self.emit(SIGNAL('PROGRESS'), maxVal) 
      # Tell the thread to sleep for 1 second and let other things run 
      time.sleep(1) 


def updateProgressBar(self, maxVal): 
    self.ui.progressBar.setValue(self.ui.progressBar.value() + maxVal) 
    if maxVal == 0: 
     self.ui.progressBar.setValue(100) 
+0

あなたの答えをありがとうが、私のGuiはまだ凍っています。変化しないように見えます。ところで、私はpyqtSignal(int)を使用しました – nuriselcuk

+0

私は私の答えを編集し、updateProgressBarの滞在に関する情報を長時間にわたって追加しました。 – HashSplat

+0

はい、あなたは正しいです、コードはprogressBarUpdateのforループを終了するのを待っています。私はそれが今働いている更新しました。全てに感謝 – nuriselcuk

関連する問題