2013-07-05 4 views
1

기존 관리 콘솔 응용 프로그램에서 GUI를 래핑하려고합니다. 주된 기능은 제한을 특정하고, 시간 제한 (차단 할 슬립을 사용하여) 만료 될 때까지 본질적으로 블로킹 호출이다 네트워크 디바이스를 검색하는 것이다. 이 예에서는 this->Manager->Search(...)입니다.QTListWidget을 강제 업데이트하여 요소를 추가/제거합니다.

내 문제는 검색이 진행되는 동안 QListWidget에 "Searching ..."을 표시 한 다음 검색이 완료 될 때 결과로 업데이트하려고한다는 것입니다. 다음과 같이 Search 버튼 내에서 클릭 코드는 다음과 같습니다

void ManagerGUI::on_searchButton_clicked() 
{ 
    ui->IPList->clear(); 
    new QListWidgetItem(tr("Searching..."), ui->IPList); 
    ui->IPList->repaint(); 
    this->Manager->Search(static_cast<unsigned int>(this->ui->searchTime->value()*1000.0)); 
    ui->IPList->clear(); 
    if(this->Manager->GetNumInList() != 0) 
    this->displayFoundInList(this->Manager->GetFoundList()); 
    else 
    new QListWidgetItem(tr("No Eyes Found"), ui->IPList); 
    ui->IPList->repaint(); 
} 

나는 버튼을 누르면, 타임 아웃이 발생한 후 (나는 가정이 콜백이 종료 된 때까지)까지 QListWidgetIPList 업데이트하지 않습니다 . 누구든지 어떤 제안이 있습니까? 나는 ui->IPList->repaint()를 호출하면 목록을 즉시 다시 그리기를 일으킬 것이라는 인상이었다.

추가 정보 :

  • QT 버전 5.1.0 32 비트 Win7에 프로 64 비트에서 실행 VS2012
  • 은 (그러나 OSX와 리눅스로 포팅 할 사용하여 컴파일 된
  • , 그래서 아무것도 승리 -specific please)
+1

이 관리자 -> 관리자 -> 검색에서 차단하면 다른 스레드에서 실행해야합니다 ... – Trompa

답변

7

1) 직접 다시 칠할 필요가 없습니다.

2) 검색을 비동기 적으로 수행해야합니다. 커다란 주제입니다. 먼저 Qt의 기초를 배워야합니다.

신호 및 슬롯으로 시작한 다음 QThread 또는 QtConcurrent에 대해 알아보십시오. 그런 다음 검색을 수행하고 필요한 신호를 보낼 클래스를 구현하십시오. 검색 시작의 첫 번째 신호, 검색 중지의 두 번째 신호 -. 그런 다음 슬롯을이 신호에 연결하고이 슬롯을 목록보기로 사용하십시오.

문제는 "검색 관리자"가 Qt의 이벤트 루프를 차단한다는 것입니다. ListView가 다시 그려지지 않는 이유가 그 것이다.

+0

위로 투표하십시오. 이것은 아마도 단일 호출 일 것이므로 가장 빠른 구현은 Qt :: Concurrent가 될 것입니다. 빠른 개요는 다음과 같습니다 : http://qt-project.org/doc/qt-4.8/thread-basics.html –

+0

감사 드미트리, 이것은 내가 바라는 답변이 아니더라도 모든 것을 훨씬 명확하게 만듭니다. 나는 다시 그리기 이벤트 콜백 실행에 다른 스레드 공간에서 발생 기대했다,하지만 분명히 나는 ​​가능했던 것보다 lazier 것으로 기대했다. 관리자 코드는 이미 모든 네트워크 I/O를 수행하기 위해 부스트를 사용하므로 작업자 스레드를 생성하고 Q 계층까지 콜백을 등록 할 수 있습니다. 그렇게하면 내 관리자 라이브러리의 다른 사용자도 비동기 호출 옵션을 사용할 수 있습니다. – OcularProgrammer

1

검색이 차단되어 신호 슬롯 시스템이 필요합니다. 이상적으로 새로운 스레드에서 검색을 수행해야합니다. 그러나 당신이 processEvents()

void ManagerGUI::on_searchButton_clicked() 
{ 
    ui->IPList->clear(); 
    new QListWidgetItem(tr("Searching..."), ui->IPList); 
    emit signalStartSearch(); 
} 

void ManageGUI::slotStartSearch() 
{ 
    // Process any outstanding events (such as repainting) 
    QCoreApplication::processEvents(); 
    this->Manager->Search(static_cast<unsigned int>(this->ui->searchTime->value()*1000.0)); 
    emit signalSearchCompleted(); 
} 

void ManagerGUI::slotSeachCompleted() 
{ 
    ui->IPList->clear(); 
    if(this->Manager->GetNumInList() != 0) { 
    ui->IPList->setUpdatesEnabled(false); 
    this->displayFoundInList(this->Manager->GetFoundList()); 
    ui->IPList->setUpdatesEnabled(true); 
    } else { 
    new QListWidgetItem(tr("No Eyes Found"), ui->IPList); 
    } 
} 

과 속임수 수 이상적으로 당신은 Manager->Search 다른 스레드에서 검색을 수행 QtConcurrent::run를 사용하여 다음 신호를 방출하고 싶은 것입니다.

+0

Phil에게 감사드립니다. 해결 방법이 마음에 들지만이 응용 프로그램에서는 총알을 물고 관리자 클래스의 적절한 스레드 기반 구현을 수행해야합니다.정말 흥미로운 반응입니다. Qt의 신호 기능에 대해 더 많은 것을 배울 수 있습니다. – OcularProgrammer