Как использовать QSignalMapper для отображения целых чисел на цифры?

У меня проблемы с простым приложением в Qt. Приложение выглядит как простой калькулятор с кнопками (цифры от 0 до 9).

После нажатия кнопки приложение должно отобразить на выходе приложения соответствующее число в виде цифры и цифры (слово).

Мне нужно использовать QSignalMapper, Как я могу решить это?

Мой код до сих пор:

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

2 ответа

Решение

Посмотрите на этот вопрос три способа сопоставления одного из множества объектов значению. Использование QSignalMapper не требуется в Qt 5 и является необязательным в Qt 4.

Ниже приведен пример использования QSignalMapper в Qt4/5. Есть три момента, которые нужно иметь в виду, чтобы использовать QSignalMapper:

  1. Использовать setMapping способ добавить сопоставление между отправителем QObject экземпляр и значение (целое число, строка и т. д.).

  2. Подключите сигнал отправителя к map слот в маппере.

  3. Подключите картограф mapped(ValueType) сигнал для потребителя отображения. ValueType это тип, который вы отображаете - здесь, это было бы QString,

скриншот примера

// https://github.com/KubaO/stackrun/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();
}

QString::number(buttonID) отображает только текст в виде числа, но не печатает это число в слове. Для печати одним словом вы можете перерабатывать QString txtButtons[]:

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

(Это должно быть txtButtons[9], тоже считается 0! Но вы можете использовать QStringList лучше http://doc.qt.io/qt-4.8/qstringlist.html)

Возьмите эти слова для отображения после числа:

void Widget::keyPressed(int buttonID)
{
    qDebug() << QString::number(buttonID) + ", " + **txtButtons[buttonID]** + " was clicked";
}
Другие вопросы по тегам