QT入门学习之信号与槽

信号与槽是Qt编程的基础,信号与槽机制让界面各个组件的交互操作时变得更加直观和简单。所有从QObject或其子类(例如Qwidget)派生的类都能够包含信号和槽。当对象改动其状态时,信号就由该对象发射(emit)出去,这就是对象所要做的全部事情,他不知道另一端是谁在接收这个信号。这就是真正的信息封装,他确保对象被当作一个真正的软件组件来使用。槽用于接收信号,但他们是普通的对象成员函数。一个槽并不知道是否有所有信号和自己相连接。而且,对象并不了解具体的通信机制。你能将非常多信号和单个的槽进行连接,也能将单个的信号和非常多的槽进行连接,甚至于将一个信号和另外一个信号相连接也是可能的,这时无论第一个信号什么时候发射系统都将即时发射第二个信号。总之,信号和槽构造了一个强大的部件编程机制。

1、信号与槽定义及相关基本格式

I、定义
信号(Signal):就是在特定的情况下被发射的事件(如:PushButton最常见的信号是鼠标单击时候发射的click()信号)。当某个信号对其客户或所有者发生的内部状态发生改动,信号被一个对象发射。只有定义过这个信号的类及其派生类能够发射这个信号。当一个信号被发射时,和其相关联的槽将被即时执行,就象一个正常的函数调用相同。信号-槽机制完全独立于所有GUI事件循环。只有当所有的槽返回以后发射函数(emit)才返回。如果存在多个槽和某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行。

信号的声明是在头文件中进行的,QT的signals关键字指出进入了信号声明区,随后即可声明自己的信号。例如,下面定义了三个信号:
signals:
void mySignal();
void mySignal(int x);
void mySignalParam(int x,int y);

在上面的定义中,signals是QT的关键字,而非C/C++的。接下来的一行void mySignal() 定义了信号mySignal,这个信号没有携带参数;接下来的一行void mySignal(int x)定义了重名信号mySignal,不过他携带一个整形参数,这有点类似于C++中的虚函数。从形式上讲信号的声明和普通的C++函数是相同的,不过信号却没有函数体定义,另外,信号的返回类型都是void,不要指望能从信号返回什么有用信息。 信号由moc自动产生,他们不应该在.cpp文件中实现。

槽(Slot):就是对信号响应的函数。槽就是一个函数,与一般的C++函数一样,可以定义在类的任何部分(public\private\protected),可以具有任何参数,也可以被直接调用。槽函数与一般函数不同在于它与信号关联,当对应的信号发射,关联的槽函数就会自动执行。
public slots:在这个区内声明的槽意味着所有对象都可将信号和之相连接。这对于组件编程非常有用,你能创建彼此互不了解的对象,将他们的信号和槽进行连接以便信息能够正确的传递。
protected slots:在这个区内声明的槽意味着当前类及其子类能将信号和之相连接。这适用于那些槽,他们是类实现的一部分,不过其界面接口却面向外部。
private slots:在这个区内声明的槽意味着只有类自己能将信号和之相连接。这适用于联系非常紧密的类。
槽也能够声明为虚函数,这也是非常有用的。
槽的声明也是在头文件中进行的。例如,下面声明了三个槽:
public slots:
void mySlot();
void mySlot(int x);
void mySignalParam(int x,int y);

注1:使用信号与槽机制,类定义中必须加Q_OBJECT;
注2:signals前面不可加public、private和protected进行修饰;slots前面可以加,因为Qt说槽函数可以当普通函数使用;
注3:signals区域的函数必须是void类型,而且这些信号函数没有函数体,也就是说不可以自己定义这些信号函数,你只要声明它就够了,其它不用管,Qt内部自己弄;
注4:宏定义和函数指针不能用于信号和槽的参数信号和槽也不能有缺省参数;
注5:严格情况下,信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的数据。如果不匹配,会出现编译错误或运行错误;
注6:当与信号关联的所有槽函数执行完毕后,才会执行发射信号后面的代码。

II、基本格式
信号与槽关联用QObject类的一个静态函数QObject::connect()实现,一般格式:
QObject::connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
因为QObject是所有Qt类的基类,实际调用时可以忽略前面的限定符,格式为:
connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
其中sender是发射信号的对象的名称,signal()是信号名称,信号可以看成是特殊的函数,需要带括号,有参数时候还需要指明参数。receiver是接收信号的对象名称,slot()是槽函数的名称,需要带括号,有参数还需要指明参数。
SIGNAL和SLOT都是Qt的宏,指明信号和槽,并将它们的参数转换成字符串。

1)一个信号连接多个槽,格式如下:
connect(sender,SIGNAL(signal()),receiver,SLOT(slot1()));
connect(sender,SIGNAL(signal()),receiver,SLOT(slot2()));
……………………………………………………………………
当发射信号的对象的状态发生改变的时候,发射信号对象发射信号,接收信号对象关联的不同槽都执行。执行顺序一般按照建立连接时的顺序依次进行。
注:当信号与槽函数带参数时,在connect()函数里要写明参数的类型,但可以不写参数名称。

2)多个信号关联到同一个槽,格式如下:
connect(sender1,SIGNAL(signal()),receiver,SLOT(slot()));
connect(sender2,SIGNAL(signal()),receiver,SLOT(slot()));
……………………………………………………………………
注意:发射的信号可以是由不同发射信号对象发射出的相同类型的信号也可以是不同类型的信号。

3)一个信号关联另一个信号,格式如下:
connect(sender1,SIGNAL(signal()),receiver,SIGNAL(signal()));
当一个信号发射时另一个信号也发射。

2. 可视化生成槽函数原型和框架

创建一个Qt Widget Application项目demo3,实现更改文本编辑框文字颜色功能.在创建窗体时选择基类QDialog,生成的类命名为QWDialog,并选择生成窗体。这样生成的项目文件中就会自动生成qwdialog.ui文件、一个头qwdialog.h和一个源程序文件qwdialog.cpp,项目文件demo3.pro和主程序文件main.cpp。
项目界面已经创建完成,如.ui文件所示。接下来进行颜色按钮与相应的槽关联,更改文本编辑器文字颜色操作,具体操作如下:
在这里插入图片描述1)在窗体设计模式下,选中Blue组件,单击右键弹出快捷菜单(如上图所示)。在快捷菜单中单击菜单项“Go to slot…”,弹出如上图所示的字对话框。该对话框列出了QRadioButton类的所有信号,第一个是clicked(),第二个是clicked(bool)……。选择第二个信号clicked(bool)会将QRadioButton组件当前的选择状态作为一个参数传递,在代码里可以直接利用这个传递的参数。如果是选择第一个信号的话,则需要在代码中读取QRadioButton的选中状态。此处我们选择第二个信号。
2)选择clicked(bool),然后单击"OK"按钮,在Dialog的类定义中,会在private slots部分自动添加一个槽函数的声明,如图所示:
在这里插入图片描述
同时dialog.cpp文件中自通添加了函数on_rbtnBlue_clicked(bool checked)的槽函数的框架,在此函数中添加如下代码,实现对文本框字体颜色的控制。
在这里插入图片描述
3)通过以上操作信号和对应的槽函数关联好了,并在槽函数中实现了对文本框字体颜色的设置,最后项目运行,效果如下图所示:
在这里插入图片描述
出来上述使用可视化完成信号与槽的关联,生成槽函数框架外,还可以使用可视化设计器上的Signals和Slot编辑器进行关联设置。如下图所示:
在这里插入图片描述
这里的信号与槽函数的关联实现在ui_dialog.h文件的setupUi函数里:
QObject::connect(pushButton, SIGNAL(clicked()), Dialog, SLOT(close()));

3. 代码实现信号与槽的关联及槽函数实现

创建一个Qt Widget Application项目demo4,实现更改文本编辑框文字颜色功能.在创建窗体时选择基类QDialog,生成的类命名为QWDialog,并选择生成窗体。这样生成的项目文件中就会自动生一个头qwdialog.h和一个源程序文件qwdialog.cpp,项目文件demo4.pro和主程序文件main.cpp。
接下来使用代码实现颜色按钮与相应的槽关联,更改文本编辑器文字颜色操作,具体操作如下:
1)dialog.h文件中声明相关变量和槽函数,具体内容如下:
在这里插入图片描述
dialog.cpp文件中定义各个变量,设计UI界面,并且让信号和自定义的槽函数关联。实现更改文本编辑区的字体类型为下划线类型。代码实现和运行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cainiaoxiakexing/article/details/88656608