|Home | Tutorial | Classes | Functions | QSA Developer | Language | Library | Qt API | QSA Articles Qt Script for Applications

[Prev: How to Design and Implement Application Objects] [Home] [Next: Debugging Qt Script Applications]

Creating Scripts using Qt Script for Applications

In this chapter we'll demonstrate how to create scripts for a scriptable application. We will explain how to use Qt Scripter, the built-in IDE, to create a dialog using Qt Script and then create and implement a convertToEuro() function. We will write the scripts using the spreadsheet application that we created in an earlier chapter.

Settings for Euro Converter Finished Dialog

Creating a New Macro

A 'Macro' is simply a global Qt Script function.

Run the spreadsheet application if it isn't already running.

Click the New button located on the Scripts toolbar to invoke the New Macro dialog. Once we create a new macro, a toolbar button will appear on the Scripts toolbar as a shortcut to execute the macro.

New Macro Toolbar Button

Follow the steps below to create the new macro:

Click OK when you have entered the information in the New Script dialog. The Add Function message box will pop up, saying "The function doesn't exist. Do you want to add it?". Click Yes.

Adding the New Function

Please note that Qt Scripter pops up automatically when you set up the macro for the new script in the New Macro dialog. This is the recommended way to open the IDE when creating a new function. If you want to access Qt Scripter another way, click the Open Qt Scripter toolbar button on the Scripts toolbar.

Qt Scripter pops up and the source code editor is open with the new empty function added to it. We will implement the scripting function in the following section.

Creating a Dialog

Before we implement our new function, we need to create a dialog which will allow the user to enter data, call our function, and display the results. It is possible to write macros that the user can execute directly. But in this example, we want to present the user with a dialog in which they can: 1) enter a range of rows and columns which are read from the spreadsheet, 2) specify where in the spreadsheet the results should be written, and 3) select a currency type to convert into Euros.

It is possible to create dialogs where widgets have fixed sizes and positions, such dialogs don't scale so are unsatisfactory if the text is translated into a different language that takes up more space, or if used on a smaller screen. Qt Scripter uses layouts which place widgets in relation to each other and which allows them to scale perfectly.

Creating a New Dialog

Click File|New|Dialog to create a new dialog. A new dialog called 'Dialog1' will appear. Note that this dialog is also listed in the Project Overview list. The Properties tab of the Property Editor/Signal Handler's window shows the dialog's default property settings.

Click in the Value column beside the name property and change the dialog's name to 'EuroSettings'. Change the dialog's caption to 'Settings for Euro Converter'. The properties are ordered in accordance with the inheritance hierarchy, and caption is roughly in the middle of the property editor. Save the form: click File|Save.

Property Editor

Using the Property Editor

The Properties tab of the Property Editor/Signal Handlers window, has two columns, the Property column which lists property names and the Value column which lists the values of the properties. Some property names have a plus sign '+' in a square to their left; this signifies that the property name is the collective name for a set of related properties. Click the form to make the Property Editor show the form's properties. Click the sizePolicy property's plus sign; you will see four properties appear indented below sizePolicy: hSizeType, vSizeType, horizontalStretch and verticalStretch. These properties are edited in the same way as any other properties.

Some properties have simple values, for example, the name property has a text value, the width property (within minimumSize for example) has a numeric value. To change a text value click the existing text and type in your new text. To change a numeric value click the value and either type in a new number, or use the spin buttons to increase or decrease the existing number until it reaches the value you want. Some properties have a fixed list of values, for example the mouseTracking property is boolean and can take the values True or False. The cursor property also has a fixed list of values. If you click the cursor property or the mouseTracking property the value will be shown in a drop down combobox; click the down arrow to see what values are available. Some properties have complex sets of values; for example the font property. If you click the font property an ellipsis button (...) will appear; click this button and a Select Font dialog will pop up which you can use to change any of the font settings. Other properties have ellipsis buttons which lead to different dialogs depending on what settings the property can have. For example, if you have a lot of text to enter for a text property, you could click the ellipsis button to invoke the multi-line text editor dialog.

The names of properties which have changed are shown in bold. If you've changed a property but want to revert it to its default value click the property's value and then click the red 'X' button to the right of the value. Some properties have an initial value, e.g. 'TextEdit1', but no default value; if you revert a property that has an initial value but no default value (by clicking the red 'X') the value will become empty unless the property, e.g. name, is not allowed to be empty.

Adding Widgets and Laying Out the Dialog

The Settings for Euro dialog consists of two spinboxes for selecting the columns and rows on the spreadsheet, a group box to lay out these spinboxes, another spinbox to select the column to output the result to, a combobox to select the currency to convert from, and some text labels and checkboxes. If you run the dialog application and resize it, all the widgets scale properly.

The Qt Script for Applications approach to laying out a dialog is to place the required widgets on the dialog in the approximate positions that they should occupy and then use the layout tools to size and position them correctly. Most of the widgets we need are on the Toolbox toolbar located by default on the left side of Qt Scripter. The widgets are listed in categories; to display a group of widgets, click on the category button. We'll now add the Settings for Euro dialog's widgets.

Add Text Labels to the Group Box

Note: When you double-click a widget from the toolbar, you enter 'click-to-place' mode; this means that whenever you click the form a new widget of the type you double-clicked will be placed. This is a shortcut instead of having to click the widget each time. To stop adding the widget to the toolbar, click the Pointer button or press F2.

Pointer Toolbar Button

We also need to add multiple spinboxes to the group box.

Now we are ready to lay out the group box. Click the group box and then click the Lay out in a grid toolbar button.

Lay Out the Group Box Widget

We are now ready to add the rest of the widgets to the form.

We have now placed all of our widgets on the dialog, but the dialog does not look quite right. The Calculate push button takes up too much space. We really need a couple of spacers to ensure that the widgets are all laid out properly.

Implementing the Script's Functionality

In Qt Script, we have some global objects. The most important one for our example is called Application. This object contains other objects, the most important being the application objects. These are the objects that the C++ application makes available to our script. In the spreadsheet example, the sheets are available this way, e.g. Application.sheet1. Other important objects which the Application object are the dialogs we create in the project, for example, Application.EuroSettings.

We will now implement the script's functionality.

When we first create our new macro, Qt Scripter automatically pops up and the source code editor is open with the new, empty function added to it (this is file main.qs). To open this editor again, click main.qs in the Project Overview window.

All global functions are implemented in this file. We want to write one line of code to execute our dialog.

    function convertToEuro()
    {
        Application.EuroSettings.exec();
    }

Now we want to implement the init() function of the dialog which will read the user's selection on the spreadsheet and initialize the spinboxes with these values.

Click the dialog and then right click Source in the context menu to open the source code editor. We want the code to do the following:

The first line of code finds out if the user has made a selection on the spreadsheet.

        if ( Application.sheet1.numSelections > 0 ) {

The second line of code retrieves the selection from the spreadsheet, if a selection was made.

            var r = Application.sheet1.selection( 0 );

The code that follows uses the values from the selection and initializes the values of the spinboxes in the dialog.

            spinStartRow.value = r.y + 1;
            spinEndRow.value = r.y + r.height;
            spinColumn.value = r.x + 1;
            spinOutputColumn.value = r.x + 2;
        }

We now need to set up a signal handler for the Calculate button, then implement the functionality of the signal handler.

Click the 'Calculate' button, then click the Signal Handlers tab in the Property Editor/Signal Handlers window. Right click the clicked() signal, then click New Signal Handler. A name is suggested for the new signal and will will accept it, so press Enter. This will create a signal handler called 'buttonCalculate_clicked()' and it is added to the source code editor as an empty function.

Note that there is an easier and more convenient way to create signal handlers for the default signals of widgets. We will show this later on when we connect the Cancel button.

This function is connected to the clicked signal of the button. When the Calculate button is clicked, we want the function to read the values the user has given in the dialog, and to also read the values from the spreadsheet and then calculate the results. When the results are calculated, we want to be able to write the results to the spreadsheet.

The first block of code reads what currency the user chose and then initializes the divisor accordingly:

    function buttonCalculate_clicked()
    {
        var divisor;

        switch ( comboCurrency.currentText ) {
        case "NOK":
            divisor = 7.8680;
            break;
        case "DM":
            divisor = 1.95583;
            break;
        case "ATS":
            divisor = 13.7603;
            break;
        }

The second block of code reads the range the user has entered in the dialog:

        const inputColumn = spinColumn.value - 1;
        const outputColumn = spinOutputColumn.value - 1;
        const startRow = spinStartRow.value - 1;
        const endRow = spinEndRow.value - 1;

The third block of code checks that the entered range is valid. If it is not valid, a warning is issued and the operation is canceled.

        if ( endRow < startRow ) {
            MessageBox.critical( "Cannot calculate!", "Error" );
            accept();
            return;
        }

The fourth block of code reads the value from the spreadsheet, calculates the results and then writes them back to the spreadsheet.

        for ( var i = startRow; i <= endRow; ++i )
            Application.sheet1.setText( i, outputColumn, Application.sheet1.text( i, inputColumn ) / divisor );

The last line of code simply closes the dialog.

            accept();
            return;
        }

Finally, we need to connect the Cancel button to the dialog to close the dialog.

Double click the Cancel button to create a signal handler. The signal handler is automatically connected to the default signal of the button, which in this case is the clicked signal. The source code editor opens and the cursor points to the new and empty signal handler function. The only thing we want this function to do is to close the dialog, so write "reject()" into the function body.

Running the EuroConvertor Macro

We are now ready to run the macro and invoke the dialog we just created.

Error Handling and Warnings

Sometimes an error occurs while parsing or executing the script. If this occurs, a message box will pop up with information about the error and gives the option to debug the error or ignore it.

Error Message Box

If you ignore the error, the script execution is stopped. If you choose to debug the error, Qt Scripter pops up and the error message is displayed in the Warnings/Errors tab of the debugger window. In addition, the piece of code that caused the error is highlighted in the source editor.

Highlighted Code in the Source Editor

Warnings are also displayed in the Warnings/Error window when developing a script and testing it out by executing it while Qt Scripter is open.

We've now designed a dialog and written the code to provide its functionality, all purely using Qt Script. This should provide a taste of the power and flexibility that Qt Script for Applications can provide for your Qt C++ applications.

[Prev: How to Design and Implement Application Objects] [Home] [Next: Debugging Qt Script Applications]


Copyright © 2001-2003 TrolltechTrademarks
QSA version 1.0.0-beta2