1、基本用法
比如说我有个主界面类MainWindow,该类是继承自QMainWindow。
然后,我还有一个类,是用于显示图像,叫ImageView,继承至QGraphicsView。
ImageView是MainWindow中用于显示图像的类。
这个时候,我想从ImageView中发送一个信号回到MainWindow。这个时候,就可以用emit发送了。
1)首先,在ImageVeiw的头文件里面定义一个signal函数
signals:
void testSignal(int s);
在signal函数中,一些常见的数据类型都是支持的。
2)在ImageView的cpp文件中,在对应想要发送信号的地方,写:
int mySignal = 10;
emit testSignal (mySignal);
这样,信号就发送出去了
3)在MainWindow中定义一个槽函数。
void testSlot(int s);
槽函数的参数变量要和signal函数一致,或者包含signal的变量。
然后再在cpp中,connect信号和槽函数。
则完成了信号的接收和处理。
2、自定义数据格式
如果我的数据类型不是int、float、double等这些,而是我自己定义的Struct,该怎么办,比如说
struct MyStruct
{
int a; float b; std::vector<double> c_vector;
}
Q_DECLARE_METATYPE(MyStruct);
在完成struct的定义之后,加上一个宏Q_DECLARE_METATYPE(),这个的作用是让 Qt 的元类型系统认识这个类型。
然后,就可以正常通过emit发送MyStruct类型的变量了,就可以把Mystruct当成int、float这些常见的变量使用了。
值得注意的是,在emit之前,加上:
qRegisterMetaType<MyStruct>();
emit testSignal (my_struct);
这样就可以跨线程发送信号。
3、智能指针
假如说,我们的MyStruct中有一个比较大的数据,如一个vector,这个时候如果直接emit,效率会比较低。这个时候就可以使用智能指针了。
struct MyStruct
{
int a; float b; std::vector<double> c_vector;
}
1)为什么不直接使用指针?
最大的问题就是生命周期管理的问题,什么时候将这个指针释放?如果是在槽函数中释放,那如果我的发送方还要用这个数据,就没办法用了。如果是在emit端释放,那如果是多线程的,则有可能数据释放了,但是槽函数还没处理完。总之,就是各种麻烦事。
2)为什么不使用引用?
可以,但仅限于单线程。
3)使用智能指针
智能指针会自动管理生命周期,根本就不需要操心指针的释放问题。
auto signalPtr = std::make_shared<MyStruct> (myData);
然后直接emit这个智能指针就行。

9722

被折叠的 条评论
为什么被折叠?



