如果QPushButton
用于计算器按钮,则解决方案可能非常简单:
Qt 提供了捷径的概念。操作以及某些小部件(QPushButton
包括)已经为此做好了准备。
QPushButton::shortcut(继承自基类QAbstractButton
):
此属性保存与按钮关联的助记符
访问函数:
QKeySequence shortcut() const
void setShortcut(const QKeySequence &key)
例子:
// a button with label '0'
QPushButton qBtn0("0");
// set shortcut for key 0
qBtn0.setShortcut(QKeySequence("0"));
为了尝试这一点,我使用了我的(旧)袖珍计算器示例并添加了对快捷键的支持。
唯一的源代码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();
}
要构建的 Qt 项目文件qCalc.pro
:
SOURCES = qCalc.cc
QT = widgets
使用 Qt 5.13 在 VS2017 中构建和测试: