您当前的位置: 首页 >  qt

我什么都布吉岛

暂无认证

  • 5浏览

    0关注

    292博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

QT信号与槽小结

我什么都布吉岛 发布时间:2020-07-28 23:15:37 ,浏览量:5

Signal & Slot 是QT语言的核心机制,Qt提供了信号与槽机制用于完成界面操作的响应,是完成任意两个Qt对象之间通信的机制。其中,信号会在某个特定情况或动作下被触发,槽是等同与接受并处理信号的函数。[1]

一、关于信号与槽的映射关系

1 信号与槽的映射关系用集合的关系无非是上面四种,一个信号可能指向多个处理信号的槽;一个槽也可能被多个信号关联。

二、定义这种关系的接口QObject::connect

2

2.1 QObject的signal&slot “声明形式”

最常见的形式。该函数参数依次是: 信号 信号字符指针 接收者 信号字符指针,QT使用宏(SLOT(XXX) SIGNAL(XXX))的方式信号与槽(signals public slots private slots ),该宏可以将对应的信号与槽“声明”转换成适合的const char *,宏接受的参数要求:

  • 只能是信号与槽中的一种
  • “声明”是忽略void的声明
QMetaObject::Connection QObject::connect(\
const QObject *sender,   const char *signal, \
const QObject *receiver, const char *method,\
Qt::ConnectionType type = Qt::AutoConnection)

注意:

  • 必须使用SIGNALSLOT宏指定信号和方法
  • 信号与方法是不带返回值的声明
  • 信号还可连接到另一个信号
  • 机制线程安全的

一个简单的例子:

 QLabel *label = new QLabel;
 QScrollBar *scrollBar = new QScrollBar;
 QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
                  label,  SLOT(setNum(int)));
2.2 QObject间signal&slot“成员函数指针形式”

该形式将原来const char *位置的变成了信号或者槽成员函数指针。

QMetaObject::Connection connect(\
const QObject *sender,   PointerToMemberFunction signal,\
const QObject *receiver, PointerToMemberFunction method,\
Qt::ConnectionType type = Qt::AutoConnection);

关于C++成员函数地址可以由以下方法获取:&A::fun。其重载的优点在于:

  • 解除了限制。形式一要求signal和method必须是类中的信号或者槽;

缺点在于:

  • 重载时书写复杂。若signal或method若重载了,需要通过强制转换告知具体的重载方法

此外,我想提提内置控件信号与槽的命名方法,一般来说:

  • 信号名是动作的过去式(pressed),槽则是动作原型或set+状态

如我们常用的QPushButton继承了来自QAbstractButton的信号与槽:

public Q_SLOTS:
    void setIconSize(const QSize &size);
    void animateClick(int msec = 100);
    void click();
    void toggle();
    void setChecked(bool);

Q_SIGNALS:
    void pressed();
    void released();
    void clicked(bool checked = false);
    void toggled(bool checked);

如果你想自定义一个信号或者槽,你需要注意以下几点:

  • 信号与槽都没有返回值
  • 信号必须在头文件声明,且没有实现;
  • 信号与槽的参数类型必须匹配或者可隐式转换;
  • 信号可以多发信号,槽可以选择性接收(也就是信号参数大于或者等于槽的参数个数)

例子:

QObject::connect(qb1,&QPushButton::clicked,this,&MainWindow::fun);//fun是自定义的普通成员函数
QObject::connect(qb1,&QPushButton::clicked,this,&QPushButton::hide);//hide是内置的控件的slots
2.3 QObject signal 和函数对象

这种方法限制比方法二更加小,你甚至都不需要是类中的成员函数,只要求是一个函数对象。

QMetaObject::Connection 
connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)

Functor是函数对象,llambda就是其中一个,结合这个优点非常突出:

  • 更加简洁。结合lambda,可以省略对QObject槽函数的书写;
  • 更加灵活。结合lambdat替代QObject::sender();
  • 提示灵活。使用形式一,我需要查阅文档才能知道内置控制有那些信号和槽,这种形式,使用::可以直接查看拥有的信号与槽。

缺点是:

  • 重载麻烦甚至不能用

一个lambda对象例子:

QObject::connect(qb1,&QPushButton::clicked,this,[]{qDebug()            
关注
打赏
1658157489
查看更多评论
0.0564s