2011-11-10 2 views
3

저는 PyQt4를 처음 접했기 때문에 아마도 bagatelle입니다. 내 GUI에서 작업 스레드에 의해 업데이 트됩니다 진도를 표시하려고합니다 .QProgressBar 다른 메모리 QTableWidget에 있습니다.작업자 스레드별로 진행 상황을 변경하는 방법

작업자 스레드는 내 GUI의 초기화 기능에서 시작됩니다. 내 서버는 그가 스레드에서 원격 prozedure 전화로 촬영 한 것입니다 다음 메소드를 호출하여 데이터베이스에 값을 변경하면 다음

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

는 스레드 클래스

_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

내가 정확히 KNW DNT,하지만 난 안전 스레드로 승리 양식, – 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

헤이와이 문제를 가지고 일단 먼저 답변을 주셔서 감사에서 메소드 호출자 또는 다른 이들처럼 뭔가, U 도움이 될 수 있습니다. 전에 신호를 사용했는데 "주 응용 프로그램이 아직 실행 중입니다 ..."라는 오류 메시지가 표시되고 내 코드가 매우 비슷합니다. – Chris

+0

@Chris. 전체 오류 메시지 및/또는 문제를 일으키는 코드를 보지 않고는 더 이상 도움을 줄 수 없습니다. – ekhumoro

+0

나는 스트레스를 많이받는 순간에 사과했다. 문제를 해결하기 위해 내일 다시 돌아가서 코드 공유를 업로드 할 수있다. – Chris

관련 문제