0

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";
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
pank_94
  • 13
  • 7
  • Have you read the [documentation](http://doc.qt.io/qt-4.8/qsignalmapper.html#details)? – rbaleksandar May 27 '16 at 21:19
  • Yes, I have wrote this line of code for example: `button9 = new QPushButton(tr("9"), this); connect(button9, SIGNAL(clicked(bool)), m, SLOT(map())); m->setMapping(button0, 9);` – pank_94 May 27 '16 at 21:21
  • Please provide your code in the post and not in the comment section. The more useful information your provide (especially code snippets), the better and faster the answer will come. – rbaleksandar May 27 '16 at 21:22
  • 1
    Is that a class assignment? In Qt 5 you don't need to use the signal mapper anymore :) Even in Qt 4 you don't have to, you can assign each button a dynamic property specifying the number/word. – Kuba hasn't forgotten Monica May 27 '16 at 21:25
  • ok, my code has a little changed – pank_94 May 27 '16 at 22:07
  • Your code works fine, what is your question? – m. c. May 27 '16 at 22:34
  • Once a button is clicked application shall display on the application’s output the corresponding number as a digit and as a word. For example: 0, zero My code only display: 0 – pank_94 May 27 '16 at 22:35
  • 1
    I see, there is no existing qt way to translate number into word, the answer below has one of the possible solutions. Your SignalMapper code works. – m. c. May 27 '16 at 23:12
  • @Kuba: Please elaborate: In which way does Qt5 make QSignalMapper obsolete? How can one add a dynamic property in Qt4? – Silicomancer May 28 '16 at 20:23
  • @Silicomancer See the duplicate. – Kuba hasn't forgotten Monica May 31 '16 at 14:06

2 Answers2

0

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";
}
DYangu
  • 611
  • 1
  • 7
  • 16
  • So, shall I declare `QString txtButtons[]` as class member. – pank_94 May 28 '16 at 06:23
  • I can't initialize `QString` array :( – pank_94 May 28 '16 at 06:41
  • You better use QStringList: – DYangu May 28 '16 at 09:43
  • Yes, declare this QStringList in your .h file (but only declare, don't initialize), and initialize it as follows (replace QString array by this): QStringList txtButtons << "zero" << "one" << "two" << "three" << "four" << "five" << "six" << "seven" << "eight" << "nine"; – DYangu May 28 '16 at 10:00
  • Ok, thanks. It works.I took the words for displaying like this: `void Widget::keyPressed(int buttonID) { qDebug() << "Button clicked: " << buttons[buttonID]->text().trimmed() << " with ID " << buttonID; }` How can I declare this QStringList as a pointer like : `QStringList *txtButtons;` – pank_94 May 28 '16 at 10:14
  • This topic may help you about "QStringList as a pointer": http://stackoverflow.com/questions/19178815/using-the-operator-with-a-qstringlist-pointer – DYangu May 28 '16 at 11:23
0

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();
}
Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313