3信号与槽

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。(这里提一句,Qt 的信号槽使用了额外的处理来实现,并不是 GoF 经典的观察者模式的实现方式。)。换句话说,信号=短信,槽函数=接受短信的手机。

一、使用内部槽函数

直接新建一个窗体程序,不需要空白。

为了体验一下信号槽的使用,我们以一段简单的代码说明:

#include <QApplication>

#include <QPushButton>

int main(int argc, char *argv[])

{

QApplication app(argc, argv);

QPushButton button("Quit");

QObject::connect(&button, &QPushButton::clicked,&app, &QApplication::quit);

button.show();

return app.exec();

}

信号与槽函数连接使用connect()函数.

原型:

QObject::connect(const QObject * sender,const char * signal, const QObject * receiver, const char * method)

参数解析:

sender:发出信号的对象

signal:发送对象发出的信号

receiver:接收信号的对象

method (slot):接收对象在接收到信号之后所需要调用的函数

注意点:

  1. 槽函数:任意的成员函数,普通全局函数,静态函数
  2. 槽函数需要和信号一致(参数,返回值)

    void  signal(int ,double,char)

        void  slot(int ,double,char)

    3. 信号和槽是没有返回值,但是可以有参数

    4.信号和槽的参数个数可以不一样

    a)     信号的参数个数可以大于槽函数参数的个数

    b)     槽函数个数不可以大于信号参数个数

    5. 信号和槽函数可以使用QT内部定义好的,也可以自定义

如果信号槽不符合,或者根本找不到这个信号或者槽函数,比如我们改成:

connect(&button, &QPushButton::clicked, &QApplication::quit2);

由于 QApplication 没有 quit2 这样的函数,因此在编译时会有编译错误:

‘quit2‘ is not a member of QApplication

这样,使用成员函数指针我们就不会担心在编写信号槽的时候出现函数错误。

前章学习了按钮控件,本次小小地运用以下。

说明:新建三个按钮控件,B1、B2和B3。点击按钮B1,按钮自动B2隐藏。点击按钮B3,窗口自动关闭。

在widget.h中,新建按钮控件对象:

#include <QPushButton>

QPushButton B1;

QPushButton *pB2;

QPushButton B3;

注意:不要在widget.cpp中创建。

原因:如果在widget.cpp中创建,那么此时B1,pB2,B3都将是局部变量,而不是全局变量。在main.cpp中可以看到  widget w;w.show();。本人是利用w的构造函数来初始化并操作。如果在构造函数中B1,pB2,B3都被释放了。那么在main.cpp中的w.show()将没有东西显示。

初始化按钮控件:

B1.setParent(this);

B1.setText("B1");

B1.move(100,100);

pB2=new QPushButton(this);

pB2->setText("B2");

pB2->move(200,100);

B3.setParent(this);

B3.setText("B3");

B3.move(300,100);

信号与槽函数的连接

connect(&B1,&QPushButton::pressed,pB2,&QPushButton::hide);

connect(&B3,&QPushButton::released,this,&QWidget::close);

解析:

信号由B1发出,发出Pressed(压下)信号,被pB2(按钮B2)接受,同时相应hide(隐藏)事件。

同理,信号由B3发出,发出released(弹起)信号,被this(窗口)接受,同时相应close(关闭)事件。

其中,信号pressed,released可以通过QpushButton来查询,即点击QpushButton按下F1,找基类,找信号。步骤如下:

光标放在QpushButton处按下F1,只有右边分栏,再按一下F1。

两次F1后,发现没有右侧没有Signal的介绍。此时找其基类,左边Inherits: QAbstractButton.点击进去。

点击Inherits: QabstractButton,可以找到Signal,再点击进去。

进去后 就可以找到有哪些信号了

二、人为定义槽函数

使用connect()可以让我们连接系统提供的信号和槽。但是,Qt 的信号槽机制并不仅仅是使用系统提供的那部分,还会允许我们自己设计自己的信号和槽。仔细看上面的注意点,信号与槽函数。

connect(&B1,&QPushButton::pressed,this,&widget::MySlot);

void MySlot()

{

B1.setText("自创B3");

B1.move(100,200);

}

说明:B1发出信号,窗口接受,如果B1被按下后,触发槽函数MySlot,将B1的内容由“B1”修改成“自创B3”。MySlot是widget类的成员函数。

自定义信号槽需要注意的事项:

1.发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);

2.使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;

3.槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;

4.使用 emit 在恰当的位置发送信号;

5.使用QObject::connect()函数连接信号和槽。

6.任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数

信号槽的更多用法:

1.一个信号可以和多个槽相连

如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。

2.多个信号可以连接到一个槽

只要任意一个信号发出,这个槽就会被调用。

3.一个信号可以连接到另外的一个信号

当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。

4.槽可以被取消链接

这种情况并不经常出现,因为当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。

5.使用Lambda 表达式

在使用 Qt 5 的时候,能够支持 Qt 5 的编译器都是支持 Lambda 表达式的。

我们的代码可以写成下面这样:

QObject::connect(&newspaper, static_cast<void (Newspaper:: *)

(const QString &)>(&Newspaper::newPaper),

[=](const QString &name)

{ /* Your code here. */ }

);

在连接信号和槽的时候,槽函数可以使用Lambda表达式的方式进行处理。

源代码:

widget.h

#ifndef WIDGET_H

#define WIDGET_H

#include <QWidget>

#include <QPushButton>

namespace Ui {

class widget;

}

class widget : public QWidget

{

Q_OBJECT

public:

explicit widget(QWidget *parent = 0);

~widget();

void MySlot()

{

B1.setText("自创B3");

B1.move(100,200);

}

private:

Ui::widget *ui;

QPushButton B1;

QPushButton *pB2;

QPushButton B3;

};

#endif // WIDGET_H

widget.cpp

#include "widget.h"

#include "ui_widget.h"

widget::widget(QWidget *parent) :

QWidget(parent),

ui(new Ui::widget)

{

ui->setupUi(this);

//按钮初始化

B1.setParent(this);

B1.setText("B1");

B1.move(100,100);

pB2=new QPushButton(this);

pB2->setText("B2");

pB2->move(200,100);

B3.setParent(this);

B3.setText("B3");

B3.move(300,100);

/*

原型:

QObject::connect(const QObject * sender,

const char * signal, const QObject * receiver, const char * method,

*/

//信号与槽函数的连接

connect(&B1,&QPushButton::pressed,pB2,&QPushButton::hide);

connect(&B3,&QPushButton::released,this,&QWidget::close);

//connect(&B1,&QPushButton::pressed,pB2,&QPushButton::close);

//上面两者等效,因为QpushButton继承Qwidget。

//connect(&B1,SIGNAL(released()),this,SIGNAL(buttonclick()));

//人为定义槽函数

/*

Qt5:任意的成员函数,普通全局函数,静态函数

槽函数需要和信号一致(参数,返回值)

由于信号都是没有返回值,所以,槽函数一定没有返回值

*/

//connect(&B1,&QPushButton::pressed,this,&widget::MySlot);

}

widget::~widget()

{

delete ui;

}

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

widget w;

w.show();

return a.exec();

}

原文地址:https://www.cnblogs.com/gd-luojialin/p/9215693.html

时间: 2024-10-12 22:58:06

3信号与槽的相关文章

【C/C++学院】(13)QT开发技术/QT 基础/QT 信号和槽

Qt是一个跨平台的c++图形用户界面用用程序框架. Qt安装说明: windows下环境变量path需要加入以下路径,以便QT写的程序可以离开QT开发环境独立运行 C:\Qt\Qt5.2.0\5.2.0\mingw48_32\bin\;C:\Qt\Qt5.2.0\Tools\mingw48_32\bin; linux下需要设置.bash_profile文件 PATH中加入/opt/Qt5.2.0/5.2.0/gcc/bin 用root用户登录系统,进入/usr/lib目录后执行 ln libGL

第78课 多线程中的信号与槽(上)

1. QThread类中的信号和槽 (1)QThread类拥有发射信号和定义槽函数的能力 (2)QThread中的关键信号 ①void started():线程开始运行时发射该信号 ②void finished():线程完成运行时发射该信号 ③void terminated():线程被异常终止时发射该信号 2. 与线程相关的概念 (1)线程栈 ①进程中存在栈空间的概念(区别于栈数据结构) ②栈空间专用于函数调用(保存函数参数.局部变量等) ③线程拥有独立的栈空间(可调用其它函数) ④只要函数体中

1.3 初步了解信号和槽

在Qt中,如何响应动作.这会用到Qt的信号和槽机制. 我的理解:它和Win32程序的消息响应机制差不多吧. 信号,简单理解就是:当我们点击一个按钮时,这个按钮自身就会产生一个叫作"单击"的信息,这个信息说明了刚刚我们点击了这一个按钮.产生的这个信息就相当于自己发射了一个信号,表明一个用户动作已经发生了或者是一个状态已经改变了.这就是信号(signal). 槽,可以理解为:当这个按钮发射了这个信号之后,假如有一个"监听员"发现了这个信号,它会马上做出响应,做相应的动作

QT学习小结之信号与槽

信号与槽函数是我们学习QT必备的基础知识,今天跟大家分享我学习QT的一些总结吧. 信号槽机制是Qt编程的基础.通过信号槽,能够使Qt各组件在不知道对方的情形下能够相互通讯. 槽函数和普通的C++成员函数没有很大的区别.它们也可以使virtual的:可以被重写:可以使public.protected或者private的:可以由其它的C++函数调用:参数可以是任何类型的.如果要说区别,那就是,槽函数可以和一个信号相连接,当这个信号发生时,它可以被自动调用. 信号与槽函数的连接我们可以用connect

QT 的信号与槽

转载: QT 的信号与槽机制介绍 QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT 库的基础之上.QT 支持下列平台:MS/WINDOWS-95.98.NT 和 2000:UNIX/X11-Linux.Sun Solaris.HP-UX.Digital Unix.IBM AIX.SGI IRIX:EMBEDDED- 支持 framebuffer

QT5中的信号与槽与C++ 11的function的配合

最近将公司的界面开发库从WX转换到了QT,有了信号和槽,原本我们在使用WX的时候,为了使用信号,我们是使用BOOST的signal2库,到了QT有了信号槽,这个就没什么必要了 但是前段时间使用QT发现QT的信号和槽没有placeholder,也就是占位符,于是信号和槽声明只能严格地一样,比如 void slot(int val); void signal( int val); 但是在signals2,我们可用利用placeholder,及时函数声明不一样,也可用进行connect void sl

Qt的信号与槽机制

1.信号和槽机制是QT的核心机制,要精通QT编程就必须对信号和槽有所了解. 2.信号和槽是一种高级接口,应用于对象之间的通信,它是QT的核心特性,也是QT区别于其它工具包的重要地方. 3.信号和槽是QT自行定义的一种通信机制,它独立于标准的C/C++语言,因此要正确的处理信号和槽,必须借助一个称为moc(Meta Object Compiler)的QT工具,该工具是一个C++预处理程序,它为高层次的事件处理自动生成所需要的附加代码. 4.在我们所熟知的很多GUI工具包中,窗口小部件(widget

在Qt Creator 和在 vs2012 里添加信号和槽

Qt  的窗口部件通过发射信号(signal)来表明一个用户的动作已经发生了或者是一个状态已经改变了. 如点击一个QPushButton时,按钮会发送一个clicked()信号,信号可以与函数(在qt里称做槽slot)相连接 可以把信号理解为c#里的事件 在vs2012里和在Qt Creator里添加信号和槽不一样,这里把两种环境下怎么添加详细说明一下 1.在vs2012里添加信号和槽 新建一个qt的项目QtDemo 在qtdeom.h里添加槽 private slots: void Btn_O

Qt信号与槽自动关联机制

参考链接1:http://blog.csdn.net/skyhawk452/article/details/6121407 参考链接2:http://blog.csdn.net/memory_exception/article/details/50953005 信号与槽可以通过使用手写代码显式的实现关联 ,也可以运用 QMetaObject 类规定的槽 函数命名范式来实现自动关联. 显示关联 class MyWidget : public QWidget { Q_OBJECT public: M

【Qt】2.2 继续了解信号和槽

槽和普通成员函数一样,可以是虚函数.被重载,可以是公有.私有.保护的.它可以被其它C++成员函数调用. 槽连接了信号,当发射这个信号时,槽会被自动调用. 连接函数: bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt::ConnectionTypetype = Qt::AutoConnection ) sende