How to use QSignalMapper to map integers to numerals?

为君一笑 提交于 2019-12-12 00:11:12

问题


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";
}

回答1:


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.

// 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();
}



回答2:


QString::number(buttonID) only displays text as a number, but it does not print that number in a word. For printting in a word you could recycle your QString txtButtons[]:

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

(It should be txtButtons[9], 0 counts too! But you could use QStringList better http://doc.qt.io/qt-4.8/qstringlist.html)

Take that words for displaying after the number:

void Widget::keyPressed(int buttonID)
{
    qDebug() << QString::number(buttonID) + ", " + **txtButtons[buttonID]** + " was clicked";
}


来源:https://stackoverflow.com/questions/37492290/how-to-use-qsignalmapper-to-map-integers-to-numerals

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!