QSignalMapper 类,它是 Qt 提供的一个信号映射工具,核心作用是将多个来源相同、参数不同的信号,映射到同一个槽函数中,并传递自定义的标识参数(比如整数、字符串、对象指针),避免为每个信号单独写槽函数,简化代码。

在 Qt 中,如果多个控件(比如多个按钮)需要触发逻辑相似的操作,只是操作的目标 / 参数不同,直接绑定信号槽会写大量重复代码:

// 冗余写法:每个按钮写一个槽函数
connect(btn1, &QPushButton::clicked, this, &MyWidget::onBtn1Clicked);
connect(btn2, &QPushButton::clicked, this, &MyWidget::onBtn2Clicked);
connect(btn3, &QPushButton::clicked, this, &MyWidget::onBtn3Clicked);

而 QSignalMapper 可以将这些信号统一映射到一个槽函数,通过参数区分不同按钮,大幅简化代码。
2. 核心能力
绑定信号源:将多个无参数信号(如 clicked())绑定到 QSignalMapper;
设置映射参数:为每个信号源设置自定义参数(int/ QString/ QWidget
等);
统一转发信号:QSignalMapper 会将信号转发为带参数的信号(如 mapped(int)),传递预设的参数。
二、完整使用示例
下面以 “多个按钮触发同一逻辑,通过参数区分按钮” 为例,展示 QSignalMapper 的用法:
*

#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QSignalMapper>
#include <QMessageBox>

class SignalMapperDemo : public QWidget {
    Q_OBJECT
public:
    SignalMapperDemo(QWidget *parent = nullptr) : QWidget(parent) {
        // 1. 创建QSignalMapper对象
        m_signalMapper = new QSignalMapper(this);

        // 2. 创建多个按钮
        QVBoxLayout* layout = new QVBoxLayout(this);
        QPushButton* btn1 = new QPushButton("按钮1");
        QPushButton* btn2 = new QPushButton("按钮2");
        QPushButton* btn3 = new QPushButton("按钮3");
        layout->addWidget(btn1);
        layout->addWidget(btn2);
        layout->addWidget(btn3);

        // 3. 步骤1:绑定按钮的clicked信号到QSignalMapper
        connect(btn1, &QPushButton::clicked, m_signalMapper, &QSignalMapper::map);
        connect(btn2, &QPushButton::clicked, m_signalMapper, &QSignalMapper::map);
        connect(btn3, &QPushButton::clicked, m_signalMapper, &QSignalMapper::map);

        // 4. 步骤2:为每个按钮设置映射参数(支持int/ QString/ QWidget*)
        m_signalMapper->setMapping(btn1, 1);       // 按钮1 → 参数1
        m_signalMapper->setMapping(btn2, 2);       // 按钮2 → 参数2
        m_signalMapper->setMapping(btn3, "按钮3"); // 也支持字符串参数

        // 5. 步骤3:绑定QSignalMapper的转发信号到统一的槽函数
        // 针对int参数的信号
        connect(m_signalMapper, QOverload<int>::of(&QSignalMapper::mapped),
                this, &SignalMapperDemo::onButtonClicked);
        // 针对QString参数的信号(如果有)
        connect(m_signalMapper, QOverload<const QString&>::of(&QSignalMapper::mapped),
                this, &SignalMapperDemo::onButtonClickedStr);

        setWindowTitle("QSignalMapper 示例");
        resize(300, 200);
    }

private slots:
    // 处理int类型参数的槽函数
    void onButtonClicked(int btnId) {
        QMessageBox::information(this, "提示", QString("你点击了按钮%1(int参数)").arg(btnId));
    }

    // 处理QString类型参数的槽函数
    void onButtonClickedStr(const QString& btnName) {
        QMessageBox::information(this, "提示", QString("你点击了%1(字符串参数)").arg(btnName));
    }

private:
    QSignalMapper* m_signalMapper;
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    SignalMapperDemo w;
    w.show();

    return a.exec();
}

#include "main.moc" // Qt5 需手动包含,Qt6可省略

在这里插入图片描述

更多推荐