信号和槽机制

1. 信号和槽的概念

信号和槽是Qt框架中用于实现对象之间通信的机制。信号用来表示一个事件或状态的发生,而槽则是对这个事件或状态作出响应的函数。

在使用信号和槽时,一个对象发出信号,其他对象则可以连接到这个信号上,当信号被触发时,连接的槽函数将会被自动调用。

2.特点

1. 可以在不同的对象之间进行通信,使对象间的解耦更加灵活。
2. 一个信号可以连接多个槽函数,多个信号也可以连接到一个槽函数。
3. 信号和槽可以是不同的参数类型,可以通过信号参数和槽参数的转换进行匹配。
4. 信号和槽可以在同一个对象中定义和连接,也可以在不同的对象中进行连接。

使用信号和槽机制可以实现对象之间的相互交互和数据传递,使程序的结构更加清晰和可维护。

3. 系统自带的信号和槽

3.1 connect()函数最常用的一般形式

connect(sender, signal, receiver, slot);

3.2 参数解释

sender:发出信号的对象

signal:发送对象发出的信号  

receiver:接收信号的对象  

slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

3.3 代码展示 
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //创建一个按钮,点击按钮关闭窗口
    this->close();
    QPushButton *p = new QPushButton("关闭", this);
    //设置链接,点击按钮会产生信号,调用窗口的close函数
    connect(p, &QPushButton::clicked, this, &QWidget::close);
}

 4. 按钮常用的信号

那么系统自带的信号和槽通常如何查找呢,这个就需要利用帮助文档了,在帮助文档中比如我们上面的按钮的点击信号,在帮助文档中输入 QPushButton,首先我们可以在Contents中寻找关键字 signals,信号的意思,但是我们发现并没有找到,这时候我们应该想到也许这个信号的被父类继承下来的,因此我们去他的父类QAbstractButton中就可以找到该关键字,点击signals索引到系统自带的信号有如下几个

 这里的clicked就是我们要找到,槽函数的寻找方式和信号一样,只不过他的关键字是slot

5. 自定义槽函数 

.h头文件

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
    QPushButton *button;
public slots:
    //槽函数
    void print();
};
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    button = new QPushButton;
    button->setParent(this);
    button->setText("王者荣耀");
    //注册信号与槽的链接
    //槽函数可以是普通的成员函数,还可以是槽函数
    //如果信号没有参数,槽函数也不能有参数;如果信号有参数,槽函数可以有参数,也可以有参数
    connect(button, &QPushButton::pressed, this, &Widget::print);
}
void Widget::print()
{
    qDebug() << "王者荣耀之李白最强!";
}

6. 自定义信号

6.1 sonwidget.h 
class Sonwidget : public QWidget
{
    Q_OBJECT
public:
    explicit Sonwidget(QWidget *parent = 0);
    QPushButton *button2;
signals:
    //信号没有返回值,可以有参数
    //信号函数不需要定义,只需要声明
    void show_hide_signal(int a);
public slots:
    void emit_mysignal();
};
6.2 sonwidget.cpp
Sonwidget::Sonwidget(QWidget *parent) : QWidget(parent)
{
     this->setWindowTitle("子窗口!");
    button2 = new QPushButton("显示父窗口,隐藏子窗口!", this);
    connect(button2, &QPushButton::clicked, this, &Sonwidget::emit_mysignal);
}
void Sonwidget::emit_mysignal()
{
    //点击按钮的槽函数,发射信号
    emit show_hide_signal(100);
}
6.3 widget.h
class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    Sonwidget *sonwindow;
    QPushButton *button1;
public slots:
    void button_cb();
    void signal_cb(int a);
};
6.4 widget.cpp
Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    this->setWindowTitle("父窗口!");
    this->sonwindow = new Sonwidget;
    sonwindow ->show();
    button1 = new QPushButton;
    button1->setText("隐藏父窗口,显示子窗口!");
    button1->setParent(this);
    connect(button1, &QPushButton::clicked, this, &Widget::button_cb);
    connect(sonwindow, &Sonwidget::show_hide_signal, this, &Widget::signal_cb);
}
void Widget::button_cb()
{
    this->hide();
    this->sonwindow->show();
}

void Widget::signal_cb(int a)
{
    qDebug() << a;
    this->show();
    this->sonwindow->hide();
}

7. 自定义信号和槽的注意事项

自定义信号和槽是Qt框架中用于实现对象之间的通信的重要机制。在使用自定义信号和槽时,有一些注意事项需要注意:

1. 自定义信号和槽必须声明在QObject或其派生类中。只有继承自QObject的类才能使用信号和槽机制。

2. 自定义信号和槽的声明必须在类的头文件中进行。信号和槽的声明使用Q_SIGNALS和Q_SLOTS宏来标记。

3. 自定义信号和槽的函数原型必须与QObject类中的信号和槽原型一致。原型中的参数类型必须是QObject或其派生类的指针。

4. 自定义信号和槽可以被多次连接和断开连接。可以通过connect函数和disconnect函数来连接和断开自定义信号和槽。

5. 自定义信号和槽可以被重载。重载的信号和槽会根据参数类型的不同自动选择匹配的信号和槽。

6. 自定义信号和槽可以使用Qt元对象系统中提供的元对象宏来进行扩展和使用。例如,可以使用Q_EMIT宏来发射信号。

7. 自定义信号和槽可以在不同的线程中使用。但是在不同线程中使用信号和槽时,需要注意线程安全性。

总之,使用自定义信号和槽时需要注意信号和槽的声明、参数类型和重载等问题,以确保正确地实现对象之间的通信。

8. 信号与槽在QT4中的写法

SIGNAL和SLOT不会检查里面的字符串

这里使用了SIGNAL和SLOT这两个宏,将两个函数名转换成了字符串。注意到connect()函数的signal 和 slot 都是接受字符串,一旦出现连接不成功的情况,Qt4是没有编译错误的(因为一切都是字符串,编译期是不检查字符串是否匹配),而是在运行时给出错误。这无疑会增加程序的不稳定性。

9. Lambda表达式

C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:

[capture](parameters) mutable ->return-type

{
    statement
}

[函数对象参数] (操作符重载函数参数) mutable -> 返回值{函数体}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    button = new QPushButton("点我有奖", this);
    int a = 10;
    int b = 20;
    //槽函数可以是一个Lambda表达式
    connect(button, &QPushButton::clicked, this, [&]() mutable->int{
         a = 100;
         qDebug() << a;
         qDebug() << b;
         qDebug() << "点我有奖";
    });
}

 注意:

  1. Lambda表达式中[]中写的是 = ,代表上面的函数中的局部变量是以值传递的方式传入到Lambda表达式中
  2. Lambda表达式中[]中写的是 &,代表上面的函数中的局部变量是以引用传递的方式传入到Lambda表达式中
  3. Lambda表达式中[]中写的是 a,代表上面的函数中的局部变量是以a传递的方式传入到Lambda表达式中
  4.  Lambda表达式中[]中写的是 &a,代表上面的函数中的局部变量是以a的引用传递的方式传入到Lambda表达式中
  5. mutabl可以修饰了,作用是可以在Lambda修改传入变量的值
  6. -> 代表Lambda表达式返回值是一个int类型
  • 43
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我很乐意与您讨论信号机制开发经验!信号机制Qt框架中的一种设计模式,用于在对象之间进行通信。通过连接信号,一个对象的信号可以触发另一个对象的函数,从而实现对象之间的交互。 在开发过程中,我发现以下几点经验是很重要的: 1. 熟悉Qt信号语法:了解如何声明信号函数,并且理解它们之间的连接方式。可以使用connect函数将信号函数关联起来。 2. 注意信号的参数:确保信号函数的参数类型和数量匹配。如果参数不匹配,连接可能会失败或者导致运行时错误。 3. 使用QObject的派生类:通常情况下,信号函数需要在QObject的派生类中声明和实现。这样可以方便地使用Qt提供的宏(例如Q_OBJECT)来启用元对象系统。 4. 了解不同线程之间的信号连接:Qt提供了不同线程之间进行信号连接的机制。在跨线程通信时,需要注意使用正确的连接方式,以避免多线程问题。 5. 使用Qt信号机制替代其他通信方式:信号机制可以方便地实现对象之间的解耦合,避免紧密耦合的代码。在开发过程中,可以考虑使用信号机制替代其他通信方式,提高代码的可维护性和可扩展性。 这些是我在信号机制开发中的一些经验,希望对您有所帮助!如果您有任何更具体的问题,我将非常乐意为您解答。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值