网站怎么进行优化,ppt模板下载免费版学生,免费推广的途径与原因,淘宝网站可以做轮播吗目录
自定义信号 带参数的信号和槽
信号和槽存在的意义
信号与槽的连接方式
一对一
一对多
多对一
意义
信号和槽的其他说明
信号和槽的断开
使用Lambda表达式定义槽函数
信号与槽的优缺点
优点: 松散耦合
缺点: 效率较低 自定义信号
自定义槽函数是非常关键的在开发中大部分情况都是需要自定义槽函数的。 槽函数就是用户触发某个操作之后要进行的业务逻辑 自定义信号比较少见在实际开发中很少会需要自定义信号。 信号就对应到用户的某个操作。 在GUI用户能够进行哪些操作是可以穷举的在Qt中内置的信号基本已经覆盖到了上述所有可能的用户操作。因此使用Qt内置的信号旧足以应付大部分的开发场景。 widget这个类中虽然没有定义任何信号由于继承自Qwidget和QObject这俩个类里面已经提供了一些信号可以直接使用。 所谓的Qt信号本质上就是一个”函数“。 Qt5已经更高版本中槽函数和普通的成员函数之间已经没有区别但是信号则是一类特殊的函数
只需要写出函数声明并且告诉Qt这是一个”信号“即可这个函数的定义是Qt在编译过程中自动生成的自动生成的过程程序员无法进行干预。因为信号在Qt中式特殊的机制Qt生成的信号函数的实现要配合Qt框架左很多既定的操作。作为信号函数这个函数的返回值必须式void有没有参数都可以甚至也可以支持重载。 这个signals也是Qt自己扩展出来的关键字在qmake的时候调用一些代码的分析/生成工具扫描到类中包含signals这个关键字的时候此时就会自动的把下面的函数声明认为是信号并且给这些信号函数自动的生成函数定义。 #ifndef WIDGET_H
#define WIDGET_H#include QWidgetQT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();signals:void mySignal();public slots:void handleMySignaal();private:Ui::Widget *ui;
};
#endif // WIDGET_H#include widget.h
#include ui_widget.hWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);connect(this, Widget::mySignal, this, Widget::setWindowTitle);
}Widget::~Widget()
{delete ui;
}void Widget::handleMySignaal()
{this-setWindowTitle(自定义信号);
}
建立好联系之后还需要将信号发送出去。 对于Qt内置的信号都不需要手动通过代码来触发用户在GUI进行某些操作就会自动触发对应信号发射信号的代码已经内置到Qt框架中了。 关键字emit 发射 发射信号的操作可以在任意合适的代码中。 这样就可以完成自定义信号了。
也可以通过点击按钮的方式进行对窗口的编辑。 【注意】其实在Qt5中emit什么都不会做真正进行操作的都包含在mysignal内部生成的函数定义里面所以可以舍弃emit信号也能发送出去即使如此在实际开发过程中建议把emit加上这可以让代码的可读性更高更加明显的标识出这里发射自定义的信号。 带参数的信号和槽
Qt的信号和槽也支持带有参数同时也可以支持重载。 此处要求当信号带有参数的时候槽的参数必须和信号参数一致当发射信号的时候就可以给信号函数传递实参与之对应的这个参数就会被传递到槽函数里此时就可以起到让信号给槽传参效果了。 【注意】在C中声明函数的时候形参的名字可以不用写。 信号函数和槽函数必须一致个数如果不一致也可以当个数不一致的时候要求信号参数的个数必须比槽的参数个数多。 传参可以起到复用代码代码的效果如果有多个逻辑逻辑上整体一致但是涉及到的数据不同就可以通过函数-参数来复用代码并且在不同的场景中传入不同的参数。 通过这一套信号槽搭配不同的参数就可以起到设置不同标题的效果。 在Qt的很多内置的信号也是带有参数的这些参数不是咱们自己传递的。
例如clicked信号就带有一个参数。 clicked(bool)这个参数表示当前按钮是否处于“选中”状态。这个选中状态对于QPushButton没有意义但是对于QCheckBox复选框是很有用的。 信号函数的参数个数超过了槽函数的参数个数还是可以正常使用的。 如果信号函数的参数个数少于槽函数的参数个数此时代码无法编译通过。 为什么允许信号的参数比槽的参数多呢 一个槽函数又可能会绑定多个信号。如果严格要求参数个数一致就意味着信号绑定槽的要求就变高了。换而言之当下这样的规则就允许信号和槽之间的绑定更灵活了有更多的信号可以绑定到这个槽函数上。
如果个数不一致槽函数就会按照参数顺序拿到信号的前N个参数。至少要确保槽函数的每个参数都是有值的。所以要求信号给槽的参数可以有富裕但是不能少。 【注意】带有参数的信号要求信号的参数和槽的参数一致这里的一致指的是类型一致个数满足要求信号的参数个数要对于槽的参数个数。 在Qt中如果要让某个类能够使用信号槽即可以在类中定义信号函数和槽函数则必须在类最开始的地方写下Q_OBJECT宏。 这个事情可以看作是Qt中的硬性规定这个宏能展开成很多额外的代码。 这里的宏还可以进一步展开最后展开的效果会得到一系列很复杂的代码此处就不深入研究了。 如果不加这个宏代码在编译期间就会出错。 信号和槽存在的意义
所谓的信号和槽最终要解决的问题就是响应用户的操作。
信号与槽的连接方式
一对一
主要有俩种形式分别是一个信号连接一个槽和一个信号连接一个信号 一对多
一个信号连接多个槽 多对一
多个信号连接一个槽函数 意义
一个信号可以connect多个槽函数一个槽函数也可以被多个信号connect。 Qt引入信号与槽机制最本质的目的就是为了能够让信号和槽之间按照“多对多”的方式进行关联。其他GUI框架是不具备这样的特性。但是随着程序开发的经验变多在GUI开发过程中多对多这种情况其实是”伪需求“在实际开发中很少用到绝大部分的情况一对一就够用了。
信号和槽的其他说明
信号和槽的断开
使用disconnect即可完成断开disconnect的用法和connect基本一致。 实际使用中disconnect的使用比较少大部分情况下把信号和槽连接上之后就不用等了。
主动断开的目的往往是把信号重新绑定到另一个槽函数上。
断开原来的信号槽重新绑定信号槽。
如果没有disconnect就会构成一个信号绑定俩个槽函数触发信号的时候俩个槽函数都会执行。
使用Lambda表达式定义槽函数
Qt5在Qt4的基础上提高了信号与槽的灵活性允许使用任意函数作为槽函数。但是如果想要方便的编写槽函数例如在编写函数的时候连函数名都不想定义就可以通过Lambda表达式来达到这个目的。 Lambda表达式是C11增加的特性。在C11中的Lambda表达式用于定义并创建匿名的函数对象以简化编程工作。 Lambda表达式的语法格式如下 其本质上就是一个”匿名对象“主要应用在”回调函数“场景中。 lambda表达式是一个回调函数引入了”变量捕获“语法通过变量捕获获取到外层作用域中的变量。
在[ ]可以添加下面函数中需要的参数如果想要使用外层的全部变量就需要[]。
[]这个写法的函数就是把上层作用域中的所有变量都给捕获进来。 #include widget.h
#include ui_widget.h#include QPushButtonWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui-setupUi(this);QPushButton* button new QPushButton(按钮 ,this);button-move(350, 250);connect(button, QPushButton::clicked, this, [](){this-setWindowTitle(lambda);button-setText(lambda);});
}Widget::~Widget()
{delete ui;
} 如果对应的槽函数比较简单而且是一次性使用的经常会写成lambda形式。 另外也需要确认捕获到lambda内部的变量是由意义的例如无论何时用户点击了按钮捕获到的变量都能正确使用。 信号与槽的优缺点
优点: 松散耦合
信号发送者不需要知道发出的信号被哪个对象的槽函数接收槽函数也不需要知道哪些信号关联了⾃⼰Qt的信号槽机制保证了信号与槽函数的调⽤。⽀持信号槽机制的类或者⽗类必须继承于QObject类。
缺点: 效率较低
与回调函数相⽐信号和槽稍微慢⼀些因为它们提供了更⾼的灵活性尽管在实际应⽤程序中差别不⼤。通过信号调⽤的槽函数⽐直接调⽤的速度慢约10倍这是定位信号的接收对象所需的开销遍历所有关联编组/解组传递的参数多线程时信号可能需要排队这种调⽤速度对性能要求不是⾮常⾼的场景是可以忽略的是可以满⾜绝⼤部分场景。