手机网站设计企业,网页浏览器的缩写,斗破苍穹制作公司,网站设计首页框架图片一、前言 Qt成为我们今天拥有的灵活而舒适的工具#xff0c;除了友好和能够快速开发设计师界面#xff0c;信号槽机制是最大的核心特征#xff0c;也是区别于其他开发框架最大的优势。 Qt的信号槽作用于两个对象之间的通信。当一个对象发生了改变#xff0c;它希望其他关心…一、前言 Qt成为我们今天拥有的灵活而舒适的工具除了友好和能够快速开发设计师界面信号槽机制是最大的核心特征也是区别于其他开发框架最大的优势。 Qt的信号槽作用于两个对象之间的通信。当一个对象发生了改变它希望其他关心它的对象能够了解到这些变化。比如一个编辑框A的数据发生了改变而编辑框B的需要根据A的值发生数据变化这时候我们使用信号槽机制A产生数据变化信号B响应信号做自身数据做改变。 我们用来表达算法的语法会显著影响代码的可读性和可维护性。Qt的信号和槽的语法在实践中被证明是非常成功的。语法直观使用简单易于阅读。这可以帮助程序员从一开始就正确地进行设计甚至不必考虑设计模式。这满足安全和高效的图形用户界面编程Qt希望我们构建更干净、更安全、更符合UNIX精神的系统。
二、Signals and Slots 要实现对象之间的通讯方法有很多。 1初学者可能会通过定时器检测目标对象的属性变化而动作这类方法缺点很明显代码乱、耗资源、效率低、无法直接传递多个参数等等。 2资深的程序员会使用回调callback机制这是一种函数指针的用法想让别人的代码执行自己的代码。把自身需要执行的代码写在一个函数里面让目标对象去调用此函数实现对象间的通讯。但是如果多对象类都想要关心目标对象的状态变化此时需要维护一个列表以存放多个回调函数的地址(函数指针)对于每一个被关注的对象都需要做类似的工作并且对象需要动态销毁的时候还需要关注这些函数指针的回收这样的设计效率低且不灵活。 3信号槽机制类似于设计模式中的观察者模式(当一个对象状态发生改变的时候所有依赖于它的对象都得到通知并被自动更新)。被观察者发出信号Signals观察者监听信号设计槽函数Slots关联信号实现动作。 值得一提的是信号槽与回调函数的区别是面试中经常出现的问题。
信号槽优点 1松耦合性 目标对象不需要知道哪个对象关心自己发出的信号类似于广播如果有人对信号感兴趣使用connect连接信号与自身的处理槽函数即可。而回调函数需要目标对象去处理对自己感兴趣的全部对象的函数指针。耦合性明显Qt信号槽机制更优。 2类型安全 需要关联的信号槽的签名需要是相同的即参数型号、参数个数必须一致。如果不一致的话编译器会报错。 3灵活性 信号槽机制支持一个信号多个槽响应也可以一个槽响应多个信号还可以直接信号触发信号(适用于逻辑层信号夹带数据不需要处理直接转发)。 4内存安全 信号槽机制在UI编程上具备优势能够帮助程序员环节内存泄漏问题当应用程序创建了一个具有父窗口部件的对象时该对象被加入父窗口的child列表当父窗口被销毁时child列表中的对象被一一删除子类释放的顺序与构造顺序相反。
信号槽缺点 1速度较慢。 与回调函数相比信号和槽机制运行速度比直接调用非虚函数慢10倍。照官方说法是需要定位接收信号的对象、需要遍历全部关联槽、需要编组和接祖传递参数。但依旧能够满足大多数应用的需求因为1秒钟可以出发200万次这样的信号i586-500机器1个信号绑定一个槽函数绑定两个1秒可以触发120万次。
信号槽连接类型 connect连接信号槽第五个参数为连接类型通常情况下默认为Qt::AutoConnection自动设置。 类型描述Qt::AutoConnection如果信号与槽在同一个线程中则为Qt::DirectConnection直连、否则为Qt::QueuedConnection队列。Qt::DirectConnection直连发出信号的时候立刻调用槽函数Qt::QueuedConnection队列信号与槽不同线程时使用此类型Qt::BlockingQueuedConnection阻塞队列等待槽函数返回信号和槽不可在同一个线程否则死锁Qt::UniqueConnection一个标识与上述几种组合使用避免相同信号槽多次连接 信号槽使用注意事项 1默认情况下信号槽被多次连接导致触发信号的时候槽函数就会被多次调用。可以使用Qt::UniqueConnection解决此问题。 2Qt::BlockingQueuedConnection等于一个阻塞的机制子线程执行信号必须等待主线程返回才会继续往下走默认不阻塞。 3多线程中信号槽连接类型为Qt::QueuedConnection所以信号触发的时候不会马上执行槽函数存在实时性的风险。 4信号触发的速度过快而槽函数响应不过来。比如当你做一个视频播放器摄像头的数据一直在刷新但是界面上刷新不过来槽函数处理的速度比不上信号触发的速度如果这时候使用的是Qt::DirectConnection导致程序可能异常。 5 信号槽传递的参数必须是Qt的元对象系统所知道的类型因为Qt需要复制参数以将它们存储在后台的事件中否则编译会报错。如果需要使用自定义类型作为参数传递使用Q_DECLARE_METATYPE()注册它。 6所有信号的声明都是公有的所以不能在signals前面加publicprivateproteed 7信号没有返回值只需要声明不需要定义。 7自定义类必须直接或间接继承自QObject类并且开头私有声明包含Q_OBJECT才能使用信号槽机制。
信号槽连接
1传统写法-暴露参数
QLabel *label new QLabel;
QScrollBar *scrollBar new QScrollBar;
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));
//带连接类型
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)),Qt::AutoConnection);
2)进阶写法-隐藏参数
QLabel *label new QLabel;
QLineEdit *lineEdit new QLineEdit;
QObject::connect(lineEdit, QLineEdit::textChanged,label, QLabel::setText);//带连接类型
QObject::connect(lineEdit, QLineEdit::textChanged,label, QLabel::setText,Qt::AutoConnection);
3直接触发当前函数
void someFunction();
QPushButton *button new QPushButton;
QObject::connect(button, QPushButton::clicked, someFunction);
//带连接类型
QObject::connect(button, QPushButton::clicked, someFunction,
Qt::AutoConnection);
4Lambda表达式 QByteArray page ...;QTcpSocket *socket new QTcpSocket;socket-connectToHost(qt-project.org, 80);QObject::connect(socket, QTcpSocket::connected, [] () {socket-write(GET page \r\n);});//带连接类型QObject::connect(socket, QTcpSocket::connected, [] () {socket-write(GET page \r\n);}Qt::AutoConnection);
识别信号来源 当有多个对象发送信号都通过一个槽来处理的时候我们就需要在槽中识别出这些信号然后做相应的处理。 多个lineEdit编辑框当内容发送变化的时候我们统一设计一个槽函数来做处理使用sender()返回发送信号的指针。
void QMainWindows::textChaned(QString str)
{QLineEdit* edit dynamic_castQLineEdit*(sender())if (edit ui-Edit_name){//do something }else if (edit ui-Edit_number){//do something }
}