2009-12-28 4 views
5

true를 반환하는 QMetaObject :: invokeMethod를 사용하여 GUI 스레드에서 메서드를 실행하려고합니다. 하지만 Qt :: QueuedConnection을 사용하면 내 메소드가 호출되지 않습니다 (invokeMethod가 true를 반환하더라도). 내가 Qt는 :: AutoConnection 또는 Qt는 :: DirectConnection 방법을 사용하는 경우QMetaObject :: invokeMethod는 true를 반환하지만 메서드는 호출되지 않습니다.

QMetaObject::invokeMethod(this, "draw_widgets", Qt::QueuedConnection) 

내가 ... 을 오류 메시지 또는 아무것도하지 않는 전화를받을 않습니다

내가 사용하고 무엇인가 , 물론 같은 스레드에서. GUI 스레드가 아니라 내가 필요한 것입니다.

draw_widgets는 void draw_widgets() 유형의 공용 슬롯이며 내 클래스는 QObject를 상속하며 Q_OBJECT 매크로도 사용합니다.

나는 이것에 대한 도움이나 방법이 호출되지 않는 이유를 확인하는 방법에 대해 감사하게 생각합니다.

감사합니다.

+0

내가 비슷한 상황이 : QObject에서 상속 받고'Q_OBJECT'를 사용하는 클래스가 있습니다. 이 클래스의 인스턴스는 메인 루프에 생성됩니다. 그런 다음 메인 루프에서 같은 클래스의 메서드를 실행하는 동안'void hideListsSlot()'이 public 루프 인 곳에서 QMetaObject :: invokeMethod (this, "hideListsSlot", Qt :: QueuedConnection); 수업. 슬롯은 호출되지 않습니다. – Giorgio

답변

10

"true"는 메시지가 성공적으로 대기 중임을 나타냅니다. 그렇다고 대기열에있는 메시지가 처리되었다는 것을 의미하지는 않습니다 ...

프로그램에 10 개의 스레드 (Thread1-Thread10)가 있다고합시다. Thread7에서 메시지 대기열에 있습니다. 어떤 스레드가 대기 할 것인가? 이 대기열의 항목은 언제 처리됩니까?

대답은 모든 QObject에는 Thread Affinity이라는 항목이 있으며 이는 대기중인 슬롯이 실행되는 스레드입니다. 기본 연관 관계는 객체가 생성 된 스레드에 대한 것이지만 (QObject::moveToThread()으로 변경할 수 있습니다)

GUI 스레드에 대기열을 지정하려면 this 포인터로 지정된 객체에 GUI 스레드가 있어야합니다 유연. QObject::thread() 방법으로이를 확인할 수 있습니다.

그러나 어떤 경우 에든 대기열에 관계없이 ... 해당 스레드에서 실행중인 일종의 메시지 펌프가 있어야합니다. 예를 들어 QThread::exec()을보십시오. 스레드 친 화성이 GUI에 있다면 아마도 app의 exec를 실행하고 있기 때문에 이미이 경우입니다.

의 (a (!) 참고로, QMetaObject::invokeMethod를 직접 호출은 일반적으로 필요하지 않습니다. 당신은 신호를 생성하고 슬롯에 넥타이, 다음 호출 대신에 신호를 방출 할 수있다.)

+0

답장을 보내 주셔서 감사합니다. 나는 Thread Affinity에 대해 몰랐다. 객체의 선호도를 GUI 스레드로 변경하면 문제가 해결됩니다. –

+0

@HostileFork 반대편 sidenote, 너무 많은 슬롯이 있다면 슬롯과 같은 신호를 생성 할 것이므로이 경우 QMetaObject :: invokeMethod (this, "slot 1 ... n", Qt :: QueuedConnection)'. –

+0

@HostileFork 반대편의 사이드 노트 계속,'invokeMethod' 콜백은 슬롯 내부에서 'if (QThread :: currentThread()! = thread())'를 검사합니다. 이 방법으로 클라이언트는 슬롯을 direclty로 호출 할 수 있습니다. –

관련 문제