qtsignals-slotsqkeyeventqkeysequenceqt-connection

How to call defined slots from keypress event in qt / How to connect keypressed event with QPushbutton on gui?


I am beginner to qt. I was working on calculator gui application, I have already defined slots like numPressed() when any of the number pushbutton is pressed on the calculator that will be displayed on the lineEdit.

void Calculator::numPressed(){
    QPushButton *button = (QPushButton *)sender();
    QString buttonValue = button->text();
    Qstring display = ui->lineEdit->text();
    Qdouble ProcessedValue = previousValue + buttonValue.toDouble();
    .
    .
    .
    ui->lineEdit->setText(QString::number(ProcessedValue));
}

connect(ui->add_button,SIGNAL(released),this,SLOT(numPressed));

Here add_button is a QPushbutton name on the UI.

What i want to achieve is?

When a number key is pressed on the key board i want to connect the number pressed and number pushbutton on the calculator which fills the lineEdit with the number that i have pressed on the keyboard?

PS: I want to connect number pressed on the keyboard to the number on the pushbutton.


Solution

  • If QPushButton is used for the calculator buttons then the solution might be very easy:

    Qt provides a concept for short cuts. Actions as well as certain widgets (QPushButton included) are already prepared for this.

    QPushButton::shortcut (inherited from base class QAbstractButton):

    This property holds the mnemonic associated with the button

    Access functions:
    QKeySequence shortcut() const
    void setShortcut(const QKeySequence &key)

    Example:

    // a button with label '0'
    QPushButton qBtn0("0");
    // set shortcut for key 0
    qBtn0.setShortcut(QKeySequence("0"));
    

    To try this out, I used my (old) pocket calculator example and added the support of shortcut keys.

    The one-and-only source code qCalc.cc:

    #include <QtWidgets>
    
    class Calculator: public QWidget {
      private:
        const char *const _error;
        int _accuSum, _accuProd;
        char _op;
        bool _clr;
        QGridLayout _qGrid;
        QLineEdit _qView;
        QPushButton _qBtnClr;
        QPushButton _qBtn7, _qBtn8, _qBtn9, _qBtnDiv;
        QPushButton _qBtn4, _qBtn5, _qBtn6, _qBtnMul;
        QPushButton _qBtn1, _qBtn2, _qBtn3, _qBtnSub;
        QPushButton _qBtnNeg, _qBtn0, _qBtnEqu, _qBtnAdd;
      public:
        explicit Calculator(QWidget *pQParent = nullptr);
        virtual ~Calculator() = default;
        Calculator(const Calculator&) = delete;;
        Calculator operator=(const Calculator&) = delete;
      private:
        void clear(bool);
        void negate(bool);
        void addDigit(char digit);
        void eval(char op); 
    };
    
    Calculator::Calculator(QWidget *pQParent):
      QWidget(pQParent),
      _error("ERROR"), _accuSum(0), _accuProd(0), _op(' '), _clr(true),
      _qBtnClr("C"),
      _qBtn7("7"), _qBtn8("8"), _qBtn9("9"), _qBtnDiv("/"),
      _qBtn4("4"), _qBtn5("5"), _qBtn6("6"), _qBtnMul("*"),
      _qBtn1("1"), _qBtn2("2"), _qBtn3("3"), _qBtnSub("-"),
      _qBtnNeg("-"), _qBtn0("0"), _qBtnEqu("="), _qBtnAdd("+")
    {
      // setup GUI
      _qView.setReadOnly(true);            
      _qGrid.addWidget(&_qView, 0, 0, 1, 3);
      _qBtnClr.setShortcut(QKeySequence("C"));
      _qGrid.addWidget(&_qBtnClr, 0, 3);
      _qBtn7.setShortcut(QKeySequence("7"));
      _qGrid.addWidget(&_qBtn7, 1, 0);
      _qBtn8.setShortcut(QKeySequence("8"));
      _qGrid.addWidget(&_qBtn8, 1, 1);
      _qBtn9.setShortcut(QKeySequence("9"));
      _qGrid.addWidget(&_qBtn9, 1, 2);
      _qBtnDiv.setShortcut(QKeySequence("/"));
      _qGrid.addWidget(&_qBtnDiv, 1, 3);
      _qBtn4.setShortcut(QKeySequence("4"));
      _qGrid.addWidget(&_qBtn4, 2, 0);
      _qBtn5.setShortcut(QKeySequence("5"));
      _qGrid.addWidget(&_qBtn5, 2, 1);
      _qBtn6.setShortcut(QKeySequence("6"));
      _qGrid.addWidget(&_qBtn6, 2, 2);
      _qBtnMul.setShortcut(QKeySequence("*"));
      _qGrid.addWidget(&_qBtnMul, 2, 3);
      _qBtn1.setShortcut(QKeySequence("1"));
      _qGrid.addWidget(&_qBtn1, 3, 0);
      _qBtn2.setShortcut(QKeySequence("2"));
      _qGrid.addWidget(&_qBtn2, 3, 1);
      _qBtn3.setShortcut(QKeySequence("3"));
      _qGrid.addWidget(&_qBtn3, 3, 2);
      _qBtnSub.setShortcut(QKeySequence("-"));
      _qGrid.addWidget(&_qBtnSub, 3, 3);
      /// @todo _qBtnNeg.setShortcut(QKeySequence("???"));
      _qGrid.addWidget(&_qBtnNeg, 4, 0);
      _qBtn0.setShortcut(QKeySequence("0"));
      _qGrid.addWidget(&_qBtn0, 4, 1);
      _qBtnEqu.setShortcut(QKeySequence(Qt::Key_Enter));
      _qGrid.addWidget(&_qBtnEqu, 4, 2);
      _qBtnAdd.setShortcut(QKeySequence("+"));
      _qGrid.addWidget(&_qBtnAdd, 4, 3);
      setLayout(&_qGrid);
      // connect signal handlers
      connect(&_qBtnClr, &QPushButton::clicked,
        this, &Calculator::clear);
      connect(&_qBtn7, &QPushButton::clicked,
        [this](bool) { addDigit('7'); });
      connect(&_qBtn8, &QPushButton::clicked,
        [this](bool) { addDigit('8'); });
      connect(&_qBtn9, &QPushButton::clicked,
        [this](bool) { addDigit('9'); });
      connect(&_qBtnDiv, &QPushButton::clicked,
        [this](bool) { eval('/'); });
      connect(&_qBtn4, &QPushButton::clicked,
        [this](bool) { addDigit('4'); });
      connect(&_qBtn5, &QPushButton::clicked,
        [this](bool) { addDigit('5'); });
      connect(&_qBtn6, &QPushButton::clicked,
        [this](bool) { addDigit('6'); });
      connect(&_qBtnMul, &QPushButton::clicked,
        [this](bool) { eval('*'); });
      connect(&_qBtn1, &QPushButton::clicked,
        [this](bool) { addDigit('1'); });
      connect(&_qBtn2, &QPushButton::clicked,
        [this](bool) { addDigit('2'); });
      connect(&_qBtn3, &QPushButton::clicked,
        [this](bool) { addDigit('3'); });
      connect(&_qBtnSub, &QPushButton::clicked,
        [this](bool) { eval('-'); });
      connect(&_qBtnNeg, &QPushButton::clicked,
        this, &Calculator::negate);
      connect(&_qBtnClr, &QPushButton::clicked,
        this, &Calculator::clear);
      connect(&_qBtn0, &QPushButton::clicked,
        [this](bool) { addDigit('0'); });
      connect(&_qBtnEqu, &QPushButton::clicked,
        [this](bool) { eval('='); });
      connect(&_qBtnAdd, &QPushButton::clicked,
        [this](bool) { eval('+'); });
      // init
      clear(false);
    }
    
    void Calculator::clear(bool)
    {
      _qView.setText("+0");
      _accuSum = _accuProd = 0; _op = ' ';
      _clr = false;
    }
    
    void Calculator::negate(bool)
    {
      QString text = _qView.text();
      if (text == _error) return;
      text[0] = text[0] == '-' ? '+' : '-'; 
      _qView.setText(text);
    }
    
    void Calculator::addDigit(char c)
    {
      QString text = _qView.text();
      if (text == _error) return;
      if (_clr) text = "+";
      else if (text == "+0" || text == "-0") text.chop(1);
      if (text.length() < 10) text += c;
      _clr = false;
      _qView.setText(text);
    }
    
    void Calculator::eval(char op)
    {
      QString text = _qView.text();
      if (text == _error) return;
      int value = text.toInt();
      switch (_op) {
        case '+':
          _accuSum += _accuProd;
          _accuProd = value;
          break;
        case '-':
          _accuSum += _accuProd;
          _accuProd = -value;
          break;
        case '*':
          _accuProd *= value;
          break;
        case '/':
          if (value == 0) {
            _qView.setText("ERROR"); return;
          }
          _accuProd /= value;
          break;
        default:
         _accuProd = value;
      }
      switch (op) {
        case '=':
        case '+': case '-':
          _accuProd += _accuSum; _accuSum = 0;
      }
      text = QString::number(_accuProd);
      if (text[0] != '-') text.insert(0, '+');
      _qView.setText(text);
      _op = op; _clr = true;
    }
    
    int main(int argc, char **argv)
    {
      qDebug() << "Qt Version:" << QT_VERSION_STR;
      QApplication app(argc, argv);
      Calculator qCalc;
      qCalc.show();
      return app.exec();
    }
    

    A Qt project file to build qCalc.pro:

    SOURCES = qCalc.cc
    
    QT = widgets
    

    Built and tested in VS2017 with Qt 5.13:

    Animated Snapshot of qCalc.exe