Qt信号与槽

目录

前言

Qt中理解信号与槽机制非常重要,在Qt中进行了一段时间的开发之后,虽然也能够简单的使用信号与槽完成任务,但是却无法把程序写好。所以,加深对信号与槽的认知非常有必要。
学习!分享!感谢!

信号与槽简单使用

参考QT 自定义函数 自定义信号和槽

自定义信号与槽注意:
1、类的声明和实现分别放在.h.cpp文件中(在头文件中用signals声明一个信号,public slots声明一个槽函数)
2、类声明中包含Q_OBJECT
3、信号只要声明不需要设计其函数实现
4、发射信号用emit关键字
5、自定义槽的实现和普通成员函数实现一样

补充:自定义信号与槽的参数列表应该相同,或者信号的参数多于槽的参数,但是注意槽的参数应该和信号的参数一一对应。
如果不对应会出现类似如下错误:

QObject::connect: Incompatible sender/receiver arguments
        Widget::sigTest(QPoint&) --> Widget::slotTest3(QRect&)

这里我定义的sigTest(QPoint&)自定义信号slotTest3(QRect&)自定义槽,因为参数不匹配,所以执行的时候对应的槽函数不会执行。


connect(sender, SIGNAL(signal), receiver, SLOT(slot));

senderreceiver是指向QObject的指针,signal信号slot是槽函数。

  • Qt5中信号与槽的使用方法
connect(sender, &Sender::signal, receiver, &Receiver::slot);
  1. 编译器检查信号与槽是否存在,参数类型检查,Q_OBJECT宏是否存在。
  2. 信号可以和槽函数、类的普通成员函数、lambda函数连接(不在局限于信号和槽函数)
  3. 参数可以是typedef或者使用不同的namespace specifier [不懂诶]
  4. 可以允许一些自动类型转换(即信号与槽函数类型不必完全匹配)
  • 参考代码
/* main.cpp
 ***********/
#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}
/* widget.h
 ***********/
 #ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include <QDebug>

class Widget : public QWidget
{
    Q_OBJECT    // all the signals and slots have to include this

public:
    Widget(QWidget *parent = 0);
    ~Widget();
signals:
    void sigTest(QPoint &Qp); // signal implementation does not require a function prototype
    void sigTest_qt5(QPoint &Qp);
private slots:
    void slotTest1();
    void slotTest2(QPoint& Qp);
//    void slotTest3(QRect& rect);
    void slotTest3();
    void slotTest4(QPoint& Qp);
private:
    QPushButton* pb;
    QLineEdit* lEdit;
    QLabel* label;
    QPoint Qp;
};

#endif // WIDGET_H
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // set widget position
    setGeometry(90, 90, 300, 200);

    // set pushButton position
    pb = new QPushButton("Modify", this);
    pb->setGeometry(10, 10, 100, 20); // x, y, w, h

    // set lineEdit text and position
    lEdit = new QLineEdit("what's your name", this);
    lEdit->setGeometry(10, 30, 200, 150);

    // set label position
    label = new QLabel("My Label", this);
    label->setGeometry(115, 10, 100, 20);

    // clicked() is Qt's signal
    // slotTest1 do not have parameter
    connect(pb, SIGNAL(clicked()), this, SLOT(slotTest1()));

    // sigTest's param is same to slotTest's param
    connect(this, SIGNAL(sigTest(QPoint&)), this, SLOT(slotTest2(QPoint&)));

//    connect(this, SIGNAL(sigTest(QPoint&)), this, SLOT(slotTest3(QRect&)));

    // sigTest's have param, but slotTest3 don't have param
    connect(this, SIGNAL(sigTest(QPoint&)), this, SLOT(slotTest3()));

    // qt5 signals and slots
    connect(this, &Widget::sigTest_qt5, this, &Widget::slotTest4);
}

Widget::~Widget()
{

}

void Widget::slotTest1()
{
    lEdit->setText("SIMON");
    label->setText("TTT");  // set label text
    Qp.setX(10);
    Qp.setY(10);
    if(label->text() != "My Label")
    {
        emit sigTest(Qp);
        emit sigTest_qt5(Qp);
    }
}

void Widget::slotTest2(QPoint& Qp)
{
    lEdit->setText("signal");   // if sigTest() is activate, lineEdit text will be changed
    qDebug() << "Qp.x()=" << Qp.x() << " Qp.y()=" << Qp.y();
}

//void Widget::slotTest3(QRect& rect)
void Widget::slotTest3()
{
    qDebug() << "slotTest3";
}

void Widget::slotTest4(QPoint& Qp)
{
    qDebug() << "Qp.x()=" << Qp.x() << " Qp.y()=" << Qp.y() << "slotTest4";
}

顺便记录下setGeometry

inline void QWidget::setGeometry(int ax, int ay, int aw, int ah)
{ setGeometry(QRect(ax, ay, aw, ah)); }

信号与槽参数不对应,会出现类似如下错误:

QObject::connect: Incompatible sender/receiver arguments
        Widget::sigTest(QPoint&) --> Widget::slotTest3(QRect&)

这里我定义的sigTest(QPoint&)自定义信号slotTest3(QRect&)自定义槽,因为参数不匹配,所以执行的时候对应的槽函数不会执行。

跨线程信号与槽的连接:

connect(m_thread, &ThreadFromQThread::progress
        , this, &Widget::progress);

其中:m_thread = new ThreadFromQThread(this);ThreadFromQThread是继承QObject的线程类,progress是线程中的自定义信号,this表示当前对象,也就是Widgetprogress是当前对象类中的信号。

  • 函数功能:
    1) Modify按钮按下之后,触发slotTest1()槽函数。然后slotTest1()槽函数会修改lEdit的值为SIMON,修改label的值为TTT。同时设置QPoint Qp的值为(10, 10),如果label的值不是My Label,就会触发sigTest(Qp)信号。
    2) 信号触发后,对应的槽函数slotTest2(QPoint&)slotTest3()执行,而slotTest3(QRect&)因为参数错误,不会执行。slotTest2(QPoint&)执行之后会设置lEdit的值为signal,同时打印Qp的值。slotTest3()会打印slotTest3

总结:

总体来说,Qt的信号与槽设计的简单好用,而且能够跨线程连接信号与槽!或许有更多的细节,比如disconnect,不过像我这种入门级别的,能够使用就好了。以后继续补充!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值