사용자 도구

사이트 도구


qt:signalsandslots

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

다음 판
이전 판
qt:signalsandslots [2014/02/19 06:09] – 새로 만듦 changwooqt:signalsandslots [2014/10/09 21:24] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 ====== Signals & Slots ====== ====== Signals & Slots ======
  
 +===== 설명 =====
 레퍼런스: http://qt-project.org/doc/qt-5/signalsandslots.html 레퍼런스: http://qt-project.org/doc/qt-5/signalsandslots.html
  
줄 9: 줄 10:
 여기서 시그널과 슬롯을 선언한다고만 해서 무조건 두 객체간에 통신이 이뤄지는 것은 아니다. 둘을 명시적으로 엮어 주어야 시그널의 메시지가 슬롯으로 전달된다. 이 역할을 하는 것이 ''[[http://qt-project.org/doc/qt-5/qobject.html#connect|QObject::connect()]]'' 함수이다. 반대의 역할을 하는 함수는 ''[[http://qt-project.org/doc/qt-5/qobject.html#disconnect|QObject::disconnect()]]'' 여기서 시그널과 슬롯을 선언한다고만 해서 무조건 두 객체간에 통신이 이뤄지는 것은 아니다. 둘을 명시적으로 엮어 주어야 시그널의 메시지가 슬롯으로 전달된다. 이 역할을 하는 것이 ''[[http://qt-project.org/doc/qt-5/qobject.html#connect|QObject::connect()]]'' 함수이다. 반대의 역할을 하는 함수는 ''[[http://qt-project.org/doc/qt-5/qobject.html#disconnect|QObject::disconnect()]]''
  
 +===== SIGNAL(), SLOT() 매크로 =====
 connect() 함수의 슬롯 인자로는 함수 포인터도 가능하지만, 람다 함수의 형태도 가능하다. 또한 함수 포인터를 입력하는 곳에 각각 ''SIGNAL()'', ''SLOT()'' 매크로를 사용 가능한데 함수 포인터 형태가 아닌 함수 형태로 입력 가능하다. 즉, connect() 함수의 슬롯 인자로는 함수 포인터도 가능하지만, 람다 함수의 형태도 가능하다. 또한 함수 포인터를 입력하는 곳에 각각 ''SIGNAL()'', ''SLOT()'' 매크로를 사용 가능한데 함수 포인터 형태가 아닌 함수 형태로 입력 가능하다. 즉,
   connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);   connect(sender, &QObject::destroyed, this, &MyObject::objectDestroyed);
줄 15: 줄 17:
 이 때 SIGNAL의 인자 개수가 SLOT의 인자 개수보다 적어서는 안 된다. 런타임 에러가 날 것이다. 이 때 SIGNAL의 인자 개수가 SLOT의 인자 개수보다 적어서는 안 된다. 런타임 에러가 날 것이다.
  
 +===== 객체 시그널 매핑 =====
 어떤 객체의 시그널을 특정한 객체와 매핑하는 방법이 있다. ''[[http://qt-project.org/doc/qt-5/qsignalmapper.html|QSignalMapper]]''를 이용해 특정 객체의 시그널은 다른 특정 객체의 슬롯으로 매핑 가능하다. 어떤 객체의 시그널을 특정한 객체와 매핑하는 방법이 있다. ''[[http://qt-project.org/doc/qt-5/qsignalmapper.html|QSignalMapper]]''를 이용해 특정 객체의 시그널은 다른 특정 객체의 슬롯으로 매핑 가능하다.
 <code cpp> <code cpp>
줄 35: 줄 38:
 </code> </code>
  
 +===== 자동 시그널 연결 =====
 +[[http://qt-project.org/doc/qt-5/designer-using-a-ui-file.html#automatic-connections]] 
  
 +uic에 의해 특정 이름을 가진 슬롯은 자동으로 시그널과 연결이 된다. 다음 규칙을 보자.
 +  void on_<object name>_<signal name>(<signal parameters>);
 +  
 +일례로 ''void on_okButton_clicked()''는 okButton이란 위젯 내의 객체가 클릭되었을 때 자동으로 호출된다.
  
 +''[[http://qt-project.org/doc/qt-5/qmetaobject.html#connectSlotsByName|QMetaObject]]''는 어떤 오브젝트를 이러한 이름 규칙에 따라 시그널을 연결하도록 만드는 함수이다. 메타 오브젝트를 보면 이게 C++ 인지 파이썬 스크립트인지 헷갈리게 한다.
  
  
 +===== 예제: signal_emitter, signal_receiver =====
 +[[.:HelloWorld]] 예제의 signal_emitter를 약간 수정한 시그널 주고 받기 예제를 기록해 본다.
 +
 +우선 signal_emitter에 시그널을 추가한다.
 +<code cpp>
 +void send(const int);
 +</code cpp>
 +
 +signal_receiver 클래스를 만든다. 물론 QObject를 상속 받아야 한다. 그리고 다음 함수를 슬롯으로 등록한다.
 +<code cpp>
 +void receive(const int value);
 +
 +void signal_receiver::receive(const int value)
 +{
 +  std::cout << "received: " << value << std::endl;
 +}
 +</code>
 +
 +main 함수에서 시그널과 슬롯을 연결한다.
 +<code cpp>
 +// it is assigned at stack. You must declare after the parent.
 +signal_receiver receiver(&app);
 +
 +// emitter-receiver connection
 +QObject::connect(emitter, &signal_emitter::send,
 +                 &receiver, &signal_receiver::receive);
 +</code>
 +
 +signal_emitter의 launch() 함수에 시그널을 보내는 코드를 추가한다.
 +<code cpp>
 +for(int i = 0; i < 10; ++i) {
 +  emit send(i);
 +}
 +</code>
 +
 +결과
 +<code>
 +Hello, world!
 +received: 0
 +received: 1
 +received: 2
 +received: 3
 +received: 4
 +received: 5
 +received: 6
 +received: 7
 +received: 8
 +received: 9
 +</code>
 +변경된 소스는 {{:qt:signal_slots_2.tar.gz|여기}}서 다운로드 가능하다.
 +
 +===== 시그널은 오버로딩 가능할까? =====
 +출처: http://stackoverflow.com/a/16795664
 +
 +우격다짐으로 가능한 것 같아 보이지만, 하지 말자. 좋지 않다.
qt/signalsandslots.1392790182.txt.gz · 마지막으로 수정됨: 2014/10/09 21:23 (바깥 편집)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki