Qt信号与槽

来源:互联网 发布:华为p10抽奖软件 编辑:程序博客网 时间:2024/05/29 18:17

目录

  • 目录
  • 前言
  • 信号与槽简单使用
  • 总结

前言

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&)自定义槽,因为参数不匹配,所以执行的时候对应的槽函数不会执行。


  • Qt4中信号与槽的使用方法
    参考Qt之信号与槽
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 thispublic:    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,不过像我这种入门级别的,能够使用就好了。以后继续补充!

原创粉丝点击