2012-02-09 1 views
1

그래서 기본적으로 메인 GUI 스레드와 작업자 스레드가있는 Qt 응용 프로그램이 있습니다.데이터 포격시 QPlainTextEdit 위젯 최적화?

작업자 스레드는 다음과 같이이다 :

void Client::readResults(int msgqid, pid_t pid) 
{ 
    int ret; 
    msg_t message; 

    connect(this, SIGNAL(dataReceived(QString)), this, SLOT(updateDisplay(QString))); 
    connect(this, SIGNAL(doneProcessing(QString)), this, SLOT(updateStatus(QString))); 

    for (;;) 
    { 
     ret = msgrcv(msgqid, &message, MSGSIZE, pid, 0); 
     if (ret == -1) 
     { 
      showStatusBarError("msgrcv"); 
      return; 
     } 

     if (ret > 0) 
     { 
      emit dataReceived(QLatin1String(message.info)); 

      if (message.is_eof) 
      { 
       emit doneProcessing("Done!"); 
       break; 
      } 
     } 
    } 
} 

그것은 메시지 큐에서 읽고 메인 GUI 스레드에서 QPlainTextEdit 위젯을 (이 스레드를 양산하는) 원인이 신호를 방출이다 않는 모든 appendPlainText (message.info)를 호출하여 메시지 대기열에서 수신 한 데이터가 위젯에 추가되도록하십시오.

큐에서 데이터의 거대한 덩어리 (실제로는 약 30MB 이상의 텍스트 파일)를 읽는 경우 문제가 발생합니다. 전체 GUI는 작업자 스레드가 완료 될 때까지 중단됩니다. 멈추지 않고 작업자 스레드에서 데이터를 받으면 실제로 QPlainTextEdit 위젯 스크롤을 볼 수있는 방법이 있습니까?

감사합니다.

+0

데이터를 청크로 텍스트 편집기에 공급할 수 있습니까? 나는. 수동으로 메시지를 소화 할 수있는 덩어리로 나눕니까? 또 다른 관심사는 QLatin1String에 캐스트입니다. 이것은 새로운 임시 메시지를 만들고 messsage.info의 데이터를 복사 한 다음 슬롯으로 값으로 전송하기 위해 다시 복사됩니다. 불필요한 변환이나 복사를하지 않도록하십시오. –

+0

@AlexanderKondratskiy 30MB 파일은 실제로 메시지 대기열에 배치되기 전에 한 번에 256 바이트 (다른 ​​프로세스에 의해) 읽혀집니다. 그래서 각 emit dataReceived(), message.info는 256 문자입니다. –

+0

흠. 이상 하네. QPlainTextEdit에 문제가 있다고 생각하지 않습니다. 전에 큰 로그를 인쇄하는 데 사용 했으므로. 바보 같은 제안 일지 모르지만 Client 객체는 어디에 생성됩니까? 모든 슬롯이 실제로 주 스레드에서 트리거하므로 GUI 스레드가 아닌 작업자 스레드 내에서 인스턴스화 되었기를 바랍니다. –

답변

0

이전에 비슷한 문제가있었습니다. 필자의 경우, 그리고 경험상 Signal/Slot System은 프로그램 흐름을 잠그고있는 것처럼 보입니다. 많은 양의 데이터를 읽거나 일부 데이터를 자주 읽으면 자연스럽게 GUI가 느려질 수 있습니다.

저에게 도움이 된 것은 모델 기반 입력을 사용하는 것이 었습니다. 안정적이고 원활한 업데이트가 가능했습니다. 입력에서 GUI로 직접 읽을 수 있도록 입력의 재배치를 고려할 수 있습니다.