신호 슬롯 및 타이머 - QT, 부 II에 시작
이 게시물에서 나는 QT에서 초보자를위한 작은 튜토리얼을 할 수있는 게임을 따랐다. 이번엔 내가 자신의 신호와 슬롯 및 타이머를 처리할를 만드는 방법을 보여줍니다.
소스 코드는이에서 찾을 수 있습니다 링크 .
예제 프로그램은 클래스를 사용하는 타이머이다 QTime , QT의 주요 클래스 중 하나를, 그리고 당신에게 수업에 계산기를 사용하여 스타일 LCD 디스플레이가 표시됩니다 QLCDNumber를 .
QT와 타이머
QT에서 가장 기본적인 지원 타이머 방법을 제공 QObject 클래스에서 사용할 수 있습니다 : startTime () : QObject를 하고 QObject : : KillTimer () . 첫 번째 방법은 고유 ID를 반환하고 두 번째 타이머는이 ID를 통해 타이머를 종료됩니다.
작업이 들어 있지만,이 메커니즘을 사용하여 코드 조각은 "이벤트 루프"안에 있어야합니다. 일단 타이머가 그것 수시로 시작 (시간 초과) 응용 프로그램을 만드는 Dispater QTimerEvent 이벤트가 처리 될때까지 프로그램의 정상적인 흐름을 방해.
최대 제한이 정의되지 않은, 그건 년 초과와 타이머를 만들 수 있습니다, 그러나, 최소한의 시간은 시스템에 따라 다를 수 있습니다. 리눅스 2.6.x이가 (기본값은 4입니다 MS) 구성할 수있는 동안 Windows Vista의 최소 타이머는 10 MS입니다. Qt는 요청에 따라 모든 이벤트를 제공하기 위해 노력할 것입니다하지만, 시스템이 허락하지 않는다면 그것은 드롭 "흑자를."
타이머 스레드에서도 사용할 수 있지만, 당신은 이벤트 루프 내부되는 상태를 존중해야합니다. 스레드는 항상 별도의 기사를받을 자격이 ...
클래스 QTime는 일부 기능을 사용, 타이머보다 높은 수준을 구현합니다. 하나는이다 singleShot () : QTime 한 번 이벤트를 발생시킵니다.
광범위한 설명서 및 지루한 반복을 읽고,하지만 날 믿어, 당신은 QDorDeCabeca을 많이 저장됩니다 ...
신호와 슬롯에 관한 자세한
신호와 슬롯은 개체, QT의 중앙 중 하나를 사이에 통신을 위해 사용됩니다. 이벤트를 처리하는 콜백을 구현하기보다는이 시스템에서, 우리는 프로그래밍이 더 직관하고, 슬롯에 신호를 연결의 개념을 사용합니다.
신호와 슬롯에 의해 처리하는 수업 방법입니다 메타 객체 컴파일러 (moc) 소스 코드를 컴파일해야하기 전에. 그들은 표준 C + +, fazum moc는 소스 코드를 구문 분석되므로 발생 compilable의 일부가 아닌 특별한 진술을했습니다.
신호와 슬롯을 구현하는 클래스에 moc 명령을 실행하여 소스 코드의 특정 양의가 생성됩니다. 프로그램의 사용과 qmake , moc는 프로그램에 대한 호출은 프로그래머에게 투명하고, Makefile에 달려있다.
클래스가 신호와 슬롯을 구현할 수 들면, 그것은에 액세스할 필요가 메타 객체 시스템 . 그래서 클래스에서 상속해야합니다 QObject 와 하위 클래스, 그리고 매크로가 필요 Q_OBJECT 개인 정보 보호 정책 자신의 영역에 있습니다. "슬롯 [| | 보호 개인 공개]"준비 완료, 간판 섹션 및 슬롯에 섹션 '신호'에 선언됩니다.
선언 이후에 슬롯이 후, 다른 일반적인 방법으로 정의, 명시 된 것처럼 다른 방법으로 호출할 수 있습니다. 이미 징후가 좀 더 섬세하고 있으며, 오직 선포하고 프로그래머에 의해 정의됩니다. 그 이유는? 빌드하는 시도의 끝에 메시지 :
TMP / moc_mydisplay.o : signalPlay () '함수는`MyDisplay에서 : ~ / 스톱워치 / tmp를 / moc_mydisplay.cpp : 89 :`MyDisplay의 여러 정의 : signalPlay () ' TMP / mydisplay.o : ~ / 스톱워치 / mydisplay.cpp : 169 : 처음에 이곳에 정의 collect2 : 신분증 1 종료 상태를 반환 만들기 : ** [스톱워치] 오류 1
파일 내부 moc_mydisplay.cpp 다음 코드를 생성한다 :
/ / 신호 0 signalPlay ( ) 공극 MyDisplay : signalPlay () { activate ( this , & staticMetaObject , 0 , 0 ) ; QMetaObject : 활성화 (이, & staticMetaObject, 0, 0); }
예, moc는 QT의 이른바 메타 방식의 정의와 신호를 생성합니다. 따라서, QT에서 신호의 시체를 정의하는 것은 불법이며 방법을 다시 설정하여 컴파일 오류를 생성합니다. 하자 moc는 당신을위한 신호의 구현을 담당.
연결
그것은 더 좋은 단지 설정 신호와 슬롯 없습니다. 그들이 상호 작용하는 방법을 당신이 정의해야합니다. 이 작업을 수행하는 방법) (연결을 통해 연결하여 모든 후계자의 방법 존재 QObject . 이 moc는 신호를 구현할 수 있도록 그 같은 매개 변수 (S) 슬롯 (S) 연결 (S)에 대한 호출 결과를 호출합니다.
연결에 따라 신호도 다시라는 마지막 슬롯과 같은 값을 반환할 수 있습니다. 이거 정말 안전하지 않습니다 여러 슬롯에 연결된 신호 그러므로, 아무것도라는 이름의 순서를 보장하지 않습니다.
주어진 신호가 바로 두 번째 신호에 연결될 수 있습니다. 첫 번째 신호에) (방출 다음에 상응하는 그 이후, 두 번째 신호에서) (방출 두 번째로 moksha, 첫 번째 호출에서 호출 결과를 만드는 단계 이후에, 이것은 다른 방법에 연결된 전화에서 이렇게 결과 .
연결하는 방법
이 신호와 슬롯을 연결하는 세 가지 방법은 기본적으로하고 올바르게 사용하지 않을 경우 것은 발견할 수 몹시 어려운 버그의 원천이 될 수 있습니다. 연결이 양식은 연결 () 메서드에 추가 매개 변수로 전달됩니다. 그들은 다음과 같습니다
연결 직통 : 슬롯은 즉시 신호가 신호가 발행되었습니다 스레드에 발행되었습니다라고합니다. 이것은 슬롯에 직접 전화로 역할을합니다.
대기중인 연결 : 신호가 전송되고 슬롯에 대한 호출은 QT의 내부 목록에가는, 그리고 신호가 전화 또는되지 않은 관계없이 슬롯 즉시 반환됩니다. 이벤트 루프는 해당 목록을 처리하고 나중에 전용 슬롯은 객체가 슬롯을있는 스레드에서 호출됩니다.
자동 연결 : 이것은 연결의 유형을 지정하지 않을 때 사용되는 기본 유형입니다. 그것은 중 하나입니다 "악의 씨앗" , 그것은 두 개의 행동을 제시 : 신호와 슬롯은 같은 스레드에있는 경우, 직접 연결로 작동하지만, 별도로 대기중인 연결을 사용할 수 있습니다.
대기중인 연결을 차단 : 응!? 단지 세게 아니었나? 음, 읽고 그 기사의 장점 중 하나이다 : 당신이 문서를 일관성 저장! 이 연결 신호가 적법하게 실행될 때까지 스레드가 차단되어있는 신호를 제외하고 대기열에 연결하는 것과 비슷합니다. 단 매우 신중하게 사용해야합니다, 그리고 다른 스레드에서 신호와 슬롯. 오용은 교착 상태가 발생할 수 있습니다. 이 같은 것을 볼 때 당신은 알게 될 겁니다 :
사용자 @ 호스트 :. ~ / 스톱워치 $ / 스톱워치 Qt는 : BlockingQueuedConnection를 활성화하는 동안 감지 죽은 잠금 : 보낸 사람입니다 QPushButton (0x807e2d8) 수신기는 MyDisplay (0x8076ac0)입니다
의미 무엇에 대한 질문이 주소로 "물체가있는 스레드" QT arespeito 스레드를 참조하십시오.
항상 신호, 슬롯, 스레드와 타이머와 큰 돌봐. 이들은 QT의 핵심 기능은 있지만, 그 오용 찾아낼 매우 어려운 버그로 이어질 수 있습니다. 그것에 대해 모든 설명서를 참조하십시오.
아래 소스로
우리의 예제는 두 개의 클래스와 MyDisplay 스톱워치 및 일반 파일을 기본으로 구성되어 있습니다. 메인 및 단지 QApplication 객체 스톱워치를 만듭니다. 클래스는 버튼 및 LCD 디스플레이 스타일로 대화 구성된, 프로그램의 MyDisplay 영상 부분을 담당. 스톱워치 클래스는 타이머를 표시하고 구현하는 위젯을 생성합니다. 이 아키텍처는 가장 elegent하지 않습니다, 클래스 스톱워치의 MyDisplay에서 상속 더 흥미로운. 하지만 그건 거의 신호와 슬롯을 사용할 필요가 없습니다. 재미가 없잖나
우리가 외부와 통신할 수 개체를 원할 때 신호와 슬롯의 사용이 명확된다. 일반적으로, 클래스 외부 건지 모르겠어요. 그들 내에서 외부 개체에 포인터를 전달, 그것은 캡슐을 상처와 코드가 덜 일반합니다. 우리 예제에서, 신호와 슬롯을 사용하는 더 재미있는가 일반 또는 캡슐에서 길을 잃지 않고 들어, 객체 (내부 스톱워치) /에서 객체 스톱워치로 보고서 이벤트 (외부 Mydisplay)에 myDisplay입니다.
Qt 디자이너 (다른 문서에 제가 얘기를합니다)의 도움으로, 그 대화 상자, 버튼과 LCD를 만들었습니다. 이후 우리 목적에 맞게 코드를 단순화. 어떻게 myDisplay는 QDialog에서 상속, 이것은 간접적으로 신호와 슬롯 그냥 클래스 선언의 전용 섹션에서 Q_OBJECT 매크로를 추가 사용하려면 QObject에서 상속됩니다. 그 후, 다른 보조 방법 중 추가 :
공공 슬롯 : long ) ; slotDisplayValue 무효 (길이); 개인 슬롯 : slotPlay의 무효 (); slotStop의 무효 (); 신호 : signalPlay의 무효 (); signalPause의 무효 (); signalStop의 무효 (); signalReset의 무효 ();
흔적이 버튼을 클릭에 관련된 외부 이벤트에 통신합니다. 대중이 외부 타이머 진드기로부터받을 수있는 동안 이미 민간 슬롯은 사전 처리 절차를 만들 것입니다. 따라서 클래스는 외부로 정보를 전송하고 반대쪽에 뭐가 모르고, 외부에서 정보를받습니다. 좋은 오래된 인터페이스 계약.
공공 슬롯 : slotPlay의 무효 (); slotPause의 무효 (); slotStop의 무효 (); slotReset의 무효 (); 개인 슬롯 : slotTick의 무효 (); 신호 : long ) ; signalTicks 무효 (길이);
아날로그와 반대로 스톱워치 클래스는 신호 MyDisplay 클래스를 수신 슬롯을 구현하고, 대중의 슬롯에 정보를 보내는 신호를 선언합니다.
그것은 또한 카운터를 증가 (우리 친구들이 lerdinhos 비스타를 따를 수 있도록!) 매 10 밀리초를 발사한다 QTime을 구현합니다. 이 카운터는 표시 형식과 디스플레이로 전송됩니다.
타이머가 중지 수 있으며, 일시 중지하고 적절한 버튼을 클릭하여 언제든지 다시 시작.
Finalmentes
예제 자체는 많은 코드가 아니지만, 그것은 타이머 및 맞춤형 신호와 슬롯 건설의 가장 기본적인 사용을 보여줍니다. 아주 특별한주의가 그러나, 이러한 리소스의 사용을 포함 자세한 내용은 부여해야, 그들은 치명적인 함정이 될 수 있습니다.
중요 링크
신호와 슬롯
QTime
QT의 스레드
QT의 온라인 문서
댓글
- Walison
- Walison
- Blaber
- Blaber
- 로드리고
- 로드리고
- 루카스
- 루카스
- http://blabos.pip.verisignlabs.com/ 공포
- http://blabos.pip.verisignlabs.com/ 공포
- 루카스
- 루카스

