QSignalMapper类的使用

QSignalMapper类可以看成是信号的翻译和转发器。
它可以把一个无参的信号翻译成带以下4种参数的信号再转发:int、QString、 QObject*以及QWidget *

 

 

 QSignalMapper类的功能核心是通过setMapping()函数建立一个从信号源Object----->到需要的数据的映射。 

QSignalMapper的接收信号槽函数是map(),它将根据setMapping规则,转发出mapped()信号给别家。

QSignalMapper可将多个有类似处理方式signal用一个slot实现,相当于将N个一对一映射通过集中转换成多对一映射。

例子:N个button,把其clicked()事件的处理放在一个处理函数里;只要事先给button编号或者给button起好名字作为参数,无需给每个button写一个slot函数。

class ButtonWidget : public QWidget
{
    Q_OBJECT

public:
    ButtonWidget(const QStringList &texts, QWidget *parent = nullptr);

signals:
    void clicked(const QString &text);

private:
    QSignalMapper *signalMapper;
};
ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent)
    : QWidget(parent)
{
    signalMapper = new QSignalMapper(this);

    QGridLayout *gridLayout = new QGridLayout;
    for (int i = 0; i < texts.size(); ++i) {
        QPushButton *button = new QPushButton(texts[i]);
        connect(button, &QPushButton::clicked, signalMapper, &QSignalMapper::map);  //设置信号转发给中继者
        signalMapper->setMapping(button, texts[i]);  //建立转发规则
        gridLayout->addWidget(button, i / 3, i % 3);
    }

    connect(signalMapper, &QSignalMapper::mappedString, this, &ButtonWidget::clicked);  //信号最终目的接收者

    setLayout(gridLayout);
}

以上相应语句也可以写成:

connect(button,SIGNAL(clicked()),signalMapper,SLOT(map()));        //设置信号转发给中继者

connect(signalMapper,SIGNAL(mapped(QString)),this,SLOT(doClicked(QString)));    //信号最终目的接收者

connect(signalMapper, SIGNAL(mapped(QString)),this, SLOT(ShowName(QString)));  //信号最终目的接收者
void Widget::ShowName(QString name) {
QMessageBox::information(this, "Name", name);
}

 另外,现在比较简便直接的方式还是使用槽函数建立关联

//获得当前窗体的所有以QAbstractButton为父类的对象
QList<QAbstractButton *> tbtns = ui->widgetTop->findChildren<QAbstractButton *>();
foreach (QAbstractButton *btn, tbtns) {
    btn->setIconSize(icoSize);
}

//也可以先如下这样进行信号槽函数关联后,在槽函数中具体区分源对象:
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonClicked()));

void formWindget::buttonClicked()
{
    QAbstractButton *b = (QAbstractButton *)sender();
    int count = btns.count();
    int index = btns.indexOf(b);
    ui->stackedWidget->setCurrentIndex(index);

    for (int i = 0; i < count; i++) {
        QAbstractButton *btn = btns.at(i);
        btn->setChecked(btn == b);
    }
}

 

posted @ 2022-04-08 20:32  云山漫卷  阅读(455)  评论(0编辑  收藏  举报