I am trying to create a dialog that returns a double, similar to a QInputDialog, but with numeric buttons included in the dialog. It is for an embedded system with no keyboard.
The problem is that the QDoubleSpinBox never reacts to key presses/releases. The dialog itself is receiving the key events. I tried calling event->ignore() in keyPressEvent() and keyReleaseEvent(), without success. Also tried calling QApplication::processEvents(), without success.
I am using Qt 4.8 running on Linux on an embedded ARM processor.
NumericDialog.h
#ifndef NUMERICDIALOG_H
#define NUMERICDIALOG_H
#include <QDialog>
#include <QSignalMapper>
namespace Ui {
class NumericDialog;
}
class NumericDialog : public QDialog
{
Q_OBJECT
public:
explicit NumericDialog(QWidget *parent = 0);
~NumericDialog();
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void SetMax(double max);
void SetMin(double min);
void SetValue(double value);
void SetSuffix(QString suffix);
void SetTrimEnable(bool enable);
private slots:
void ButtonClicked(int key);
private:
Ui::NumericDialog *ui;
QSignalMapper _SignalMapper;
};
#endif // NUMERICDIALOG_H
NumericDialog.cpp
#include "NumericDialog.h"
#include "ui_NumericDialog.h"
#include <QKeyEvent>
#include <QDebug>
NumericDialog::NumericDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NumericDialog)
{
ui->setupUi(this);
this->setFocusPolicy(Qt::NoFocus);
ui->doubleSpinBox->setFocusPolicy(Qt::StrongFocus);
ui->doubleSpinBox->setFocus();
// Map signals, so we can use one slot for all buttons
_SignalMapper.setMapping(ui->button0, '0');
_SignalMapper.setMapping(ui->button1, '1');
_SignalMapper.setMapping(ui->button2, '2');
_SignalMapper.setMapping(ui->button3, '3');
_SignalMapper.setMapping(ui->button4, '4');
_SignalMapper.setMapping(ui->button5, '5');
_SignalMapper.setMapping(ui->button6, '6');
_SignalMapper.setMapping(ui->button7, '7');
_SignalMapper.setMapping(ui->button8, '8');
_SignalMapper.setMapping(ui->button9, '9');
_SignalMapper.setMapping(ui->buttonDot, '.');
_SignalMapper.setMapping(ui->buttonBS, Qt::Key_Backspace);
_SignalMapper.setMapping(ui->buttonEnter, Qt::Key_Enter);
_SignalMapper.setMapping(ui->buttonCancel, Qt::Key_Cancel);
_SignalMapper.setMapping(ui->buttonUp, Qt::Key_Up);
_SignalMapper.setMapping(ui->buttonDown, Qt::Key_Down);
connect(ui->button0, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button1, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button2, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button3, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button4, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button5, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button6, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button7, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button8, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->button9, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->buttonDot, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->buttonBS, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->buttonEnter, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->buttonCancel, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->buttonUp, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(ui->buttonDown, SIGNAL(clicked()), &_SignalMapper, SLOT(map()));
connect(&_SignalMapper, SIGNAL(mapped(int)),this, SLOT(ButtonClicked(int)));
}
NumericDialog::~NumericDialog()
{
delete ui;
}
void NumericDialog::keyPressEvent(QKeyEvent *event)
{
qDebug() << "Dialog got key press" << event->text();
QDialog::keyPressEvent(event);
}
void NumericDialog::keyReleaseEvent(QKeyEvent *event)
{
qDebug() << "Dialog got key release" << event->text();
QDialog::keyReleaseEvent(event);
}
void NumericDialog::SetMax(double max)
{
ui->doubleSpinBox->setMaximum(max);
ui->labelMax->setText(QString("%1").arg(max));
ui->progressBar->setMaximum(max);
}
void NumericDialog::SetMin(double min)
{
ui->doubleSpinBox->setMinimum(min);
ui->labelMin->setText(QString("%1").arg(min));
ui->progressBar->setMinimum(min);
}
void NumericDialog::SetValue(double value)
{
ui->doubleSpinBox->setValue(value);
ui->progressBar->setValue(value);
}
void NumericDialog::SetSuffix(QString suffix)
{
ui->doubleSpinBox->setSuffix(suffix);
}
void NumericDialog::ButtonClicked(int key)
{
switch(key)
{
case Qt::Key_Enter:
break;
case Qt::Key_Cancel:
break;
case Qt::Key_Up:
break;
case Qt::Key_Down:
break;
default:
QKeyEvent keyPress(QEvent::KeyPress, key, Qt::NoModifier, QString(QChar(key)));
qDebug() << keyPress.text();
QApplication::sendEvent(ui->doubleSpinBox, &keyPress);
QKeyEvent keyRelease(QEvent::KeyRelease, key, Qt::NoModifier, QString(QChar(key)));
qDebug() << keyRelease.text();
QApplication::sendEvent(ui->doubleSpinBox, &keyRelease);
//QApplication::processEvents();
break;
}
}
When I click on the number '9' button, the console output is:
"9"
"9"
Dialog got key release "9"
When I click on the Backspace button, the console output is:
" " Dialog got key press " " " " Dialog got key release " "
There are no changes to the value in the doubleSpinBox. How do I get the key events to the doubleSpinBox?
Thanks, Mary
I had to set the focusPolicy of all the buttons to NoFocus (in QtDesigner). It now behaves as expected.