前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt自定义信号槽

Qt自定义信号槽

作者头像
zy010101
发布2020-04-08 16:54:25
1K0
发布2020-04-08 16:54:25
举报
文章被收录于专栏:程序员程序员

Qt的信号槽机制不仅可以使用系统提供的部分,也可以自定义信号槽。信号槽是Qt的核心机制,只要是继承了QObject类的子类或者间接子类都可以使用信号槽机制,无论是不是GUI程序。

下面我们来实现一个自定义的信号槽,我们将有两个类,分别是Teacher和Student。老师讲课,学生听课。

代码语言:javascript
复制
//Teacher.h
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QString str)     
    {
        this->str = str;
    }
    void send()
    {
        emit speak(str);                //发射信号
    }
signals:
    void speak(const QString & str);                //信号
private:
    QString str;                  
};

#endif // TEACHER_H
代码语言:javascript
复制
//Student.h
#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>
#include <QDebug>

class Student : public QObject
{
    Q_OBJECT
public:
    //explicit Student(QObject *parent = nullptr);
    void listen(const QString & str)
    {
       qDebug() << "老师讲的内容是:" << str;
    }
signals:
    
};

#endif // STUDENT_H
代码语言:javascript
复制
//main.cpp
#include <QCoreApplication>
#include "teacher.h"
#include "student.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    Teacher teacher("1+1=2");
    Student studet;
    
    QObject::connect(&teacher, &Teacher::speak, &studet, &Student::listen);
    teacher.send();
    
    return a.exec();
}

运行结果如下:

  1. 为了能使用信号槽机制,我们的Teacher和Student都继承自QObject。并且在类中的第一行就写上了Q_OBJECT宏。这个宏为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力。这个宏非常重要,很多操作都需要依赖这个宏。
  2. 在Teacher类中,我们在signals下写了个信号函数的声明。没错,我们仅仅只是写了个声明,并没有实现它。而Qt居然编译通过,成功运行。这是因为,Qt有一个叫做moc(Meta Object Compiler,元对象编译器)的工具,它帮助我们实现了函数体。其实Q_OBJECT也是被moc处理的,moc会处理含有Q_OBJECT的头文件。其实我们可以看到这个moc处理之后的文件。具体是这样的。如果你勾选了项目下的Shadow build(Qt Creator 4.11.0默认勾选),那么Qt Creator会生成影子文件在另外一个文件夹里,这里放着你的Debug或者Release版本的可执行文件以及moc处理过后moc_xxx.cpp文件。这些cpp文件就是将xxx.h文件处理之后的形成的。如果你不勾选Shadow build,那么就和代码放在一个文件夹下。Qt这么做保证了源代码的纯净,使用太久的VS,我喜欢不勾选这个选项。
  1. 信号函数声明必须放在signals之下,另外signals受到public,protected和private限制。如果上面代码中的是私有信号,那么我们将无法使用它。信号函数的形式被规定如下:返回值只能是void,因为无法获得信号的返回值。信号可以把想让槽函数知道的东西放在参数里。
  2. emit也是一个宏,它的功能就是发送信号。
  3. qDebug()函数是提供在控制台或者应用程序输出区进行输出的,使用它需要包含头文件QDebug.

因此,自定义信号槽需要三个步骤:

  1. 声明信号函数和定义槽函数
  2. 连接信号槽
  3. 发射信号

信号可以连接到信号,这和信号槽的连接没有本质区别;

一个信号可以连接多个槽函数,但是槽函数的执行顺序是不确定的,不建议这么做;

一个槽函数可以连接多个信号;

信号槽的连接可以被取消,使用disconnect函数。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档