2010-01-05 8 views
15

Qt 신호의 기본 개념을 내게 설명 할 수 있습니까 & 슬롯 메커니즘 구현? 모든 Q_OBJECT 매크로가 "일반 C++에서"무엇을하는지 알고 싶습니다. 이 질문은 신호에 관한 것이 아니며 & 슬롯 사용법입니다.Qt는 신호와 슬롯을 어떻게 구현합니까?

추가 : 내가 Qt는이 ++ 일반 C++에서 Qt는-C를 변환하는 MOC 컴파일러를 사용하는 것을 알고있다. 하지만 moc는 무엇을합니까? 나는 "moc_filename.cpp"파일을 읽을려고하지만 난 이런 걸 의미 할 수 있는지 아무 생각

void *Widget::qt_metacast(const char *_clname) 
{ 
if (!_clname) return 0; 
if (!strcmp(_clname, qt_meta_stringdata_Widget)) 
    return static_cast<void*>(const_cast< Widget*>(this)); 
return QDialog::qt_metacast(_clname); 
} 
+0

dup : http://stackoverflow.com/questions/1406940/how-signal-and-slots-are-implemented-under-the-hood – elcuco

답변

16

Q_OBJECT 매크로는 신호 및 슬롯과 관련하여 나중에 moc으로 정의 될 클래스의 선언에 가상 함수 qt_metacall() 선언을 추가합니다. (또한 변환에 대한 몇 가지 선언을 추가하지만 여기에 너무 중요하지 않아.)

moc는 헤더 파일을 읽어 들여, 매크로를 볼 때, 그것은 가상 기능에 대한 정의를 moc_headerfilename.cpp라는 이름의 또 다른 .cpp 파일을 생성합니다 - 당신은 왜 당신이 신호의 적절한 정의없이 signals:을 당신의 헤더 파일에 언급하는 것으로 벗어날 수 있는지 스스로에게 물어볼 것입니다.

그래서 신호가 호출되면 mocfile의 정의가 실행되고 QMetaObject::activate()이 신호의 이름과 신호의 인수로 호출됩니다. 그러면 activate() 함수는 어떤 연결이 설정되었는지 알아 내고 해당 슬롯의 이름을 가져옵니다. 실제 슬롯 case 문 -

는 그 다음 슬롯 이름과 신호와 큰 switch의 도움으로 metacall 기능 위임이 주어진 인수 qt_metacall를 호출합니다.

신호 슬롯의 실제 이름에 관한 C 가능한 실제 런타임 정보 ++ 없기 때문에, 이미 발견 한 바와 같이, 이들은 하나를 "1"로 (단순 const char*들에 SIGNALSLOT 매크로에 의해 인코딩 될 슬롯과 신호를 구별하기 위해 이름에 "2"가 추가됨).

으로는 qobjectdefs.h에 정의되어

#define SLOT(a)  "1"#a 
#define SIGNAL(a) "2"#a 

-

Q_OBJECT 매크로 응용 프로그램을 번역하는 데 사용할 수있는 개체 내부의 tr() 기능을 정의하고 수행하는 다른 것은.

편집 당신이 qt_metacast가 무엇을하고 있는지 질문한다. 객체가 특정 클래스에 속하는지 여부를 확인하고 포인터가 해당 객체에 포인터를 반환하는지 여부를 확인합니다. 그렇지 않으면 0을 반환합니다.

Widget* w = new Widget(); 
Q_ASSERT(w->qt_metacast("Widget") != 0); 
Q_ASSERT(w->qt_metacast("QWidget") != 0); 
Q_ASSERT(w->qt_metacast("QObject") != 0); 
Q_ASSERT(w->qt_metacast("UnrelatedClass") == 0); 

이렇게하면 달리 반영 할 수없는 런타임 리플렉션을 제공해야합니다. 예를 들어,이 함수는 QObject::inherits(const char *)에서 호출되고 단순히 상속을 확인합니다.

+1

자세한 내용은이 블로그 게시물을 참조하십시오. http://woboq.com/blog/how-qt-signals-slots-work.html – guruz

3

그 매크로, "++ 일반 C에서"정말 아무것도하지 않는다 - 그들이 문자열을 (내가 생각하는) 비우 확장을 .

QT는 (다른 것들 중에서 정의 신호/슬롯을 구현) Q_OBJECT 가능한 클래스 C++ 코드를 생성하는 메타 오브젝트 컴파일러를 사용한다.

당신은 official documentation에 대한 자세한 내용을보실 수 있습니다.

+0

참으로. 사실 코드를 컴파일하면 생성 된 소스를 볼 수 있습니다. –

+1

시그널과 시그널은 신호를 시그널에'connect()'할 수있는만큼 작은 차이가있을 필요가 있습니다. 그러면 그 시그널이 의미하는 것이 명확하지 않을 것입니다. – Debilski

-1

기본적인 아이디어는 당신이 신호가 완료되면 그들이하는 방법 (슬롯)을 실행 할 수 있도록 개체를 연결할 수 있다는 것입니다.

connect(pistol,SIGNAL(sigShoot()),runner,SLOT(slotRun())) 

위의 연결을 통해 권총이 신호를 내면 주자가 슬롯을 실행합니다.

당신은 각각의 클래스에 신호와 슬롯을 선언해야,이 작업을 수행합니다.

은 기본 개념입니다.

행운을 빈다.

+5

하지만 OP는 내부 구현에 대해 묻는 것이지 사용 방법은 묻지 않았습니다. –

+0

dojo가 메시지 시스템을 다루는 것과 같은 생각입니다. –

관련 문제