새 스타일 신호 / 슬롯 연결

네, 알고 있습니다. 조수의 마지막 포스트 오히려 지루합니다. 그럼에도 불구하고 요즘 내가 작업 한 스냅 샷 고정 표시기 가 아직도 조금 보이지만 드미트리 스냅 샷 사이를 전환 할 때 상대적으로 높은 지연이 발생할라고으로 미완성 (조금을 당신은 참조). 그러나 이것은 내가 내가 정말 더 문제를 조사하기 위해 자신의 검사 결과를 기다리고, 내 나이가 노트북에 재현 할 수있는 것이 아니다.

그러나이 있다 나는 무작위로 일을 테스트입니다 때 바로 일어나는 흥미로운 뭔가. Krita의 디버그 출력에서, 나는 보았다 QObject::connect()는 괄호를 기대 말, 내가 전달되는 인수에 대해 불평. "좋아,"나는 "다음에 뭔가 문제가있을가 생각 내가 쓴 코드를 ."그리고 그것은 매우 혼란했다. 이후 나는 그 장소에서 멤버 함수 포인터를 사용하여 컴파일 타임 오류가있어 한 기억이 KisSignalAutoConnectionsStore새로운 구문을 지원하지 않았다 다음 다시 전환 SINGAL()SLOT()매크로. KisSignalAutoConnectionsStore빨리 (DIS)이 연결 그룹을 연결하는 헬퍼 클래스입니다. 하나는 사용할 수있는 addConnection()연결을 추가하는 방법, 그리고 사용 clear()하기 전에 모든 연결을 제거합니다.

음, 모든 좋은 떨어져 내가 디버그 출력으로 보았다 때까지 발견하지 않았다 괄호를 놓쳤다는 사실에서. 그래서 난에 새 구문을 추가하지 왜 드미트리에게 물었다 KisSignalAutoConnectionsStore, 그는 우리가해야했다.

어떤 새로운 구문에 대한 좋은 것은 컴파일 시간 체크를합니다. 우리는 아마도 우리의 연결이 서명에 오타가해서, 당신은 프로그램을 실행하는 경우에만 만들 수 실패하고 싶지 않아요. 즉 잡을 확실히 피곤하고 힘들다 (오늘은 무작위로 명령 줄에서 보았다 때까지 흠, 내가 문제를 통지하지 않았다, 나는 그 부주의 버그와 함께 스냅 샷 고정 표시기를 제공하는 경우가 더 악화 될 수있다).

코드에 대한 수정은 간단 보인다. 일어나는 모든이에 KisSignalAutoConnection클래스입니다. 생성자에서 연결하여 이루어진다 QObject::connect(); 소멸자의 연결이 인수의 동일한 세트를 통과시켜 제거한다 QObject::disconnect()최신 master. 서명은 그냥 KisSignalAutoConnection(const QObject *, const char *, const QObject *, const char *)같이 SIGNAL()하고 SLOT()매크로가 있지만 해당 인수 문자열에 추가 할 "1""2"각각.

그래서 우리가 가지고있는 문제는 우리가 신호 및 / 또는 슬롯을 지정하는 인수 그냥 문자열 싶지 않아합니다. 우리는 그들이 멤버 함수에 대한 포인터, 또는 어쩌면 람다되고 싶어요. QObject를 문서에 따르면, 새로운 스타일에 대한 서명이 connect()있습니다 :

1
QMetaObject :: 연결 :: QObject를 연결 ( CONST QObject를 * 송신자 PointerToMemberFunction 신호 CONST QObject를 * 컨텍스트 펑터 펑, Qt는 :: ConnectionType 타입 = Qt는 :: AutoConnection)

좋아, 그래서 우리는 알고 senderreceiver포인터해야한다 QObject들, 그리고 유형 중 하나 signal또는 functor우리는 알지 못한다. 이제 우리 만들어 보자 KisSignalAutoConnection생성자 템플릿 기능 :

1 
2
3
4
서식 <  신호 , 클래스  방법 > 
인라인 KisSignalAutoConnection ( CONST QObject를 *의 송신기 , 신호 신호 , CONST QObject를 *의 수신기 , 방법 에있어서 Qt는 : : ConnectionType 타입 = Qt는 :: AutoConnection);


이러한 매개 변수에 전달되는 때 QObject::connect(), 우리는 대한 일치 과부하가없는 말, 컴파일 타임 오류가 발생 connect().

왜?

대답은 Qt의 문서는, 진실을 단순화하지 않을 경우 숨어있다. 에 대한 진정한 정의는 connect()라인 (227)에서 발견된다 qobject.h:

1 
2
3
4
서식 < 유형 이름 FUNC1, 유형 이름 이 Func2> 
정적 인라인 QMetaObject :: 접속 연결 ( CONST가 TYPENAME QtPrivate :: FunctionPointer <FUNC1> :: 개체 * 송신자, FUNC1 신호, CONST이 유형 이름 QtPrivate :: FunctionPointer <이 Func2> :: 개체 * 수신기이 Func2 슬롯 Qt는 :: ConnectionType 타입 = Qt는 :: AutoConnection)


그리고 정의 추적 QtPrivate::FunctionPointer, 우리는 그것을 얻을 qobjectdefs_impl.h:

1 
2
3
4
5
템플릿 < 클래스  의 Obj , 유형 이름  징벌 , 유형 이름 ... 인수 > 구조체  FunctionPointer <징벌 OBJ (:: *) (인수 ...)> 
{ 형식 정의 를 Obj 개체; ... };



그리고 우리가 전달 것을보고 KisSignalAutoConnection합니다 (의 테스트 코드 ) :

1 
2
KisSignalAutoConnectionsStore의 CONN; 
conn.addConnection (test1.data (), 및의 TestClass :: sigTest1, test2.data (), 및의 TestClass :: slotTest1);

우리는 볼 수 Func1의 멤버 함수 TestClass때문에, QtPrivate::FunctionPointer<Func1>::Object단지입니다 TestClass. 그러나의 생성자는 KisSignalAutoConnection받습니다 const QObject *. 문제는 여기 즉 connect()기대하고 const TestClass *있지만, 우리는 그들을를 제공합니다 const QObject *. 기본 클래스 포인터는 암시 적으로 파생 클래스 포인터로 변환, 그래서 우리는 그 오류를 할 수 없습니다.

우리는 단지의 유형을 포함 할 필요가로 해상도는, 아주 간단 보인다 senderreceiver에 그대로 템플릿으로, 그리고 모든 것을 전달합니다 QObject::connect():

1 
2
3
서식 < 클래스  발신자 ,  신호 , 클래스  수신기 , 클래스  방법 > 
인라인 KisSignalAutoConnection ( 발신자 송신기 , 신호 신호 , 수신기 , 수신기 , 방법 에있어서 , Qt는 : : ConnectionType 타입 = Qt는 :: AutoConnection);

가능한 소리. 그러나 우리는 어떻게 네 개의 매개 변수를 저장할 수 있습니까? 그것은, 말을, 다른 기본 클래스를 만들기 위해 직관적 수 있습니다 KisSignalAutoConnectionBase(), 그리고 수 있도록 KisSignalAutoConnection템플릿 클래스를, 그래서 우리는 저장할 수 sender, receiver

그러나 잠깐,이 너무 복잡하지? 우선, 우리는 소멸자를 제외한 모든 오버라이드 기능이 없습니다. 무엇보다, 우리는 기본 클래스의 모든 가치있는 일을하지 않는 것 - 그것은 빈 클래스가 될 것입니다. 여기 상속의 사용이 추하고 쓸모가 없다.

그리고, 우리 모두의 네 개의 매개 변수를 저장하는 데 필요하지 않습니다. QObject::connect()반환 QMetaObject::Connection이후에 사용할 수있는, disconnect()그것은. 그래서 그 대신에 전달 된 매개 변수 connect(), 우리는 단지 저장 Connection개체를. 그리고는 템플릿의 일부가되지 않습니다 :

1 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
공개 : 서식 < 클래스 발신자 , 신호 , 클래스 수신기 , 클래스 방법 > 인라인 KisSignalAutoConnection ( 발신자 송신기 , 신호 신호 , 수신기 , 수신기 , 방법 에있어서 , Qt는 : : ConnectionType 타입 = Qt는 :: AutoConnection)         : m_connection는 (QObject를는 : (연결할 송신기, 신호 수신 장치에있어서, 입력))     {     } 인라인 ~ KisSignalAutoConnection ()     {









QObject를 :: 분리 (m_connection);
}

개인 :
QMetaObject :: 연결 m_connection;

테스트 코드는 위에서 언급 한, 우리는 새로운 구현이 모두 구문으로 잘 작동하는지 확인 않습니다.

그래서, 큰, krita 개발자, 우리는뿐만 아니라 자동 연결을위한 새로운 구문을 사용할 수 있습니다.

추신 : 곧 스냅 샷 고정 표시기의 내 작품에 또 다른 포스트있을 것입니다 - 그것은 거의 완성입니다!

원본 : 큰 상자  새로운 스타일 신호 / 슬롯 연결


추천

출처www.cnblogs.com/chinatrump/p/11423926.html