2009-12-29 2 views
0

QT3에서 QT4로 응용 프로그램을 포팅하고 스레드가 QProgressDialog를 업데이트 할 때 문제가 계속 발생합니다. 원래 코드는 다음과 같이 대략 설계되었습니다.QT3에서 QT4로 스레드 포팅

이것은 Qt3to4를 실행하고 QT 포팅 가이드에서 적절하게 변경 한 것입니다. ScanProcessThread 내부의 원래 디자인에서

:

void ScanProcessThread::run(){ 
//... 
ProgressInfo *prog = new ProgressInfo(); //then fill it in 
QCustomEvent* progEvent = new QCustomEvent(QEvent::User+1, (void*)prog); 
QCoreApplication::postEvent(parent, progEvent);//Parent is pointer to the ScanProcess 
//... 
} 

void ScanProcess::customEvent(QCustomEvent *e){ 
    if(e->type() == QEvent::User+1){ 
    //update QProgressDialog 
    progres->setValue(prog.index);//Value from the ProgressInfo passed above 
    //This line crashes deep in ntdll, but I have traced it to the QProgressDialog::repaint() 
    } 
} 

struct ProgressInfo {int count; int index; QString text;}; 

그래서,이 중요한 코드입니다. QProgressDialog :: Repaint에 대한 호출은 항상 ntdll의 어딘가에서 충돌하는 것처럼 보입니다. 나는 다른 두 가지 방법을 시도했다. QCoreApplication :: postEvent() 사용 2) QProgressDialog *를 전달하고 ScanProcessThread가이를 직접 업데이트하도록한다. 모든 경우에 실패하는 것은 QProgressDialog :: repaint()입니다. 어떤 아이디어?

(qt4.4, 윈도우 XP SP3을, 비주얼 스튜디오 2008 /) 만 메인 쓰레드가 GUI에 액세스 할 수 있기 때문에, 당신은 당신이 메인 스레드에서 ScanProcess::customEvent() 처리 루틴을하고 있는지 확인해야

+0

그냥 메모하지만 진행률 정보를 전달하기 위해 내 자신의 맞춤 이벤트 클래스를 만들겠다. 게시하는 객체가 포인터를 삭제하지 않으면 잠재적으로 메모리 누수가 발생합니다. 게시 한 코드에는 포인터가 삭제되지 않습니다. 또한 게시 된 클래스가 이벤트를 처리하기 전에 사라지거나 파생 클래스가이를 오버라이드하고 그렇게하지 못하거나 또는 잊어 버린 경우 메모리를 확보 할 수 없습니다. –

+0

@cjhuitt 만약 내가 가진다면 많은 일을 할 것입니다. 즉,이 코드는 customEvent에서 자체 포인터를 정리하는 작업을 처리합니다 (해당 행을 추가하는 것을 잊었습니다). –

답변

0

. 일반적으로 가장 쉬운 방법은 신호를 내보내거나 처리하는 스레드가 own event loop인지 확인하는 것입니다.

+0

나는 ScanProcess 클래스가 메인 스레드에서 인스턴스화되지 않았지만 다른 스레드에서는 충돌이 발생한다고 생각한다. –

+0

QT가 메인 스레드에서 GUI 업데이트가 필요한 이유는 무엇입니까? –

+0

@David Souther : GUI 루틴은 스레드로부터 안전하지 않습니다. 대부분의 OS에서 GUI 호출이 좀 더 정밀한 세분성을 사용하는 대신 숨겨진 로컬 상태를 '프로세스 당'색인화하여 전체 GUI API를 스레드로부터 안전하지 않게 만드는 것을 감안할 때 매우 어렵습니다. – Javier