小算盤標準型的思路
小弟剛入職所以老闆還在考核我的學習能力因為小弟還是個新手 剛接觸QT也只有1周的時間 C++基礎也很薄弱上周做了一個簡單的四則運算計算機 被老闆講說我做的是垃圾根本沒有實用價值要我在下周二前在做一個跟微軟小算盤標準型有同樣功能跟算數邏輯的計算器並且要求我注意並且增加 1:16進制 10進制 2進制的互相轉換2:能連續運算 像是能連續輸入1+2/3+4-5 並且遵從 /* >+-的執行規則3:1/3=0.333333333後*3會回歸1 開根號開平方都比照辦理4:基本的除錯1/0 要顯示出Error 除數不可為0等等(這個我有做出來我自己看了QT本身提供的calcuator範例簡直看得一頭霧水 連他的運算式是怎麼完成的都看不太懂 而且他沒有透過ui檔新增button而是直接在主程式新增並且排程(這部分我有看懂是怎麼做的)但是我還是比較習慣在表單用ui直接手動增加元件....我現在碰到幾個難關進位的處理要怎麼做才不會卡到二次運算的輸出 我一般都是在按鍵1~9做自動進位*10 等到按下=之後才做ui->lineEdit->setText(Qstring::number((A+B)/10)並且輸出答案(但是這樣我會卡到多次運算 只能做單次運算)有辦法直接在lineEdit內輸入值後直接拿那些值來運算嗎?要怎麼把他轉為數值?比方說我直接連續在理面輸入1+2/3+4-5 然後我直接拿出來做運算? 下面是我參考的範例源碼 目前只看懂不到1/3而已首先他頭文件有2個 我不懂為什麼會要弄到2個頭文件 我自己做的只有1個頭文件#ifndef BUTTON_H#define BUTTON_H#include <QToolButton>//! [0]class Button : public QToolButton{ Q_OBJECTpublic: explicit Button(const QString &text, QWidget *parent = 0); QSize sizeHint() const Q_DECL_OVERRIDE;};//! [0]#endif-------------------------------------------------------------------------------------------------------------------------#ifndef CALCULATOR_H#define CALCULATOR_H#include <QWidget>QT_BEGIN_NAMESPACEclass QLineEdit;QT_END_NAMESPACEclass Button;//! [0]class Calculator : public QWidget{ Q_OBJECTpublic: Calculator(QWidget *parent = 0);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();//! [0]//! [1]private://! [1] //! [2] Button *createButton(const QString &text, const char *member); void abortOperation(); bool calculate(double rightOperand, const QString &pendingOperator);//! [2]//! [3] double sumInMemory;//! [3] //! [4] double sumSoFar;//! [4] //! [5] double factorSoFar;//! [5] //! [6] QString pendingAdditiveOperator;//! [6] //! [7] QString pendingMultiplicativeOperator;//! [7] //! [8] bool waitingForOperand;//! [8]//! [9] QLineEdit *display;//! [9] //! [10] enum { NumDigitButtons = 10 }; Button *digitButtons[NumDigitButtons];};//! [10]#endif然後是主文件也有3個 比我正常在做多一個#include <QtWidgets>#include "button.h"//! [0]Button::Button(const QString &text, QWidget *parent) : QToolButton(parent){ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); setText(text);}//! [0]//! [1]QSize Button::sizeHint() const//! [1] //! [2]{ QSize size = QToolButton::sizeHint(); size.rheight() += 20; size.rwidth() = qMax(size.width(), size.height()); return size;}//! [2]----------------------------------------------------------------------------------------------------------------#include <QtWidgets>#include <cmath>#include "button.h"#include "calculator.h"//! [0]Calculator::Calculator(QWidget *parent) : QWidget(parent){ sumInMemory = 0.0; sumSoFar = 0.0; factorSoFar = 0.0; waitingForOperand = true;//! [0]//! [1] display = new QLineEdit("0");//! [1] //! [2] display->setReadOnly(true); display->setAlignment(Qt::AlignRight); display->setMaxLength(15); QFont font = display->font(); font.setPointSize(font.pointSize() + 8); display->setFont(font);//! [2]//! [4] for (int i = 0; i < NumDigitButtons; ++i) { digitButtons = createButton(QString::number(i), SLOT(digitClicked())); } Button *pointButton = createButton(tr("."), SLOT(pointClicked())); Button *changeSignButton = createButton(tr("\302\261"), SLOT(changeSignClicked())); Button *backspaceButton = createButton(tr("Backspace"), 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())); Button *divisionButton = createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked())); Button *timesButton = createButton(tr("\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()));//! [4]//! [5] QGridLayout *mainLayout = new QGridLayout;//! [5] //! [6] 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 = 1; i < NumDigitButtons; ++i) { int row = ((9 - i) / 3) + 2; int column = ((i - 1) % 3) + 1; mainLayout->addWidget(digitButtons, 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"));}//! [6]//! [7]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));}//! [7]//! [8]void Calculator::unaryOperatorClicked()//! [8] //! [9]{ 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 = std::sqrt(operand); } else if (clickedOperator == tr("x\302\262")) { result = std::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;}//! [9]//! [10]void Calculator::additiveOperatorClicked()//! [10] //! [11]{ Button *clickedButton = qobject_cast<Button *>(sender()); QString clickedOperator = clickedButton->text(); double operand = display->text().toDouble();//! [11] //! [12] if (!pendingMultiplicativeOperator.isEmpty()) {//! [12] //! [13] if (!calculate(operand, pendingMultiplicativeOperator)) { abortOperation(); return; } display->setText(QString::number(factorSoFar)); operand = factorSoFar; factorSoFar = 0.0; pendingMultiplicativeOperator.clear(); }//! [13] //! [14] if (!pendingAdditiveOperator.isEmpty()) {//! [14] //! [15] if (!calculate(operand, pendingAdditiveOperator)) { abortOperation(); return; } display->setText(QString::number(sumSoFar)); } else { sumSoFar = operand; }//! [15] //! [16] pendingAdditiveOperator = clickedOperator;//! [16] //! [17] waitingForOperand = true;}//! [17]//! [18]void Calculator::multiplicativeOperatorClicked(){ Button *clickedButton = qobject_cast<Button *>(sender()); QString clickedOperator = clickedButton->text(); double operand = display->text().toDouble(); if (!pendingMultiplicativeOperator.isEmpty()) { if (!calculate(operand, pendingMultiplicativeOperator)) { abortOperation(); return; } display->setText(QString::number(factorSoFar)); } else { factorSoFar = operand; } pendingMultiplicativeOperator = clickedOperator; waitingForOperand = true;}//! [18]//! [20]void Calculator::equalClicked(){ double operand = display->text().toDouble(); if (!pendingMultiplicativeOperator.isEmpty()) { if (!calculate(operand, pendingMultiplicativeOperator)) { abortOperation(); return; } operand = factorSoFar; factorSoFar = 0.0; pendingMultiplicativeOperator.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;}//! [20]//! [22]void Calculator::pointClicked(){ if (waitingForOperand) display->setText("0"); if (!display->text().contains('.')) display->setText(display->text() + tr(".")); waitingForOperand = false;}//! [22]//! [24]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);}//! [24]//! [26]void Calculator::backspaceClicked(){ if (waitingForOperand) return; QString text = display->text(); text.chop(1); if (text.isEmpty()) { text = "0"; waitingForOperand = true; } display->setText(text);}//! [26]//! [28]void Calculator::clear(){ if (waitingForOperand) return; display->setText("0"); waitingForOperand = true;}//! [28]//! [30]void Calculator::clearAll(){ sumSoFar = 0.0; factorSoFar = 0.0; pendingAdditiveOperator.clear(); pendingMultiplicativeOperator.clear(); display->setText("0"); waitingForOperand = true;}//! [30]//! [32]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();}//! [32]//! [34]Button *Calculator::createButton(const QString &text, const char *member){ Button *button = new Button(text); connect(button, SIGNAL(clicked()), this, member); return button;}//! [34]//! [36]void Calculator::abortOperation(){ clearAll(); display->setText(tr("####"));}//! [36]//! [38]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;}//! [38]這個算盤的結果基本上跟我想要的是幾乎一樣了 只差位元轉換的部分 但是這個思路我搞不懂看不懂 有大神可以幫忙解說一下嗎??