qtqsignalmapper

How to use QSignalMapper to map integers to numerals?


I have problems with a simple application in Qt. The app looks like a simple calculator wtih buttons (digits from 0 to 9).

Once a button is clicked application shall display on the application’s output the corresponding number as a digit and as a numeral (a word).

I need to use QSignalMapper. How can I solve this?

My code so far:

QLayout* Widget::createButtons()
{
    QGridLayout     *lt = new QGridLayout(this);
    QSignalMapper   *signalMapper = new QSignalMapper(this);

    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(keyPressed(int)));

    QString txtButtons[10] = {"zero", "one", "two", 
                              "three", "four", "five",
                              "six", "seven", "eight", 
                              "nine"};

    for(int i=0; i<10; i++) {

        buttons[i] = new QPushButton(txtButtons[i], this);
        signalMapper->setMapping(buttons[i], i);
        connect(buttons[i], SIGNAL(clicked()), signalMapper, SLOT(map()));
        lt->addWidget(buttons[i], i/3, i%3);
    }

    return lt;
}

void Widget::keyPressed(int buttonID)
{
    qDebug() << QString::number(buttonID) + " was clicked";
}

Solution

  • See this question for three ways of mapping one of a multitude of objects to a value. The use of QSignalMapper is not necessary in Qt 5, and is optional in Qt 4.

    Below is an example of the use of QSignalMapper in Qt4/5. There are three points to keep in mind to use QSignalMapper:

    1. Use the setMapping method to add a mapping between a sender QObject instance, and a value (integer, string, etc.).

    2. Connect the sender's signal to the map slot in the mapper.

    3. Connect the mapper's mapped(ValueType) signal to the consumer of the mapping. ValueType is the type you're mapping to - here, it'd be QString.

    screenshot of the example

    // https://github.com/KubaO/stackoverflown/tree/master/questions/button-grid-37492290
    #include <QtGui>
    #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
    #include <QtWidgets>
    #endif
    const QString numerals[] = {"zero", "one", "two", "three", "four", "five", "six", "seven",
                                "eight", "nine", "ten"};
    
    int main(int argc, char ** argv) {
       QApplication app{argc, argv};
       QWidget w;
       QGridLayout layout{&w};
       QLabel label;
       QSignalMapper mapper;
       QPushButton buttons[10];
       for (int i = 0; i < 10; ++i) {
          auto n = qMax(7-(3*(i/3))+i%3, 0); // numpad layout
          auto & button = buttons[i];
          button.setText(QString::number(n));
          mapper.setMapping(&button, QString("%1 - %2").arg(n).arg(numerals[n]));
          mapper.connect(&button, SIGNAL(clicked(bool)), SLOT(map()));
          layout.addWidget(&button, 1+i/3, i%3, 1, n > 0 ? 1 : 3);
       }
       layout.addWidget(&label, 0, 0, 1, 3);
       label.connect(&mapper, SIGNAL(mapped(QString)), SLOT(setText(QString)));
       w.show();
       return app.exec();
    }