QT学习:信号与槽机制


非计算机专业大四学生自学QT的一点心得,可能有很多地方的表述不够标准或是过于口语化,烦请大家多指正。

Qt是一个跨平台的C++应用程序开发框架。广泛用于开发GUI程序,这种情况下又被称为部件工具箱。也可用于开发非GUI程序,比如控制台工具和服务器。Qt使用标准的C++和特殊的代码生成扩展以及一些宏。通过语言绑定,其他的编程语言也可以使用Qt。Qt是自由且开放源代码的软件,在GNU宽通用公共许可证条款下发布。所有版本都支持广泛的编译器,包括GCC的C++编译器和Visual Studio。

概述

信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C++ 语言,因此要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler)的 QT 工具,该工具是一个 C++ 预处理程序,它为高层次的事件处理自动生成所需要的附加代码。
得益于信号与槽机制,当GUI界面中的各种窗口小部件 (widget) 发生某一事件时(鼠标左键按下、滚轮滑动或文本输入框被输入等),由该小部件发出信号,当该信号被用户与某个槽连接起来时,会自动执行槽函数中的内容。这种机制类似于回调,但是传统的回调函数通常是一个指向某个函数的指针,使用信号与槽机制使得我们的程序更加简洁明了也更加安全。

信号

当某个widget发生某一类相关的事件时,信号被一个对象使用信号发射 (emit) 函数发射,当该信号有被开发者预先与某个槽函数连接过的情况下,立刻执行该槽函数,而后emit函数才返回;若该信号没有被连接过,emit函数立即返回。
信号由moc自动产生,只需要在头文件中进行定义,不应该在.cpp中被开发者具体实现(也就是说,开发者无需关心,为什么用户点击了一个按键后,该按键对象会发出一个按键被按下的信号)。

槽是普通的 C++ 成员函数,可以被正常调用,也可以被所连接的信号调用,槽函数的方法需要开发者在.cpp中实现。

信号与槽的关联

信号与槽通过连接 (connect) 函数相关联,通过该函数,某一对象发射发射信号时.被连接的对象的槽函数将被执行,该函数定义如下:

bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) [static]

信号与槽需要满足以下两点中的一点才能够成功被连接:

  • 信号的参数个数与类型与对应的槽函数参数的个数与类型一致。
  • 信号的参数个数多于对应的槽函数的参数个数,即对应的槽函数的参数个数可以比信号函数少,但槽函数的所有参数类型必须与信号的参数类型保持一致。

实例

编译环境

  • Windows 10
  • Qt 5.12.3

修改ui文件

如下图所示,新建一个滑动控件(horizontalSlider)与一个微调框控件(spinBox)。
在这里插入图片描述

连接信号与槽

在MainWindow的构造函数中分别连接:

  • 微调框中数值被改变的信号与设置横向滑动控件的值的槽函数
connect(ui->spinBox, SIGNAL(valueChanged(int)), ui->horizontalSlider, SLOT(setValue(int)));
  • 横向滑动控件中数值被改变的信号与设置微调框的值的槽函数
connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), ui->spinBox, SLOT(setValue(int)));

这样就能够实现如下图所示两个widget中任何一种的数值被改变,都能够随之改变另一控件的数值的效果。

在这里插入图片描述
如果开发者需要同时对用户输入的值进行处理,同样也可以使用valueChanged的信号,绑定自己定义的槽,即可同步的调用该数据,示例如下:

  1. 在.ui设计文件中加入一个lable控件
    在这里插入图片描述
  2. 在MainWindow.h的MainWindow类中加入对自定义槽函数的声明
private slots:
    void on_value_changed(int value);		//自定义槽函数
  1. 在MainWindow.cpp中加入自定义槽函数的具体实现
void MainWindow::on_value_changed(int value)
{
    ui->label->setNum(value);				//改变label控件的值
}
  1. 在MainWindow的构造函数中分别连接:
  • 微调框中数值被改变的信号与自定义槽函数
connect(ui->spinBox, SIGNAL(valueChanged(int)), this, SLOT(on_value_changed(int)));
  • 横向滑动控件中数值被改变的信号与自定义槽函数
connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_value_changed(int)));

即可实现在自定义的槽函数中调用界面中用户输入的值
在这里插入图片描述
参考资料:
QT 的信号与槽机制介绍——唐新华
QT——维基百科

发布了2 篇原创文章 · 获赞 0 · 访问量 110

猜你喜欢

转载自blog.csdn.net/weixin_41399054/article/details/104211971