2016-11-21 9 views
1

저는 Qt을 처음 사용합니다. std::thread 인 작업자 스레드가 있습니다. 작업자 스레드 함수는 루프의 일부 데이터를 계속 가져옵니다. 데이터의 크기는 요소에서 QML UI로 자주 업데이트됩니다. 나는 청취자 콜백을 가지고 있는데, 이는 단지 std::function이며, thread's function에서 호출된다. 그것은 내가 Text 요소를 업데이트 한 것을 기반으로 콜백을 QML에 보냅니다. 나는 signal slot 메커니즘을 사용하여 업데이트합니다.작업자 스레드에서 Qt :: 신호를 내면 UI가 기본 스레드로 기본 업데이트됩니까?

Text { 
    id: mytext 
    objectName: "mytextobject" 

    function slotUpdateData(someValue){ 
    mytext = someValue 
    } 
} 

SignalUpdateDataQML 측에있는 slotUpdateData 접속되어

다음은 QML : Text 요소이다. std::thread에서 데이터 이벤트 콜백을받을 때마다 emit SignalUpdateDataQML Text elementUI으로 업데이트합니다. 다음

void CallBackReceivedFromWorkerThread(float someValue) { 
    emit SignalUpdateData(someValue) 
} 

내가 QML slot

QObject::connect(this, SIGNAL(SignalUpdateData(QVariant)), myTextItemQObject, SLOT(slotUpdateData(QVariant))); 

으로이 C++ signal을 연결 한 그리고이 모든 것이 잘 작동하는 방법입니다. 아무런 충돌도 일어나지 않습니다.

내 이해에 따르면, 작업자 스레드의 기능이 콜백을 트리거하므로 콜백을 받으면 실행 제어가 작업자 스레드에 있습니다. 따라서 emit SignalUpdateData(someValue)을 수행 할 때 우리는 여전히 작업자 스레드에 있습니다. 이전 경험에서 알 수 있듯이 android & java은 애플리케이션의 main thread 외부에서 UI를 업데이트 할 수 없습니다.

그래서 어떻게 작동합니까? 에 emit SignalUpdateData(someValue) 전화가 걸립니까? 에서 전화를 걸어도 Qtmain thread에 UI 변경을 계속하고 있습니까? 내 접근 방식이 괜찮 으면 성능에 영향을 미칩니 까? 가장 좋은 방법은 무엇입니까?

나는이 점에 대해 매우 확신하고 싶습니다.이 부분을 작동 시키려면 운이 좋은 것은 아닙니다. &. 최상의 접근을 위해 Qt::Connection_enum도 사용해야합니까?

+1

내가 아는 한 (틀릴 수도 있음) 모든 QML은 주/GUI 스레드에서 발생합니다. –

답변

7

당신은 Qt를 그대로 활용하고 있습니다! 그리고 우연히 그것에 뛰어 들었습니다. 그건 괜찮은 디자인의 신호입니다. "그냥 작동합니다". 만세, 너 만있어, Qt는 만세 야 :)

Qt가 작동하도록 특별히 설계 되었기 때문에 효과가있다.이 특별한 경우에 당신을 도울 수있는 기본 자동 연결을 사용하고있다. 그래서 모든 일을 제대로하고 있습니다. 아무 것도 바꾸지 마십시오!

신호를 내 보내면 Qt는 관련 소스 및 대상 객체 뮤텍스를 가져오고 수신 객체의 thread()QThread::currentThread()과 비교합니다. 동일한 경우 슬롯/펑터가 즉시 호출됩니다. 즉, 신호 본문에서 발생하므로 신호가 반환되기 전에 슬롯이 호출됩니다. 타겟 오브젝트가 안전 할 때 thread()에서 사용되므로 안전합니다.

target->thread() != QThread::currentThread() 인 경우 QMetaCallEvent은 대상 개체에 대기합니다. 이 이벤트에는 슬롯 메서드 포인터와 슬롯에서 전달 된 매개 변수의 복사본이 포함됩니다. QObject::event 구현은 이벤트를 처리하고 호출을 실행합니다. 대기열에있는 이벤트를 객체에 전달하는 것이기 때문에 대상 객체 스레드의 이벤트 루프는 호출 스택에 있습니다.

위의 내용은 간단히 말해 Qt::AutoConnection의 의미입니다. Qt::QueuedConnection을 사용하는 경우 두 번째 대소 문자가 스레드와 상관없이 적용됩니다. Qt::DirectConnection을 사용하는 경우 첫 번째 사례가 적용됩니다.

내 생각에, SO에 대한 Qt 관련 질문에서 자동 연결 유형의 95 % 이상은 불필요하며 이해가 부족하고 마법의 주문에 따라 달라집니다.

+0

Qt의 소스 코드에서 이러한 것들이 어디에서 구현되는지도 알 수 있습니까? – Paul

+0

@Paul 대부분 '[QObject'] (https://code.woboq.org/qt5/qtbase/src/corelib/kernel/)의 구현에 있으며 물론 메타 데이터 시스템과 협력합니다. –

+1

http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qobject.cpp#n3690 – BaCaRoZzo