天天看點

Qt Script之calculator

Qt Script之calculator

簡易電腦主要有數字,一進制操作符,二進制操作符,和memory操作

初始狀态等待輸入操作數,若輸入的是運算符得到的運算結果依然是0.若輸入的是數字則顯示出來

并将等待操作數設定為false,下次若還是數字則直接添加到後面如果是一進制運算符則直接得出結果

顯示出來,若是二進制運算符則分别用sumSoFar(記錄加減操作數),factorSoFar(記錄乘除操作數)和用

pendingAdditiveOperator(加減),pendingMultiplicativeOperator(乘除)運算符并設定等待操作數為true

//main.cpp
int main(int argc, char **argv)
{
    Q_INIT_RESOURCE(calculator);//初始化資源

    QApplication app(argc, argv);
//! [0a]
    QScriptEngine engine;//JS引擎解釋執行JS代碼
//! [0a]

//JS調試視窗

if !defined(QT_NO_SCRIPTTOOLS)

    QScriptEngineDebugger debugger;
    debugger.attachTo(&engine);
    QMainWindow *debugWindow = debugger.standardWindow();
    debugWindow->resize(, );
    //debugWindow->show();

endif

//! [0b] 加載JS代碼
    QString scriptFileName(":/calculator.js");
    QFile scriptFile(scriptFileName);
    scriptFile.open(QIODevice::ReadOnly);
    engine.evaluate(scriptFile.readAll(), scriptFileName);
    scriptFile.close();
//! [0b]

//! [1]加載界面UI檔案
    QUiLoader loader;
    QFile uiFile(":/calculator.ui");
    uiFile.open(QIODevice::ReadOnly);
    QWidget *ui = loader.load(&uiFile);
    uiFile.close();
//! [1]

//! [2]
    QScriptValue ctor = engine.evaluate("Calculator");//執行Calculator代碼
    QScriptValue scriptUi = engine.newQObject(ui, QScriptEngine::ScriptOwnership);//建立一個script下的UI對象
    QScriptValue calc = ctor.construct(QScriptValueList() << scriptUi);//構造Calculator對象
//! [2]

if !defined(QT_NO_SCRIPTTOOLS)

    QLineEdit *display = ui->findChild<QLineEdit*>("display");
    QObject::connect(display, SIGNAL(returnPressed()),
                     debugWindow, SLOT(show()));

endif

//! [3]
    ui->show();
    return app.exec();
//! [3]
}
           
//calculator.js

Function.prototype.bind = function() {
    var func = this;//this即Function
    var thisObject = arguments[];//函數執行上下文
    var args = Array.prototype.slice.call(arguments, );//将具有length屬性的對象轉成數組
    return function() {
        return func.apply(thisObject, args);//調用func函數
    }
}

//! [0]
function Calculator(ui)
{
    this.ui = ui;//擷取界面

    this.pendingAdditiveOperator = Calculator.NO_OPERATOR;//未決定的加法操作符
    this.pendingMultiplicativeOperator = Calculator.NO_OPERATOR;//未決定的乘法操作符
    this.sumInMemory = ;//記錄要存儲的資料
    this.sumSoFar = ;//記錄加減結果
    this.factorSoFar = ;//記錄乘除結果
    this.waitingForOperand = true;//是否在等待操作數

    with (ui) {
        display.text = "0";
        //綁定數字按鈕響應函數
        zeroButton.clicked.connect(this.digitClicked.bind(this, ));
        oneButton.clicked.connect(this.digitClicked.bind(this, ));
        twoButton.clicked.connect(this.digitClicked.bind(this, ));
        threeButton.clicked.connect(this.digitClicked.bind(this, ));
        fourButton.clicked.connect(this.digitClicked.bind(this, ));
        fiveButton.clicked.connect(this.digitClicked.bind(this, ));
        sixButton.clicked.connect(this.digitClicked.bind(this, ));
        sevenButton.clicked.connect(this.digitClicked.bind(this, ));
        eightButton.clicked.connect(this.digitClicked.bind(this, ));
        nineButton.clicked.connect(this.digitClicked.bind(this, ));
        //綁定小數點按鈕響應函數
        pointButton.clicked.connect(this, "pointClicked");
        //綁定改變符号按鈕響應函數
        changeSignButton.clicked.connect(this, "changeSignClicked");
        //後退按鈕,清空按鈕,和清空全部按鈕響應函數
        backspaceButton.clicked.connect(this, "backspaceClicked");
        clearButton.clicked.connect(this, "clear");
        clearAllButton.clicked.connect(this, "clearAll");
        //清空存儲,讀取存儲,設定存儲,添加到存儲按鈕響應函數
        clearMemoryButton.clicked.connect(this, "clearMemory");
        readMemoryButton.clicked.connect(this, "readMemory");
        setMemoryButton.clicked.connect(this, "setMemory");
        addToMemoryButton.clicked.connect(this, "addToMemory");
        //運算符按鈕響應函數
        divisionButton.clicked.connect(this.multiplicativeOperatorClicked.bind(this, Calculator.DIVISION_OPERATOR));
        timesButton.clicked.connect(this.multiplicativeOperatorClicked.bind(this, Calculator.TIMES_OPERATOR));
        minusButton.clicked.connect(this.additiveOperatorClicked.bind(this, Calculator.MINUS_OPERATOR));
        plusButton.clicked.connect(this.additiveOperatorClicked.bind(this, Calculator.PLUS_OPERATOR));

        squareRootButton.clicked.connect(this.unaryOperatorClicked.bind(this, Calculator.SQUARE_OPERATOR));
        powerButton.clicked.connect(this.unaryOperatorClicked.bind(this, Calculator.POWER_OPERATOR));
        reciprocalButton.clicked.connect(this.unaryOperatorClicked.bind(this, Calculator.RECIPROCAL_OPERATOR));
        equalButton.clicked.connect(this, "equalClicked");
    }
}
//! [0]
//定義運算符
Calculator.NO_OPERATOR = ;
Calculator.SQUARE_OPERATOR = ;
Calculator.POWER_OPERATOR = ;
Calculator.RECIPROCAL_OPERATOR = ;
Calculator.DIVISION_OPERATOR = ;
Calculator.TIMES_OPERATOR = ;
Calculator.MINUS_OPERATOR = ;
Calculator.PLUS_OPERATOR = ;
//中斷操作函數
Calculator.prototype.abortOperation = function()
{
    this.clearAll();
    this.ui.display.text = "####";
}
//計算函數,參數是右操作數和運算符并且将運算結果存儲到sumSoFar
Calculator.prototype.calculate = function(rightOperand, pendingOperator)
{
    if (pendingOperator == Calculator.PLUS_OPERATOR) {
        this.sumSoFar += rightOperand;
    } else if (pendingOperator == Calculator.MINUS_OPERATOR) {
        this.sumSoFar -= rightOperand;
    } else if (pendingOperator == Calculator.TIMES_OPERATOR) {
        this.factorSoFar *= rightOperand;
    } else if (pendingOperator == Calculator.DIVISION_OPERATOR) {
        if (rightOperand == )
            return false;
        this.factorSoFar /= rightOperand;
    }
    return true;
}

//! [1]
//操作數處理函數
Calculator.prototype.digitClicked = function(digitValue)
{
    if ((digitValue == ) && (this.ui.display.text == "0"))//初始狀态
        return;
    if (this.waitingForOperand) {//若等待操作數為真
        this.ui.display.clear();//清空display
        this.waitingForOperand = false;//設定等待操作數為false
    }
    this.ui.display.text += digitValue;//将操作數添加到display顯示文本後面
}
//! [1]
//一進制操作符處理函數
Calculator.prototype.unaryOperatorClicked = function(op)
{
    var operand = this.ui.display.text - ;//擷取操作數
    var result = ;
    if (op == Calculator.SQUARE_OPERATOR) {//開根号若操作數為負則終止操作
        if (operand < ) {
            this.abortOperation();
            return;
        }
        result = Math.sqrt(operand);
    } else if (op == Calculator.POWER_OPERATOR) {//平方
        result = Math.pow(operand, );
    } else if (op == Calculator.RECIPROCAL_OPERATOR) {//1/x若x為0則終止操作
        if (operand == ) {
            this.abortOperation();
            return;
        }
        result =  / operand;
    }
    this.ui.display.text = result + "";//顯示結果
    this.waitingForOperand = true;//處理完一個過程後将等待操作數設定為true
}
//+-操作符處理函數
Calculator.prototype.additiveOperatorClicked = function(op)
{
    var operand = this.ui.display.text - ;//擷取操作數

    if (this.pendingMultiplicativeOperator != Calculator.NO_OPERATOR) {//若有乘除操作符則先計算乘除
        if (!this.calculate(operand, this.pendingMultiplicativeOperator)) {
            this.abortOperation();
            return;
        }
        this.ui.display.text = this.factorSoFar + "";
        operand = this.factorSoFar;
        this.factorSoFar = ;
        this.pendingMultiplicativeOperator = Calculator.NO_OPERATOR;
    }

    if (this.pendingAdditiveOperator != Calculator.NO_OPERATOR) {
        if (!this.calculate(operand, this.pendingAdditiveOperator)) {
            this.abortOperation();
            return;
        }
        this.ui.display.text = this.sumSoFar + "";
    } else {
        this.sumSoFar = operand;
    }

    this.pendingAdditiveOperator = op;
    this.waitingForOperand = true;
}
//乘除處理函數
Calculator.prototype.multiplicativeOperatorClicked = function(op)
{
    var operand = this.ui.display.text - ;

    if (this.pendingMultiplicativeOperator != Calculator.NO_OPERATOR) {
        if (!this.calculate(operand, this.pendingMultiplicativeOperator)) {
            this.abortOperation();
            return;
        }
        this.ui.display.text = this.factorSoFar + "";
    } else {
        this.factorSoFar = operand;
    }

    this.pendingMultiplicativeOperator = op;
    this.waitingForOperand = true;
}
//等于處理函數
Calculator.prototype.equalClicked = function()
{
    var operand = this.ui.display.text - ;

    if (this.pendingMultiplicativeOperator != Calculator.NO_OPERATOR) {
        if (!this.calculate(operand, this.pendingMultiplicativeOperator)) {
            this.abortOperation();
            return;
        }
        operand = this.factorSoFar;
        this.factorSoFar = ;
        this.pendingMultiplicativeOperator = Calculator.NO_OPERATOR;
    }
    if (this.pendingAdditiveOperator != Calculator.NO_OPERATOR) {
        if (!this.calculate(operand, this.pendingAdditiveOperator)) {
            this.abortOperation();
            return;
        }
        this.pendingAdditiveOperator = Calculator.NO_OPERATOR;
    } else {
        this.sumSoFar = operand;
    }

    this.ui.display.text = this.sumSoFar + "";
    this.sumSoFar = ;
    this.waitingForOperand = true;
}

Calculator.prototype.pointClicked = function()
{
    if (this.waitingForOperand)
        this.ui.display.text = "0";
    if (this.ui.display.text.indexOf(".") == -)//text裡不包含.時則添加.
        this.ui.display.text += ".";
    this.waitingForOperand = false;
}

//! [2]
//取負
Calculator.prototype.changeSignClicked = function()
{
    var text = this.ui.display.text;
    var value = text - ;

    if (value > ) {
        text = "-" + text;
    } else if (value < ) {
        text = text.slice();
    }
    this.ui.display.text = text;
}
//! [2]

Calculator.prototype.backspaceClicked = function()
{
    if (this.waitingForOperand)
        return;

    var text = this.ui.display.text;
    text = text.slice(, -);
    if (text.length == ) {//擷取的text為0時設定等待操作數為真
        text = "0";
        this.waitingForOperand = true;
    }
    this.ui.display.text = text;
}
//清除display資料
Calculator.prototype.clear = function()
{
    if (this.waitingForOperand)
        return;

    this.ui.display.text = "0";
    this.waitingForOperand = true;
}
//清空全部資料
Calculator.prototype.clearAll = function()
{
    this.sumSoFar = ;
    this.factorSoFar = ;
    this.pendingAdditiveOperator = Calculator.NO_OPERATOR;
    this.pendingMultiplicativeOperator = Calculator.NO_OPERATOR;
    this.ui.display.text = "0";
    this.waitingForOperand = true;
}
//清空存儲的資料
Calculator.prototype.clearMemory = function()
{
    this.sumInMemory = ;
}
//讀取存儲的資料并顯示出來
Calculator.prototype.readMemory = function()
{
    this.ui.display.text = this.sumInMemory + "";
    this.waitingForOperand = true;
}
//設定存儲資料并顯示出來
Calculator.prototype.setMemory = function()
{
    this.equalClicked();
    this.sumInMemory = this.ui.display.text - ;
}
//添加到存儲的資料中
Calculator.prototype.addToMemory = function()
{
    this.equalClicked();
    this.sumInMemory += this.ui.display.text - ;
}