信号与槽是Qt的编程基础,是Qt编程的核心特性,也是Qt区别与其它C++开发框架的重要特性。
信号:是在特定情况下被发射的通知,例如QPushButton较常见的信号就是点击时发射的clicked()信号。GUI程序设计的主要工作就是对界面上各组件的信号进行响应,只需要知道什么时候发射哪些信号,合理的去响应和处理这些信号就可以了。
槽(slot)是对信号进行响应的函数。槽就是函数,所以也称为槽函数。槽函数与一般的C++函数一样,可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与信号关联,当信号被发射时,关联的槽函数被自动运行。
信号与槽关联是用函数 QObject::connect()实现的,使用函数 connect()的基本格式如下QObject::connect(sender, SIGNAL(signal()),receiver, SLOT(slot()));
connect()是 QObject 类的一个静态函数,而 QObject是大部分 Qt类的基类,在实际调用时可以忽略前面的限定符部分,所以可以直接写为:
connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
其中,sender是发射信号的对象的名称:signal0是信号,信号可以看作特殊的函数,需要带有括号,有参数时还需要指明各参数类型;receiver 是接收信号的对象的名称;slotO是槽函数,需要带有括号,有参数时还需要指明各参数类型。
SIGNAL和SLOT 是 Qt的宏,分别用于指明信号和槽函数,并将它们的参数转换为相应符串。关于信号与槽的使用,有以下一些规则需要注意。
一个信号可以连接多个槽函数,例如:
connect(spinNum,SIGNAL(valueChanged(int)), this, SLOT (addFun (int)));
connect(spinNum, SIGNAL (valuechanged(int)), this, SLOT (updateStatus (int)));
当一个信号与多个槽函数关联时,槽函数按照建立连接时的顺序依次运行。
当信号和槽函数带有参数时,在函数connect()里要指明各参数的类型。但不用指明参数名称
多个信号可以连接同一个槽函数。例如在本示例中,3个选择颜色的单选按钮的clicked()信号关联到相同的自定义槽函数 do_setFontColor()。
connect(ui->radioBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(ui->radioRed,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
connect(ui->radioBlue,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
一个信号可以连接另一个信号,例如:
connect(spinNum, SIGNAL (valuechanged(int)), this, SLOT (refreshInfo (int)));
这样发射一个信号时,也会发射另一个信号,以实现某种特殊的功能。
严格下,信号与槽的参数个数需要与类型一致,至少信号的参数不能少于槽的参数。如果参数不匹配,会出现编译错误或运行错误。
在使用信号与槽的类中,必须在类的定义中插入宏Q_OBJECT
当一个信号被发射时,与关联的槽函数通常被立即运行,就像正常调用函数一样,只有当信号关联的所有槽函数运行完毕后,才运行发射信号处后面的代码。
槽函数connect()有多种参数形式,有一种常用的形式是不用SIGNAL和SLOT宏,而是使用函数指针。在下边文章回详细介绍几种参数形式和使用方法。
Qt的界面组件都是从 QWidget继承而来的,都支持信号与槽的功能。每个类都有一些内建的信号和槽函数,例如 QPushButton类的常用信号是clicked(),在按钮被点击时此信号被发射。QDialog 是对话框类,它有以下几个公有的槽函数。
accept(),功能是关闭对话框,表示肯定的选择,如对话框上的“确定”按钮。
reject(),功能是关闭对话框,表示否定的选择,如对话框上的“取消”按钮。
eclose(),功能是关闭对话框。
这3个槽函数都可以关闭对话框,但是表示的对话框的返回值不同,。在本示例中,我们希望将“确定”按钮与对话框的 acceptO槽函数关联,将“退出”按钮与对话框的 closeO槽函数关联。可以在 Action 编辑器里设置组件的内建信号与其他组件的公有槽函数关联。
设置文字颜色的3个单选按钮是互斥选择的,即一次只有一个单选按钮被选中,虽然也可以采用 Go to slot 对话框为它们的 clicked()信号生成槽函数,但是这样就需要生成3个槽函数。我们换一种方式,即设计一个自定义槽函数,将3个单选按钮的clickedO信号都与这个自定义槽函数关联。为此,在 Dialog 类的 private slots 部分增加如下的槽函数定义。
void do_setFontColor();
将鼠标光标移动到这个函数名上面,点击鼠标右键,在弹出的快捷菜单中选择 Refactor→AddDefinition in dialog.cpp,就可以在文件 dialog.cpp 中自动生成该函数的代码框架。为该函数编写代码,具体如下。
void Dialog::do setFontColor()
{//自定义槽函数,设置文字颜色
QPalette plet=ui->plainTextEdit->palette(),
if(ui->radioBlue->isChecked())
plet.setColor(QPalette::Text,Qt::blue);
else if(ui->radioRed->isChecked())
plet.setColor(QPalette::Text,Qt::red);
else if(ui->radioBlack->isChecked())
plet.setColor(QPalette::Text,Qt::black);
else
plet,setColor(QPalette::Text,Qt::black);
ui->plainTextEdit->setPalette(plet);
}
由于这个槽函数是自定义的,因此它不会与界面上3个单选按钮的clickedO信号自动关联我们需要在 Dialog 类的构造函数中手动进行关联,代码如下:
Dialog::Dialog(QWidget *parent):Qpialog(parent),ui(new Ui::Dialog)
{
ui->setupUi(this);
connect (ui->radioBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor ()));
connect (ui->radioRed,SIGNAL(clicked()),this,SLOT(do_setFontColor ()));
connect (ui->radioBlue,SIGNAL(clicked()),this,SLOT(do_setFontColor ()));
}
构建项目之后运行,点击3个单选按钮就可以改变文字的颜色了。