ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Window系统下开发Qt(13)-- QSignalMapper的运用

2021-10-31 10:03:03  阅读:185  来源: 互联网

标签:13 Qt -- void QObject mapped SignalMapperWidget QSignalMapper sender


一般点击一个按钮,并且想将预先定好的参数一同发送出去时,由于按钮的点击事件clicked()并没有参数,那么按照一般的做法就会先定义一个槽与clicked()信号关联,然后获取参数,再通过自定义的信号将该参数发送出去。

  这个过程无疑是繁琐的,为此,Qt提供了QSignalMapper这个类来解决这个问题。同时,这个类可以连接多个按钮,匹配发送信号的对象对应的整数、字符串,窗口指针,继承于QObject的对象参数重新发送它们。

现在我们创建一个类似计算器的窗口,添加如下代码:

SignalMapperWidget.h

#include <QtWidgets/QWidget>

class SignalMapperWidget : public QWidget
{
	Q_OBJECT
public:
	SignalMapperWidget(QWidget* parent);
};

 SignalMapperWidget.cpp

#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QLineEdit>
#include <QtCore/QSignalMapper>
#include "SignalMapperWidget.h"

SignalMapperWidget::SignalMapperWidget(QWidget* parent)
	: QWidget(parent)
{
	QVBoxLayout* vLayout = new QVBoxLayout(this);

	//创建编辑框,用于显示点击按钮的文字,并且文字在右边显示
	QLineEdit* edit = new QLineEdit(this);
	edit->setAlignment(Qt::AlignRight);
	vLayout->addWidget(edit);

	//创建信号匹配器
	QSignalMapper* signalMapper = new QSignalMapper(this);

	QGridLayout *gridLayout = new QGridLayout;
	for (int i = 0; i < 10; ++i)
	{
		QString txt = QString::number(i);
		QPushButton *button = new QPushButton(txt);
		connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
		signalMapper->setMapping(button, txt);//将按钮和要发送的字符串配对
		gridLayout->addWidget(button, i / 3, i % 3);
	}

	//连接配对信号和设置文字槽
	connect(signalMapper, SIGNAL(mapped(QString)), edit, SLOT(setText(QString)));

	vLayout->addLayout(gridLayout);
	resize(200, 200);
}

main.cpp

#include <QtWidgets/QApplication>
#include "SignalMapperWidget.h"
int main(int argc, char* argv[])
{
	QApplication app(argc, argv);
	SignalMapperWidget widget(nullptr);
	widget.show();
	return app.exec();
}

运行效果: 

QSignalMapper源码分析

查看QSignalMapper的源码,发现定义很简单。setMapping有四个重载函数。

class Q_CORE_EXPORT QSignalMapper : public QObject
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(QSignalMapper)
public:
    explicit QSignalMapper(QObject *parent = nullptr);
    ~QSignalMapper();

    void setMapping(QObject *sender, int id);
    void setMapping(QObject *sender, const QString &text);
    void setMapping(QObject *sender, QWidget *widget);
    void setMapping(QObject *sender, QObject *object);
    void removeMappings(QObject *sender);

    QObject *mapping(int id) const;
    QObject *mapping(const QString &text) const;
    QObject *mapping(QWidget *widget) const;
    QObject *mapping(QObject *object) const;

Q_SIGNALS:
    void mapped(int);
    void mapped(const QString &);
    void mapped(QWidget *);
    void mapped(QObject *);

public Q_SLOTS:
    void map();
    void map(QObject *sender);

private:
    Q_DISABLE_COPY(QSignalMapper)
    Q_PRIVATE_SLOT(d_func(), void _q_senderDestroyed())
};

 先看其中的一个setMapping函数。往内部的hash表中添加映射关系。其他的三个重载函数的实现也一样。

void QSignalMapper::setMapping(QObject *sender, const QString &text)
{
    Q_D(QSignalMapper);
    d->stringHash.insert(sender, text);
    connect(sender, SIGNAL(destroyed()), this, SLOT(_q_senderDestroyed()));
}

再看map槽函数。当sender的信号发出时,会调用到map槽函数,然后槽函数在内部先查找是否存在这个sender,接着将信号发送出去。

void QSignalMapper::map(QObject *sender)
{
    Q_D(QSignalMapper);
    if (d->intHash.contains(sender))
        emit mapped(d->intHash.value(sender));
    if (d->stringHash.contains(sender))
        emit mapped(d->stringHash.value(sender));
    if (d->widgetHash.contains(sender))
        emit mapped(d->widgetHash.value(sender));
    if (d->objectHash.contains(sender))
        emit mapped(d->objectHash.value(sender));
}

可以看到,其实现很简单,就是一个转发的功能。

标签:13,Qt,--,void,QObject,mapped,SignalMapperWidget,QSignalMapper,sender
来源: https://blog.csdn.net/W_Y2010/article/details/121059991

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有