QT connect学习
来源:互联网 发布:长沙黑马程序员地址 编辑:程序博客网 时间:2024/06/06 05:29
前言:信号和槽机制是 Qt 的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信。
简单的来说,信号和槽都是普通成员函数,当一个对象发出信号,由具有槽的对象接受信号进行响应。
主要方法:connect(sender,SIGNAL(signal), receiver,SLOT(slot));
这里用到了两个宏:SIGNAL() 和SLOT(),根据源码知道这两个宏最后得到const char*类型,就是将普通成员函数进行包装成为类成员函数指针。
sender和receiver则是两个QObject对象指针。
要理解connect的本质需要先弄懂函数指针。
区分不同的函数指针:
void (*FunctionPointer)(); //函数指针
void (ClassName:*MemberFunctionPointer)(); //类成员函数指针
int ClassName::* MemberPointer; //类成员变量指针
使用方法:
1.定义一个函数
int func(int x)
{
return x+1;
}
利用函数指针调用:
int(*pf)(int); //定义函数指针
pf = &func; //指针指向函数,pf=func错误
cout<<(*pf)(5)<<endl; //调用函数,等价于pf(5);
利用typedef简化函数指针:
typedef int (*pF)(int);
pF y;
y=&abc;
cout<<(*y)(1)<<endl;
2.定义一个类
class A{
public:
int x; //成员变量
void func(int); //成员函数
};
//外部函数参数为类对象和类成员变量指针
void exfunc(A obj, int A::* p){ //MemberPointer p
cout<<obj.*p<<endl; //使用成员变量
}
void exfunc2(A * obj, int A::* p){
cout<<obj->*p<<endl; //对象指针应该用->
}
template <class T>
void exfunc3(T * obj, int T::* p){
cout<<obj->*p<<endl;
}
typedef int A::* MemberPointer;
MemberPointer pV;
pV = &A::x ; //成员变量指针的定义,等价于int A::* pV;
A a;
a .* pV=1; //等价于a.x=1;
cout << &a ->* pV << endl; //等价于a.x
exfunc(a,pV); //传入一个对象a,利用对象调用成员变量指针pV
exfunc2(&a,pV); //传入一个对象a的引用,利用对象指针调用成员变量指针pV
exfunc3(&a,pV);
3.存在继承关系时使用类成员函数指针
class Person {
public:
void sayHello(){
cout<<"person sayHello ";
printf("%d\n",&Person::sayHello); //地址
}
virtual void sayName(){ //虚函数
cout<<"person sayName"<<" ";
printf("%d\n",&Person::sayName); //地址
}
};
class Child : public Person {
public:
void sayHello(){
cout<<"child sayHello"<<" ";
printf("%d\n",&Child::sayHello);
}
virtual void sayName(){
cout<<"child sayName"<<" ";
printf("%d\n",&Child::sayName);
}
};
typedef void (*FunctionPointer)();
typedef void (Person::*PersonMemberFunctionPointer)();
typedef void (Child::*ChildMemberFunctionPointer)();
Person someone;
Child xiaoming;
PersonMemberFunctionPointer pp;
pp = &Person::sayHello; //父类成员函数指针
(someone .* pp)(); //调用父类函数
//等价于 (&someone ->* pp)();
//也等价于 someone.sayHello();
(xiaoming.*pp)(); //仍然调用父类函数
//pp=&Child::sayHello;//不能运行,需要强制转换
ChildMemberFunctionPointer cp = &Child::sayHello;
(xiaoming.*cp)(); //调用子类重载函数
PersonMemberFunctionPointer pp2 = &Person::sayName;
(someone.*pp2)();
(xiaoming.*pp2)();//必须是公开继承,才有权限
//pp2 = &Child::sayName;//不能运行,需要强制转换
熟悉函数指针之后,可以理解connect的本质了。
理解信号:成员函数指针类型的特殊成员变量。
定义两个类和两类成员函数指针:
typedef void (A::*Apointer)();
typedef void (B::*Bpointer)();
class A {
public:
void (A::*click)(); //A类成员变量的成员函数指针
void onClicked(){
cout<<"A的onClick函数!"<<endl;
}
B* slotObj; //B类对象的指针
void TreatClickEvent(){
(slotObj->*(Bpointer)click)();
}
};
class B {
public:
int x=5;
void onClicked(){
cout<<"B的onClick函数! 成员变量x的值为"<<x<<endl;
}
};
void runMemberVariblePointer(A * obj, int A::* pMember) {
cout<<obj->*pMember<<endl;
}
void runfuncName(A * obj, void (A::*func)()){
//void (A::*func)()成员函数指针
(obj->*func)();
}
//组合成员变量指针和成员函数指针
void runfuncPointer(A * obj, void (A::*( A::*pfunc ))()){
//void (A::*( A::*pfunc ))(),成员变量指针的成员函数指针,
//等价于Apointer A::* pfunc
(obj->*(obj->*pfunc))();
}
//typedef void (A::*Apointer)();
//typedef void (A::*(A::*Signal))();
typedef Apointer A::* Signal;
//简化成员变量指针的成员函数指针,其实就是void (A::*( A::*pfunc ))()
//信号是成员变量指针的成员函数指针,槽是成员函数指针
//Apointer slot =void (A::*slot)()
Œ void connect(A* a, Signal signal, Apointer slot){
a->*signal = slot;
//A的成员变量指针的成员函数指针signal指向成员函数指针slot
}
void connect(A* a, Signal signal, Bpointer slot){
a->*signal = (Apointer) slot; //需要强制转换
//A的成员变量指针的成员函数指针signal指向B的成员函数指针slot
}
Ž void connect(A* a, Signal signal, B* b, Bpointer slot){
a->*signal = (Apointer) slot;
a->slotObj = b; //a的成员变量slotObj是B类型指针
}
1.连接A本身的信号与槽:
A a;
runfuncName(&a , &A::onClicked); //调用(a->*onclicked)();
//a.click = &A::onClicked
// &A::click = &(A::*click)();
//connectŒ,把A的click连接到A的onClicked
connect(&a , &A::click, &A::onClicked);
(a.*a.click)(); //调用click,发射信号
runfuncPointer(&a,&A::click); //调用click,与上相同性质
2.连接A的信号到B的槽:
B b;
B * fb = &b;
//a.click = (void (A::*)())&B::onClicked;
//connect,把A的click连接到B的onClicked
connect(&a, &A::click, &B::onClicked);
(a.*a.click)(); //调用click,发射信号
//(fb->*(Bpointer)a.click)();
(b.*(Bpointer)a.click)(); //调用click,需要强制转换
3.完善连接A的信号到B的槽:
//connectŽ,把A的click连接到B的onClicked
//A的slotObj指向fb,利用fb调用他的onClicked
connect(&a, &A::click, fb, &B::onClicked);
a.TreatClickEvent();
// (fb->*(Bpointer)click)();
将 connect(&a, &A::click, fb, &B::onClicked);
和connect(sender,SIGNAL(signal), receiver,SLOT(slot));
对比就可以知道,每个参数的意义。
QT的signal和slot简化了复杂的函数指针,更加方便的进行使用。
- QT connect学习
- QT学习--connect使用详解
- QT QObject::connect函数的学习
- QT QObject::connect函数的学习
- QT QObject::connect函数的学习
- qt-connect
- Qt connect
- Qt connect
- qt connect Qt::ConnectionType介绍
- qt connect Qt::ConnectionType介绍
- QT 之 connect
- Qt 信号槽 connect
- Qt connect不明确
- 【Qt】connect机制原理
- qt中的connect函数
- QT中的connect函数
- QT PK Connect
- Qt connect中的 Lambda
- jQuery库包含的功能
- R语言执行T检验
- Unity3D基础知识梳理
- JavaScript内置对象(基础)
- 设计模式(1)
- QT connect学习
- 线性基
- SQLite入门之sql写法(二)
- 第八届蓝桥杯省赛真题
- Unity3D 5.x怎么添加背景音乐?
- 设计模式(2)
- NOI(1.9编程基础之顺序查找-05:最大值和最小值的差)
- 自定义MVC框架
- 04-树7 二叉搜索树的操作集 (30分)