QSignalManager-无法将多个信号连接到一个插槽

QSignalManager - Cant connect multiple signals to one slot

本文关键字:插槽 一个 信号 QSignalManager- 连接      更新时间:2023-10-16

我有4个QLineEdits和4个QPushButtons。如果我单击QPushButton,我想在相应的QLineEdit中设置一些文本。我想使用QSignalMapper来区分每个QButton和它对应的QLineEdit,所以如果单击Button1,我想在Edit1中设置文本。

在我的主窗口的构造函数中,我执行以下操作:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    signalMapper = new QSignalMapper(this);
    // set mapping and pass QLineEdit as parameter    
    signalMapper->setMapping(ui->btn1,  ui->edit1);
    signalMapper->setMapping(ui->btn2,  ui->edit2);
    signalMapper->setMapping(ui->btn3,  ui->edit3);
    signalMapper->setMapping(ui->btn4,  ui->edit4);
    // now connect the clicked()-signal to the mapping
    connect(ui->btn1, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
    connect(ui->btn2, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
    connect(ui->btn3, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
    connect(ui->btn4, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
    // connect signalMapper to my my function
    connect(signalMapper, SIGNAL(mapped(QObject*)), this, SLOT(setFileName(QObject*)));
}

出于测试目的,我想显示我用这个插槽"链接"到每个按钮的编辑文本:

void MainWindow::setFileName(QObject* target)
{
    QLineEdit* edit = qobject_cast<QLineEdit*>(target);
    QMessageBox msgBox;
    msgBox.setText(edit->text());
    msgBox.exec();
}

但这甚至没有编译,我不理解问题:http://pastebin.com/v5sD06yJ

有人能向我解释一下我的代码出了什么问题吗?这是我的项目:https://copy.com/2kDf8Jr0v1if

提前感谢!

您的编译错误可以在带有强制转换的新connect()语法下解决。所以改变:

connect(
    ui->targetfile_btn, &QPushButton::clicked,
    signalMapper, &QSignalMapper::map
);
connect(
    ui->sourcefile_btn, &QPushButton::clicked,
    signalMapper, &QSignalMapper::map
);
connect(
    ui->multilizer4_btn, &QPushButton::clicked,
    signalMapper, &QSignalMapper::map
);
connect(
    ui->multilizer6_btn, &QPushButton::clicked,
    signalMapper, &QSignalMapper::map
);

收件人:

connect(
    ui->targetfile_btn, &QPushButton::clicked,
    signalMapper, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map)
);
connect(
    ui->sourcefile_btn, &QPushButton::clicked,
    signalMapper, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map)
);
connect(
    ui->multilizer4_btn, &QPushButton::clicked,
    signalMapper, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map)
);
connect(
    ui->multilizer6_btn, &QPushButton::clicked,
    signalMapper, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map)
);

它可能比SIGNAL()和SLOT()宏看起来有点笨拙,但值得在编译时与运行时检查正确兼容的插槽。

如果是我,我会打开C++11(当然),写一些类似auto mapSignal = static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map);的东西,然后使用mapSignal。但还有其他方法。

我会用以下方式做同样的事情:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // Establish connections.
    connect(ui->btn1, SIGNAL(clicked()), this, SLOT(setFileName()));
    connect(ui->btn2, SIGNAL(clicked()), this, SLOT(setFileName()));
    connect(ui->btn3, SIGNAL(clicked()), this, SLOT(setFileName()));
    connect(ui->btn4, SIGNAL(clicked()), this, SLOT(setFileName()));
}

void MainWindow::setFileName()
{
    QObject *btn = sender();
    if (btn == ui->btn1) {
        ui->edit1->setText("Text1);
    } else if (btn == ui->btn2) {
        ui->edit2->setText("Text2);
    } else if (btn == ui->btn3)
    [..]
}