<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <!-- qtscriptcalculator.qdoc --> <head> <title>Qt 4.6: QtScript Calculator Example</title> <link href="classic.css" rel="stylesheet" type="text/css" /> </head> <body> <table border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> <td align="left" valign="top" width="32"><a href="http://qt.nokia.com/"><img src="images/qt-logo.png" align="left" border="0" /></a></td> <td width="1"> </td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a> · <a href="classes.html"><font color="#004faf">All Classes</font></a> · <a href="functions.html"><font color="#004faf">All Functions</font></a> · <a href="overviews.html"><font color="#004faf">Overviews</font></a></td></tr></table><h1 class="title">QtScript Calculator Example<br /><span class="subtitle"></span> </h1> <p>Files:</p> <ul> <li><a href="script-calculator-calculator-js.html">script/calculator/calculator.js</a></li> <li><a href="script-calculator-calculator-ui.html">script/calculator/calculator.ui</a></li> <li><a href="script-calculator-main-cpp.html">script/calculator/main.cpp</a></li> <li><a href="script-calculator-calculator-pro.html">script/calculator/calculator.pro</a></li> <li><a href="script-calculator-calculator-qrc.html">script/calculator/calculator.qrc</a></li> </ul> <p>In this simple <a href="qtscript.html">QtScript</a> example, we show how to implement the functionality of a calculator widget.</p> <p align="center"><img src="images/qtscript-calculator-example.png" /></p><p>The program logic in this example is a fairly straight port of the logic in the C++ <a href="widgets-calculator.html">Calculator Example</a>. The graphical user interface is defined in a UI file.</p> <p>The C++ part of the example consists of four steps:</p> <ul> <li>Evaluate the script code that defines the <tt>Calculator</tt> class.<pre> QScriptEngine engine; QString scriptFileName(":/calculator.js"); QFile scriptFile(scriptFileName); scriptFile.open(QIODevice::ReadOnly); engine.evaluate(scriptFile.readAll(), scriptFileName); scriptFile.close();</pre> </li> <li>Create a widget from the UI file using <a href="quiloader.html">QUiLoader</a>.<pre> QUiLoader loader; QFile uiFile(":/calculator.ui"); uiFile.open(QIODevice::ReadOnly); QWidget *ui = loader.load(&uiFile); uiFile.close();</pre> </li> <li>Call the Calculator constructor function to create a new <tt>Calculator</tt> script object, passing the widget as argument.<pre> QScriptValue ctor = engine.evaluate("Calculator"); QScriptValue scriptUi = engine.newQObject(ui, QScriptEngine::ScriptOwnership); QScriptValue calc = ctor.construct(QScriptValueList() << scriptUi);</pre> </li> <li>Show the widget and start the application event loop.<pre> ui->show(); return app.exec();</pre> </li> </ul> <p>On the script side, the <tt>Calculator</tt> constructor function initializes the instance variables of the new <tt>Calculator</tt> object, and connects the clicked() signal of the form's buttons to corresponding functions defined in the <tt>Calculator</tt> prototype object; the effect is that when a button is clicked, the proper script function will be invoked to carry out the operation.</p> <pre> function Calculator(ui) { this.ui = ui; this.pendingAdditiveOperator = Calculator.NO_OPERATOR; this.pendingMultiplicativeOperator = Calculator.NO_OPERATOR; this.sumInMemory = 0; this.sumSoFar = 0; this.factorSoFar = 0; this.waitingForOperand = true; with (ui) { display.text = "0"; zeroButton.clicked.connect(this.digitClicked.bind(this, 0)); oneButton.clicked.connect(this.digitClicked.bind(this, 1)); twoButton.clicked.connect(this.digitClicked.bind(this, 2)); threeButton.clicked.connect(this.digitClicked.bind(this, 3)); fourButton.clicked.connect(this.digitClicked.bind(this, 4)); fiveButton.clicked.connect(this.digitClicked.bind(this, 5)); sixButton.clicked.connect(this.digitClicked.bind(this, 6)); sevenButton.clicked.connect(this.digitClicked.bind(this, 7)); eightButton.clicked.connect(this.digitClicked.bind(this, 8)); nineButton.clicked.connect(this.digitClicked.bind(this, 9)); 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"); } }</pre> <p>A <tt>Calculator</tt> object is just a plain script object; it is not a widget. Instead, it stores a reference to the calculator form (the widget) in an instance variable, <tt>ui</tt>. The calculator script functions can access components of the form by referring to the proper children of the <tt>ui</tt> member.</p> <pre> Calculator.prototype.digitClicked = function(digitValue) { if ((digitValue == 0) && (this.ui.display.text == "0")) return; if (this.waitingForOperand) { this.ui.display.clear(); this.waitingForOperand = false; } this.ui.display.text += digitValue; }</pre> <p>The digitClicked() function is called when a digit button is clicked, with the input digit as argument.</p> <pre> Calculator.prototype.changeSignClicked = function() { var text = this.ui.display.text; var value = text - 0; if (value > 0) { text = "-" + text; } else if (value < 0) { text = text.slice(1); } this.ui.display.text = text; }</pre> <p>The changeSign() function shows how we retrieve the text property of the calculator's display, change it appropriately, and write back the new value.</p> <p /><address><hr /><div align="center"> <table width="100%" cellspacing="0" border="0"><tr class="address"> <td width="40%" align="left">Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)</td> <td width="20%" align="center"><a href="trademarks.html">Trademarks</a></td> <td width="40%" align="right"><div align="right">Qt 4.6.3</div></td> </tr></table></div></address></body> </html>