Working QSignalMapper code is clumsy to read

43 views Asked by At

I read the documentation of QSignalMapper and I've ended up with this code:

_mapperOn.setMapping(ui->btnRelayOn1, 1);
_mapperOn.setMapping(ui->btnRelayOn2, 2);
_mapperOn.setMapping(ui->btnRelayOn3, 3);
_mapperOn.setMapping(ui->btnRelayOn4, 4);
_mapperOn.setMapping(ui->btnRelayOn5, 5);
_mapperOn.setMapping(ui->btnRelayOn6, 6);
_mapperOn.setMapping(ui->btnRelayOn7, 7);
_mapperOn.setMapping(ui->btnRelayOn8, 8);
_mapperOn.setMapping(ui->btnRelayOnAll, -1);

connect(ui->btnRelayOn1, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn2, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn3, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn4, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn5, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn6, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn7, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOn8, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(ui->btnRelayOnAll, &QPushButton::clicked, &_mapperOn, static_cast<void (QSignalMapper::*)()>(&QSignalMapper::map));
connect(&_mapperOn, &QSignalMapper::mappedInt, this, &FormMonitor::setRelayOn);

In my form I have 8 QPushButtons and I mapped them to my QSignalMapper in order to connect all of them to the same slot passing an index.

It works. But I don't like the code at all! It's not much different than connect each button to its own slot... I hope I misunderstood the docs and there's a better way to avoid this clumsy code. My actual form contains several of this kind of setup.

1

There are 1 answers

0
mugiseyebrows On BEST ANSWER

When you need many widgets that work as a group you can create composite widget, encapsulate mapping in it and provide public interface (signals) as something more managable.

Or you can create buttons dynamically like in calculator qt example.

At least you can put buttons in QList and connect and map them in a loop.

QSignalMapper _mapperOn;

QList<QPushButton*> buttons = {
    ui->btnRelayOn1,
    ui->btnRelayOn2,
    ui->btnRelayOn3,
    ui->btnRelayOn4,
    ui->btnRelayOn5,
    ui->btnRelayOn6,
    ui->btnRelayOn7,
    ui->btnRelayOn8
};

for(int i=0;i<buttons.size();i++) {
    _mapperOn.setMapping(buttons[i], i);
    connect(buttons[i], &QPushButton::clicked, &_mapperOn, &QSignalMapper::map);
}
_mapperOn.setMapping(ui->btnRelayOnAll, -1);
connect(ui->btnRelayOnAll, &QPushButton::clicked, &_mapperOn, &QSignalMapper::map);

connect(&_mapperOn, &QSignalMapper::mappedInt, this, &FormMonitor::setRelayOn);