Qt의 일반 함수 인 것처럼 emit 사용과 신호 호출


97

이 신호가 있다고 가정 해 봅시다.

signals:
    void progressNotification(int progress);

Qt의 emit 키워드에 대해 최근에야 배웠습니다. 지금까지는 일반 함수처럼 신호를 호출하여 신호를 실행했습니다. 그래서 대신 :

emit progressNotification(1000 * seconds);

나는 다음과 같이 쓸 것이다.

progressNotification(1000 * seconds);

그렇게 호출하면 작동하는 것 같고 연결된 모든 슬롯이 실행되므로 emit 키워드를 사용하면 다른 동작이 발생합니까? 아니면 구문 설탕입니까?


17
+1 몰랐습니다 emit필요하지 않습니다. 그것은 당신이에 대해 배운 이상한 생각의 emit신호 슬롯 시스템은 Qt는에 대해 알게되는 최초의 것들 중 하나이기 때문에, 직접 신호를 호출 한 후 오래.
Christian Rau 2012

답변:


88

emit통사론 적 설탕입니다. 신호를 방출하는 함수의 전처리 된 출력을 보면 emit그냥 사라진 것을 볼 수 있습니다 .

"마법"은 신호 방출 함수에 대해 생성 된 코드에서 발생하며 moc에 의해 생성 된 C ++ 코드를 검사하여 확인할 수 있습니다.

예를 들어 foo매개 변수가없는 신호는 다음 멤버 함수를 생성합니다.

void W::foo()
{
    QMetaObject::activate(this, &staticMetaObject, 0, 0);
}

그리고 코드 emit foo();는 단순히foo();

emitQt/qobjectdefs.h(어쨌든 소스의 오픈 소스 풍미에서) 다음과 같이 정의됩니다 .

#ifndef QT_NO_EMIT
# define emit
#endif

(define guard는 no_keywordsQMake 구성 옵션을 통해 충돌하는 이름을 가진 다른 프레임 워크와 함께 Qt를 사용할 수 있도록하는 것 입니다.)


14
emit실제로 아무것도하지 않은 의 구현 (또는 계획된 구현)이 있었는지 아십니까 ? 이 경우 '구문 적 설탕'을 사용하는 것은 초보자 (또는 초보자 Qt 사용자 일 때는 적어도 나)를 혼동하는 emit것입니다. all-모든 마법 moc은 ( mocQt 신호 및 슬롯의 마법)을 생성 하는 일반 오래된 함수에서 발생합니다 . emit아무것도하지 않고 중요해 보이는 불필요한 장식입니다.
Michael Burr

12
방출은 "단지 장식" 이 아닙니다 . emit호출을 읽는 사람에게 마법이 일어나려고한다는 것을 알려줍니다 (즉,이 클래스가 잠재적으로 들어 본 적이없는 객체의 코드를 트리거 할 것이며 이러한 호출은 동기식 또는 비동기식 일 수 있음). 키워드를 생략하면 본질적으로 완전히 손실됩니다. 그걸 써. 자동 문서화입니다. "초보자"는 문서 및 자습서를 읽어야하며 emit항상 거기에 있습니다 (어쨌든 공식 문서에 있음). 함수를 호출 할 수 있다는 사실을 발견하는 것은 "빛을 본"후에 일어나야합니다. 그 시점에서 더 이상 초보자가 아닙니다.
Mat

19
흠, emit'키워드'의 가치에 대해 동의하는지 잘 모르겠습니다 . 함수 호출이 시그널이라는 것을 명확히 할 필요가 있다면 명명 규칙을 사용하는 것을 선호했을 것입니다.
Michael Burr

2
글쎄, 나는 그것에 근본적으로 동의하지 않는다 :) 명명 규칙을 강요하는 것은 프로젝트 / 작업장에서 스스로 할 수있는 일이다. Qt는 그것을 막지 않는다. Qt는 "키워드"를 사용하도록 강요하지 않으며, 코드의 다른 부분과 충돌 할 경우이를 끌 수도 있습니다. 제 생각에는 키워드 접근 방식이 더 낫습니다. 컴파일러는 이름 지정 정책을 시행하는 데 도움을 줄 수 없지만 철자가 잘못된 emit.
Mat

15
명확하게하려면 - 나는 이름 지정 규칙을 사용하는 것이 옹호하지되었다 - 그냥 경우 에 대한 이유 emit사이비 - 키워드 댓글이 신호가 호출되고 있음을 분명히했다, 다음 이름 지정 규칙이 동일한 기능을 수행 할 수 없음으로 미스터리와 비슷한 이점이 있습니다. 명명 규칙은 Qt에 의해 시행 moc될 수 없었지만 (실제로 시행 할 수는 있었지만 저도 그것을 옹호하지는 않습니다), Qt는 emit둘 중 하나를 사용하도록 강요 할 수 없습니다 . emit이름 충돌이 발생하면 '끄기'를 할 수 있지만, (부팅에 불필요하게) 사용하는 소스 파일이 많으면 큰 도움이되지 않습니다.
Michael Burr

2

18 개월 후 ... @Mat의 답변으로 댓글을 달기 시작했고 곧 방이 부족해졌습니다. 따라서 대답.

IMO emit는 통사론 적 설탕도 아니고 단순한 키워드도 아닙니다.

  1. 위의 @Mat에서 설명한대로 코드를 생성합니다.
  2. 그것은 도움이 connect메커니즘은 그것이입니다 실제로 것을 인식 signal하고,
  3. 신호와 응답 (슬롯)이 동기식 또는 비동기식으로 실행되거나 신호가 방출되는 위치와 방법에 따라 대기 할 수있는 "더 큰"시스템의 일부가됩니다. 이것은 신호 / 슬롯 시스템의 매우 유용한 기능입니다.

전체 신호 / 슬롯 시스템은 단순한 함수 호출과는 다른 관용구입니다. 관찰자 패턴에서 비롯된 것이라고 생각합니다. a signal와 a 사이에도 큰 차이가 있습니다 slot. 신호 구현할 필요가 없지만 슬롯 !

당신은 길을 걷고 있는데 집에 불이 붙는 것을 본다 (신호). 911에 전화를 겁니다 ( 화재 신호를 911 응답 슬롯에 연결 ). 신호는 방출 된 반면 슬롯 소방서 에서 구현 되었습니다. 정확하지 않을 수 있지만 아이디어를 얻습니다. OP의 예를 살펴 보겠습니다.

일부 백엔드 객체는 얼마나 많은 진행이 이루어 졌는지 알고 있습니다. 그래서 그것은 단순히 emit progressNotification(...)신호를 보낼 수 있습니다. 이 신호를 선택하고 실행하는 것은 실제 진행률 표시 줄을 표시하는 클래스에 달려 있습니다. 그러나 뷰는이 신호에 어떻게 연결됩니까? Qt의 신호 / 슬롯 시스템에 오신 것을 환영합니다. 이제 뷰 객체와 데이터 계산 객체 (둘 다 QObjects) 로 구성된 관리자 클래스 (일반적으로 일종의 위젯 )를 생각할 수 connect (m_myDataEngine, &DataEngine::progressNotification, m_myViewObj, &SimpleView::displayProgress)있습니다.

관리자 클래스의 디자인 측면에 대해 살펴 보지 않겠습니다. 그러나 이것이 신호 / 슬롯 시스템이 빛나는 곳이라고 말하면 충분합니다. 내 애플리케이션을위한 매우 깨끗한 아키텍처를 설계하는 데 집중할 수 있습니다. 항상 그런 것은 아니지만 종종 나는 단지 신호를 내고 슬롯을 구현 한다는 것을 알게 됩니다.

시그널 메서드 를 방출하지 않고 사용 / 호출 할 수 있다면 , 그것은 반드시 그 함수 가 처음에 시그널로 필요하지 않았 의미합니다 .


6
아니요, emit실제로 빈 매크로 일 뿐이며 순전히 선택 사항입니다. 그리은 키워드입니다 signalslot되는 MOC에 의해 처리된다. signal함수의 구현을 제공하는 slot데 사용되며, SLOT(MySlot())매크로 또는 QML에서 찾을 수 있도록 메타 개체 항목을 만드는 데 사용됩니다 . emit통사론 적 슈가입니다. 글을 쓰더라도 emit i++;(동료 일 수도 있음) 불평 하지 않고 여전히에 연결할 수 없습니다 i++.
derM

-5

두 번째 옵션은 함수 이름과 함수 매개 변수가 무엇인지 항상 알고 있으며이를 보내는 객체가 특정 함수에 의해 알려져 있음을 의미합니다. 이 두 가지 경우는 항상 사실이 아니므로 슬롯과 신호가 만들어진 두 가지 주요 이유입니다. "후드"신호 및 슬롯 메커니즘은 연결된 모든 기능에 대한 포인터가있는 테이블 일뿐입니다.

또한 신호 및 슬롯 메커니즘의 특성을 매우 명확하게 설명하는이 pdf를 참조하십시오 . http://www.elpauer.org/stuff/a_deeper_look_at_signals_and_slots.pdf


두 가지 방법 모두 시그널 이름과 그 매개 변수를 알아야합니다. 당신은 그것을 방출하고 있습니다. 어떻게 당신이 모르는 것을 방출 할 수 있습니까? 둘 다 동일한 의미를 가지고 있으며 동일합니다.
Mat

1
직접 슬롯 호출로 신호 호출을 엉망으로 만들고 있습니까? 하지만 처음에는 질문 제목에 대해 궁금해했다는 사실을 인정해야 emit합니다. 그러나이 경우에도 문제 본문을 읽으면 문제가 해결되어야하므로 -1입니다.
Christian Rau 2012
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.