首先先看下这个程序的运行的demo,效果图如下:
在这个小程序中,有些值得注意的东西,就是包含如下:
1.文本编辑框
2.一系列的控件
在上面的控件类Button都是继承自QToolButton类,并重写了其中的sizeHint()函数,让宽度拉升
具体代码如下:
#ifndef BUTTON_H
#define BUTTON_H
#include<QToolButton>
class Button : public QToolButton
{
Q_OBJECT
public:
explicit Button(const QString &text , QWidget *parent = 0);
~Button();
QSize sizeHint() const Q_DECL_OVERRIDE;
};
#endif // BUTTON_H
#include "button.h"
#include<QtWidgets>
Button::Button(const QString& text , QWidget* parent):QToolButton(parent)
{
setSizePolicy(QSizePolicy::Expanding , QSizePolicy::Preferred);
setText(text);
}
Button::~Button()
{
}
QSize Button::sizeHint() const {
QSize size = QToolButton::sizeHint();
size.rheight() += 20;
size.rwidth() = qMax(size.width() , size.height());
return size;
}
然后就是在主窗口类中完成按钮的添加,以及窗口的布局,还有就是逻辑处理等代码了,具体如下:
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QLineEdit;
QT_END_NAMESPACE
class Button;
class Calculator : public QWidget
{
Q_OBJECT
public:
explicit Calculator(QWidget *parent = 0);
~Calculator();
signals:
private slots:
//数字点击
void digitClicked();
//一元操作点击
void unaryOperatorClicked();
//加法操作
void additiveOperatorClicked();
//乘法操作
void multiplicativeOperatorClicked();
//
void equalClicked();
void pointClicked();
void changeSignClicked();
void backspaceClicked();
void clear();
void clearAll();
void clearMemory();
void readMemory();
void setMemory();
void addToMemory();
private:
Button* createButton(const QString& text ,const char* memory );
void abortOperation();
bool calculate(double rightOperand , const QString &pendingOperator);
double sumInMemory;
double sumSoFar;
double factorSoFar;
QString pendingAdditiveOperator;
QString pendingMultiplicatibeOperator;
bool waitingForOperand;
QLineEdit *display;
enum {
NumDigitButtons = 10
};
Button* digitButtons[NumDigitButtons];
};
#endif // CALCULATOR_H
#include "calculator.h"
#include<QtWidgets>
#include<math.h>
#include"button.h"
Calculator::Calculator(QWidget *parent) : QWidget(parent)
{
//变量的初始化
sumInMemory = 0.0;
sumSoFar = 0.0;
factorSoFar = 0.0;
waitingForOperand = true;
//控件的创建
//编辑框显示控件的创建
display = new QLineEdit("0");
display->setReadOnly(true);
display->setAlignment(Qt::AlignRight);
display->setMaxLength(15);
//设置编辑框的字体
QFont font = display->font();
font.setPointSize(font.pointSize() + 8);
display->setFont(font);
//创建1-9的数字按钮,并关联信号
for(int i = 0 ; i < NumDigitButtons ; ++i){
digitButtons[i] = createButton(QString::number(i) , SLOT(digitClicked()));
}
//创建 .按钮
Button* pointButton = createButton(tr(".") , SLOT(pointClicked()));
//创建改变符号按钮
Button* changeSignButton = createButton(tr("\302\261"), SLOT(changeSignClicked()));
//创建后退按钮
Button * backspaceButton = createButton(tr("back Space") , SLOT(backspaceClicked()));
//创建清空按钮
Button *clearButton = createButton(tr("Clear"), SLOT(clear()));
//创建清空所有按钮
Button *clearAllButton = createButton(tr("Clear All") , SLOT(clearAll()));
//创建清除内存按钮
Button* clearMemoryButton = createButton(tr("MC") , SLOT(clearMemory()));
//创建读内存按钮
Button* readMemoryButton = createButton(tr("MR") , SLOT(readMemory()));
//创建设置内存按钮
Button* setMemoryButton = createButton(tr("MS"), SLOT(setMemory()));
//添加到内存按钮
Button* addToMemoryButton = createButton(tr("M+") , SLOT(addToMemory()));
//创建4则运算按钮
Button * divisionButton = createButton(tr("\303\267") , SLOT(multiplicativeOperatorClicked()));
Button * timesButton = createButton(tr("x\303\227") , SLOT(multiplicativeOperatorClicked()));
Button * minusButton = createButton(tr("-"), SLOT(additiveOperatorClicked()));
Button * plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
Button *squareRootButton = createButton(tr("Sqrt") , SLOT(unaryOperatorClicked()));
Button *powerButton = createButton(tr("x\302\262") , SLOT(unaryOperatorClicked()));
Button *reciprocalButton = createButton(tr("1/x") , SLOT(unaryOperatorClicked()));
Button *equalButton = createButton(tr("=") , SLOT(equalClicked()));
//窗口布局
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
mainLayout->addWidget(display , 0,0 ,1 ,6);
mainLayout->addWidget(backspaceButton , 1 , 0 , 1 , 2);
mainLayout->addWidget(clearButton , 1 , 2 , 1 , 2);
mainLayout->addWidget(clearAllButton , 1 , 4 , 1 , 2);
mainLayout->addWidget(clearMemoryButton , 2, 0);
mainLayout->addWidget(readMemoryButton , 3, 0);
mainLayout->addWidget(setMemoryButton , 4, 0);
mainLayout->addWidget(addToMemoryButton , 5, 0);
for(int i = 0 ; i <NumDigitButtons; ++i){
int row = ((9 - i )/3) + 2;
int column = ((i - 1)%3 + 1);
mainLayout->addWidget(digitButtons[i] , row , column);
}
mainLayout->addWidget(digitButtons[0] , 5, 1);
mainLayout->addWidget(pointButton , 5 , 2);
mainLayout->addWidget(changeSignButton , 5, 3);
mainLayout->addWidget(divisionButton , 2, 4);
mainLayout->addWidget(timesButton , 3 , 4);
mainLayout->addWidget(minusButton , 4, 4);
mainLayout->addWidget(plusButton , 5 , 4);
mainLayout->addWidget(squareRootButton , 2, 5);
mainLayout->addWidget(powerButton , 3 , 5);
mainLayout->addWidget(reciprocalButton , 4, 5);
mainLayout->addWidget(equalButton , 5,5);
setLayout(mainLayout);
setWindowTitle(tr("Calculator"));
}
Calculator::~Calculator()
{
}
void Calculator::digitClicked(){
Button* clickedButton = qobject_cast<Button*>(sender());
int digitValue = clickedButton->text().toInt();
if(display->text() == "0" && digitValue == 0.0){
return;
}
if(waitingForOperand){
display->clear();
waitingForOperand = false;
}
display->setText(display->text() + QString::number(digitValue));
}
void Calculator::unaryOperatorClicked(){
Button* clickedButton = qobject_cast<Button*>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
double result = 0.0;
if(clickedOperator == tr("Sqrt")){
if(operand <0.0){
abortOperation();
return;
}
result = sqrt(operand);
}else if(clickedOperator == tr("x\302\262")){
result = pow(operand , 2.0);
}else if(clickedOperator == tr("1/x")){
if(operand == 0.0){
abortOperation();
return;
}
result = 1.0 / operand;
}
display->setText(QString::number(result));
waitingForOperand = true;
}
void Calculator::additiveOperatorClicked(){
Button* clickedButton = qobject_cast<Button*>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
if(!pendingAdditiveOperator.isEmpty()){
if(!calculate(operand , pendingMultiplicatibeOperator)){
abortOperation();
return;
}
display->setText(QString::number(factorSoFar));
operand = factorSoFar;
factorSoFar = 0.0;
pendingMultiplicatibeOperator.clear();
}
if(!pendingAdditiveOperator.isEmpty()){
if(!calculate(operand , pendingAdditiveOperator)){
abortOperation();
return;
}
display->setText(QString::number(sumSoFar));
}else{
sumSoFar = operand;
}
pendingAdditiveOperator = clickedOperator;
waitingForOperand = true;
}
void Calculator::multiplicativeOperatorClicked(){
Button* clickedButton = qobject_cast<Button*>(sender());
QString clickedOperator = clickedButton->text();
double operand = display->text().toDouble();
if(!pendingMultiplicatibeOperator.isEmpty()){
if(!calculate(operand , pendingMultiplicatibeOperator)){
abortOperation();
return;
}
display->setText(QString::number(factorSoFar));
}else{
factorSoFar = operand;
}
pendingMultiplicatibeOperator = clickedOperator;
waitingForOperand = true;
}
void Calculator::equalClicked(){
double operand = display->text().toDouble();
if(!pendingMultiplicatibeOperator.isEmpty()){
if(!calculate(operand , pendingMultiplicatibeOperator)){
abortOperation();
return;
}
operand = factorSoFar;
factorSoFar = 0.0;
pendingMultiplicatibeOperator.clear();
}
if(!pendingAdditiveOperator.isEmpty()){
if(!calculate(operand , pendingAdditiveOperator)){
abortOperation();
return;
}
pendingAdditiveOperator.clear();
}else{
sumSoFar = operand;
}
display->setText(QString::number(sumSoFar));
sumSoFar = 0.0;
waitingForOperand = true;
}
void Calculator::pointClicked()
{
}
//void Calculator::changeSignClicked()
//{
// if(waitingForOperand){
// display->setText("0");
// }
// if(!display->text().contains(".")){
// display->setText(display->text() + tr("."));
// }
// waitingForOperand = false;
//}
void Calculator::changeSignClicked(){
QString text = display->text();
double value = text.toDouble();
if(value > 0.0){
text.prepend(tr("-"));
}else if(value < 0.0){
text.remove(0,1);
}
display->setText(text);
}
void Calculator::backspaceClicked()
{
if(waitingForOperand){
return;
}
QString text = display->text();
text.chop(1);
if(text.isEmpty()){
text = "0";
waitingForOperand = true;
}
display->setText(text);
}
void Calculator::clear(){
if(waitingForOperand){
return ;
}
display->setText("0");
waitingForOperand = true;
}
void Calculator::clearAll(){
sumSoFar = 0.0;
factorSoFar = 0.0;
pendingAdditiveOperator.clear();
pendingMultiplicatibeOperator.clear();
display->setText("0");
waitingForOperand = true;
}
void Calculator::clearMemory(){
sumInMemory = 0.0;
}
void Calculator::readMemory(){
display->setText(QString::number(sumInMemory));
waitingForOperand = true;
}
void Calculator::setMemory(){
equalClicked();
sumInMemory = display->text().toDouble();
}
void Calculator::addToMemory(){
equalClicked();
sumInMemory += display->text().toDouble();
}
Button* Calculator::createButton(const QString &text, const char *memory){
Button* button = new Button(text);
connect(button , SIGNAL(clicked()) , this , memory);
return button;
}
void Calculator::abortOperation(){
clearAll();
display->setText(tr("###"));
}
bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
{
if(pendingOperator == tr("+")){
sumSoFar += rightOperand;
}else if(pendingOperator == tr("-")){
sumSoFar -= rightOperand;
}else if(pendingOperator == tr("\303\227")){
factorSoFar *= rightOperand;
}else if(pendingOperator == tr("\303\267")){
if(rightOperand == 0.0)
return false;
factorSoFar /= rightOperand;
}
return true;
}
最后在主窗口中添加窗口的显示就完成了这个小程序了。
#include <QApplication>
#include"calculator.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// MainWindow w;
//w.show();
Calculator w;
w.show();
return a.exec();
}