前言
今天开始正式的学习Qt,看了网上的教程写了一个简单的小程序,记录下自己对信号槽机制的理解。
教程链接:
我学习时看的教程,很详细
基本概念
我们平时在使用软件的时候,有时会通过一些按钮来控制一个文本的字体、颜色或是大小。而在程序中,按钮和文本框是两个完全不同的组件,为了实现不同组件之间的交互,Qt提供了信号槽的机制。
信号 其实就是一个事件函数,当我们点击按钮的时候,就触发了按钮的clicked事件,这个时候按钮就会发送一个clicked()的信号来告诉接收者执行相应的操作。
槽 就是组件在接收到信号后,进行相应动作的函数。槽函数与一般的c++函数相同,唯一的区别就是槽函数可以与一个信号进行连接,当与之连接的信号发出时,会自动调用该槽函数。
可以将他们看做遥控器与电视机,只有匹配的遥控器才能对电视机进行操作,当按下遥控器的按键时,遥控器便会发出相应的信号,电视机在接收信号后调用与之对应的槽函数进行换台操作。
信号与槽的连接可以有以下几种方式:
①Signal–Slot
②Signal–Slots
③Signals–Slot
④Signal–Signal
①所对应的是最普通的连接方式,即一对一的信号传播,②是指一个信号可以与多个槽进行连接,即一个按钮按下时有多个组件同时对该信号做出反应,槽函数调用的顺序与连接语句的顺序一致,③是指多个信号可以与同一个槽进行连接,即可以通过不同的按钮来对目标组件进行相同的操作,④是指一个信号与另一个信号进行连接,即前者的信号发出时,同时发出后者的信号。
使用方法
信号槽的连接有两种方式,以下将一一介绍,首先我们要新建一个Qt Widget Application项目,为它起一个好听的名字,然后一直按下一步。
在使用型号槽时需要在头文件添加Q_Object宏(此项目中,Qt已自动添加)
方法一
Qt creator提供了可视化的UI设计,我们可以在刚刚创建好的项目目录下找到一个Forms文件夹,在这个文件夹中有一个叫mainweindow.ui的文件,点击打开就可以进行可视化的UI设计了。
我们可以在左侧的组件菜单中将一个pushButton和一个textEdit拖拽到右侧的窗体中,这样我们就创建好了两个组件。
接下来就是为两个组件之间建立连接,我们可以右击pushButton,在弹出的菜单栏中选择转到槽。此时会弹出一个窗口,这是让我们选择相应的信号,选择clicked()即可。
接下来Qt会为我们自动在MainWindow类中创建槽函数,槽函数命名格式为on_(组件名)_(信号函数名),**不要随意更改这个名字!**接下来我们就可以在这个函数中添加对textEdit的操作了,将如下代码添加至新建的槽函数中,作用是修改textEdit中的文本。
void MainWindow::on_pushButton_clicked()
{
ui->textEdit->setText("niewu");
//这里通过ui来获取组件,再调用setText函数修改文本内容
}
接下来编译运行该程序,就可以实现点击按钮,修改文本编辑器中的内容了。在这个过程中,信号和槽的连接是由Qt来完成的,信号是我们在UI设计界面中选择的,他将自动的连接到新建的槽函数,且是根据槽函数的名字进行连接的,所以上面会强调不要更改槽函数的名字。
方法二
方法一由Qt自动在信号与槽之间建立连接,使用起来十分方便,只需要编写槽函数即可,但缺点是组件较多时,会自动生成很多的槽函数,使程序变得复杂。方法二就是通过代码进行信号槽的连接,这样减少槽函数的个数。
首先,我们需要在ui文件中新添加一个groupBox组件,再在其中添加两个radioButton组件,双击radioButton组件将其命名为black和red,我们将通过这两个组件来为文本更改颜色。
我们需要在mainwindow.h头文件中手动创建相应的槽函数。
private slots:
void setTextColor();
右键函数名选择Refactor→在mainwindow.cpp中添加定义,可自动在.cpp文件中创建函数体。修改文本颜色函数如下:
void MainWindow::setTextColor() {
QPalette palette = ui->textEdit->palette();
if(ui->radioButton->isChecked()){
palette.setColor(QPalette::Text, Qt::black);
}else if(ui->radioButton_2->isChecked()){
palette.setColor(QPalette::Text, Qt::red);
}
ui->textEdit->setPalette(palette);
}
编写好槽函数之后,运行程序后点击按钮并不会对文本颜色进行修改,这是因为没有Qt帮助我们连接信号与槽,需要我们手动的进行连接。信号槽的连接函数如下:
connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
其中,sender是发送信号的组件名,signal()是信号函数,receiver是接受组件名,slot()是槽函数。如果信号函数和槽函数带有参数的话,必须写上参数类型,但可以省去参数名。对于这个例子而言,连接函数为:
connect(ui->radioButton, SIGNAL(clicked()),
ui->textEdit, SLOT(setTextColor()));
connect(ui->radioButton_2, SIGNAL(clicked()),
ui->textEdit, SLOT(setTextColor()));
只需要将上述两句代码添加到MainWindow类的构造函数中即可。(添加在ui->setupUi(this);后面)运行程序就可以通过两个按钮改变文本的颜色了!
当然,还有一种情况需要手动连接信号槽,就是当你使用纯代码设计UI界面的时候。
最后
通过这次的学习,应该可以大致的了解Qt中信号槽的机制,其实还有一种信号槽的使用是在ui设计界面按下F4,通过连线的方式来建立连接,这种方法在使用系统提供的槽函数时很方便(例如:系统提供的关闭窗口的槽函数close())但在这里我懒得写上了。