2011-11-10 9 views
3

私はPyQt4を初めて使っていますので多分バガテルです。私はワーカースレッドによって更新される私のGUIで進捗状況を表示しようとします.QProgressBarはQTableWidget内の他のメモリと一緒です。ワーカースレッドによる進捗状況を変更するには

ワーカースレッドは、自分のGUIのinit関数で開始します。ここで

self.st = ServerThread() 
    self.st.start() 

私のサーバーは、彼がスレッドでリモートprozedureコールで撮影します次のメソッドを呼び出しますデータベース内の値を変更した場合、スレッドクラス

_exportedMethods = { 
    'changes': signal_when_changes, 
} 

class ServerThread(QtCore.QThread): 

    def __init__(self): 
     super(ServerThread,self).__init__() 
     st = self 
     #threading.Thread.__init__(self) 
    def run(self): 
     HOST = ''  # local host 
     PORT = 50000 
     SERVER_ADDRESS = HOST, PORT 

    # set up server socket 
     s = socket.socket() 
     s.bind(SERVER_ADDRESS) 
     s.listen(1) 

     while True: 
      conn, addr = s.accept() 
      connFile = conn.makefile() 
      name = cPickle.load(connFile) 
      args = cPickle.load(connFile) 
      kwargs = cPickle.load(connFile) 
      res = _exportedMethods[name](*args,**kwargs) 
      cPickle.dump(res,connFile) ; connFile.flush() 
      conn.close() 

です。

def signal_when_changes(): 
    s = Subject() 
    s.advise() 

パターンは簡単なオブザーバで、GUIが更新されました。私のGUI内のテーブルを更新するには、以下のメソッドが呼び出されます。

def refresh(self,table): 
    clients = self.db.get_clients() 
    if(self.ui.mainTable.rowCount() != len(clients)): 
     self.search_add_client 
    allRows = table.rowCount() 
    for row in xrange(0,allRows): 
     for c in clients: 
      if table.item(row,0).text() == c.get_macaddr().text(): 
       self.refresh_line(table,row,c) 

このメソッドは、必要に応じて次のメソッドがこれを行う場合、行に変更があったかどうかをチェックします。

def refresh_line(self,table,rowNumber,client): 
    table.item(rowNumber, 0).setText(client.get_macaddr().text()) 
    table.item(rowNumber, 1).setText(client.get_product().text()) 
    table.item(rowNumber, 2).setText(client.get_site().text()) 
    table.item(rowNumber, 3).setText(client.get_hostname().text()) 
    table.item(rowNumber, 4).setText(client.get_priv_data().text()) 
    table.cellWidget(rowNumber, 5).setValue(client.get_progress_value()) 
    table.item(rowNumber, 6).setText(client.get_stage().text()) 

他のメモリの更新が、することができない進行、ここで私は、この行の後に進行

self.ui.mainTable.setCellWidget(appendRowIndex,5,c.get_progress()) 

にGUIがクラッシュを更新したいと私は次のメッセージを取得した行

QPixmapの:GUIスレッド

外ピックスマップを使用することは安全ではありません

私の推測では、私は "Main/Gui"スレッドの外でQPixmapsを変更できないということです。私はこの問題をどのように解決できるかわからないので、解決のためのすべての提案を歓迎します。

ありがとうございます。

+0

私はスレッドセーフとして勝利フォームでこの問題を得た後 – Red

答えて

2

スレッド内からプログレスバーを更新しようとしないでください。代わりに信号を使用してください。

from PyQt4 import QtCore, QtGui 

class Thread(QtCore.QThread): 
    def __init__(self,parent): 
     QtCore.QThread.__init__(self, parent) 

    def run (self): 
     for step in range(5): 
      self.sleep(1) 
      self.emit(QtCore.SIGNAL('taskUpdated')) 

class Window(QtGui.QWidget): 
    def __init__(self): 
     QtGui.QWidget.__init__(self) 
     self.button = QtGui.QPushButton('Start', self) 
     self.progress = QtGui.QProgressBar(self) 
     layout = QtGui.QVBoxLayout(self) 
     layout.addWidget(self.button) 
     layout.addWidget(self.progress) 
     self.connect(self.button, QtCore.SIGNAL('clicked()'), 
        self.handleButton) 
     self.thread = Thread(self) 
     self.connect(self.thread, QtCore.SIGNAL('taskUpdated'), 
        self.handleTaskUpdated) 

    def handleButton(self): 
     self.progress.setRange(0, 4) 
     self.progress.setValue(0) 
     self.thread.quit() 
     self.thread.start() 

    def handleTaskUpdated(self): 
     self.progress.setValue(self.progress.value() + 1) 

    def closeEvent(self, event): 
     self.thread.wait() 

if __name__ == "__main__": 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.show() 
    sys.exit(app.exec_()) 
+0

、私は正確にKNW DNTが、メソッドの呼び出しや他の人のようなものは、uのを助けるかもしれねえ、最初に答えてくれてありがとう。私は以前にシグナルを使用していましたが、「メインアプリケーションはまだ実行中です...」というエラーメッセージが表示され、コードはご自分のものと非常によく似ていました – Chris

+0

@Chris。完全なエラーメッセージや問題の原因となるコードを見ることなく、さらに支援することは不可能です。 – ekhumoro

+0

私は現時点で多くのストレスに謝っています。問題を解決するために明日戻ってきて、コードシェアをアップロードできます。 – Chris

関連する問題