欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

我的QT Creator学习笔记(十七)——Qt对象模型之信号和槽机制

程序员文章站 2022-03-07 20:21:31
Qt在标准C++对象模型的基础山添加了一些特性,形成了自己的对象模型,这些特性有:...

Qt在标准C++对象模型的基础上添加了一些特性,形成了自己的对象模型,这些特性有:

1、一个强大的无缝对象通信机制----信号和槽(signals and slots)

2、可查询可设计的对象属性系统(object properties)

3、强大的事件和事件过滤器(events and event filters)

4、基于上下文的国际化字符串翻译机制(string translation for internationalization)

5、完善的定时器(timers)驱动,可以在一个事件驱动的gui中处理多个任务

6、分层结构的、可查询的对象树(Object trees),它使用一直很自然的方式来组织对象拥有权(object ownership)

7、守卫指针即QPointer,它在引用对象被销毁是自动将其设置为0;

8、动态的对象转换机制(dynamic cast);

9、支持创建自定义类型(custom type)

信号和槽机制是Qt的核心特征,用于两个对象之间的通信。当一个特殊的事件发生时便可以发送一个信号,比如按钮被单击时发送clicked()信号;而槽就是一个函数,它在信号发射后被调用来响应这个信号。Qt的部件类中已经定义了一些信号和槽,更常用的做法是子类化部件,然后添加自定义的信号和槽来实现想要的功能。

1、信号和槽的使用例子

来一个大栗子,栗子功能主界面中创建对话框,对话框可以输入数值,当单机确定按钮时关闭对话框,并将输入的数值通过信号发射处,最后主界面接收到该信号并显示数值。

新建Qt Widgets应用,项目名为mysignalslot,基类选择QWidget。项目建立后往项目中添加新文件,模板选择“Qt设计师界面类”,模板选择Dialog without Buttons,类名设置为MyDialog。完成后使用siganls关键字在mydialog.h中添加自定义信号声明,代码如下

signals:
    void dlgReturn(int);//自定义信号

signals前面不能加Public 、private等限定符,默认是Public 函数。可以从任何地方发射,但建议定义信号的类及其子类发射该信号。信号只用声明,不需要也不能对它进行定义实现。 信号没有返回值只能是void 类型。

进入mydialog.ui文件的设计模式,添加spin box 部件和一个push button部件,转到Button的单击信号对应的槽,修改代码如下,其中使用emit关键字发射信号。

void MyDialog::on_pushButton_clicked()
{
    int value=ui->spinBox->value();
    emit dlgReturn(value);//发射信号
    close();//关闭对话框
}

然后在widget.h中添加自定义槽的声明,如下

private slots:
    void showValue(int value);

槽要使用slots关键字声明,槽最大的特点是可以和信号关联,其他特性和普通c++函数一样。

进入widget.ui的设计模式,拖入label,文本改为“value:”。然后widget.cpp构造函数添加以下代码,将信号与槽关联

    MyDialog* dlg=new MyDialog(this);
    //将对话框中自定义信号与主界面中的自定义槽进行关联
    connect(dlg,SIGNAL(dlgReturn(int)),this,SLOT(showValue(int)));
    dlg->show();

添加自定义槽的实现如下

void Widget::showValue(int value)//自定义槽
{
   ui->label->setText(tr("value:%1").arg(value));
}

运行效果如下

我的QT Creator学习笔记(十七)——Qt对象模型之信号和槽机制我的QT Creator学习笔记(十七)——Qt对象模型之信号和槽机制

 

信号和槽应该注意的几点:

1、需要继承自QObject或其子类

2、在类声明的最开始处添加Q_OBJECT宏

3、槽中参数的类型要和信号参数的类型相对应,且不能比信号的参数多;

4、信号只用声明,没有定义,且返回值为void类型。

2、信号和槽的关联

信号和槽的关联使用QObject类的connect(),connect函数的讲解见我的另一篇博客认识qt 中connect函数。

3、信号和槽的自动关联

由字符串on、部件的objectName和信号名称3部分组成,中间用下划线隔开,这种形式命名的槽可以直接和信号关联,不用再使用connect函数。但是要使用调用connectSlotsByName()函数来支持信号和槽的关联(在setupUi函数中调用了该函数),并且必须使用setObjectName指定它们的objectName,才能正常使用自动关联。

代码例子:函数声明

private slots:
    void on_myButton_clicked();

在setupUi函数之前,定义部件并指定objectName代码如下

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    QPushButton* button=new QPushButton(this);//创建按钮
    button->setObjectName("myButton");//指定按钮的对象名
    ui->setupUi(this);
}

 

实现槽函数

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    QPushButton* button=new QPushButton(this);//创建按钮
    button->setObjectName("myButton");//指定按钮的对象名
    ui->setupUi(this);
}

自动关联使用不多,还是使用connect函数比较多。

4、断开关联

可以使用disconnect函数来断开信号和槽的关联,其原型如下

[static] bool QObject::disconnect(const QObject *sender, const char *signal, \
const QObject *receiver, const char *method)

从帮助文档中可以看到有以下几种使用方法

我的QT Creator学习笔记(十七)——Qt对象模型之信号和槽机制

 

最后信号和槽机制的特色和优越性:

1、类型安全的,相关联的信号和参数必须匹配

2、松耦合,信号发送者不知道也不需要知道接收者的信息

3、信号和槽可以使用任意类型的任意参数量的参数

 

 

 

 

本文地址:https://blog.csdn.net/sinat_41928334/article/details/107140612