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

Changing widget properties

This example shows how to implement a GUI control with a customizable action on activation. ScriptButton is a specialized QPushButton class that can have a snippet of script code attached to it. The script will be executed whenever the user clicks on the button. To modify the behavior of the buttons the user can right-click a button and choose to either rename the button label or edit the script code in a simple editor.

For demonstration purposes the example widget contains both a QLCDNumber and QLineEdit widget whose properties can be changed by the buttons situated on the right side.


Header file:

#ifndef SCRIPTBUTTON_H
#define SCRIPTBUTTON_H

#include <qpushbutton.h>

class QPopupMenu;
class QSInterpreter;
class Editor;

class ScriptButton : public QPushButton {
    Q_OBJECT
    Q_PROPERTY( QString scriptCode READ scriptCode WRITE setScriptCode )

public:
    // standard QPushButton constructors
    ScriptButton( QSInterpreter *i, QWidget *parent, const char* name=0 );
    ScriptButton( QSInterpreter *i, const QString &text,
                  QWidget *parent, const char* name=0 );

    void setScriptCode( const QString &c );
    QString scriptCode() const { return code; }

public slots:
    void executeScript();

protected:
    void contextMenuEvent( QContextMenuEvent *e );

private slots:
    void editCode();
    void renameButton();

private:
    void init( QSInterpreter *i );

    QString code;
    QPopupMenu *popup;
    Editor *edit;
    QSInterpreter *ip;
};

#endif


Implementation:

#include "scriptbutton.h"

#include <qsinterpreter.h>
#include <qseditor.h>
#include <qpopupmenu.h>
#include <qinputdialog.h>
#include <qtextedit.h>
#include <qlayout.h>

class Editor : public QDialog
{
public:
    Editor( QWidget *parent = 0, const char *name = 0 );
    void setCode( const QString &c );
    QString code() const { return ed->text(); }

protected:
    void keyPressEvent( QKeyEvent *e ) {
        if ( e->key() == Key_Escape ) { // let the editor handle the ESC key
            e->ignore();
            return;
        }
        QDialog::keyPressEvent( e );
    }

private:
    QSEditor *ed;
};

Editor::Editor( QWidget *parent, const char *name )
    : QDialog( parent, name )
{
    ed = new QSEditor( this );
    QPushButton *ok = new QPushButton( "&OK", this );
    QPushButton *cancel = new QPushButton( "&Cancel", this );
    connect( ok, SIGNAL( clicked() ), SLOT( accept() ) );
    connect( cancel, SIGNAL( clicked() ), SLOT( reject() ) );

    QVBoxLayout *vbox = new QVBoxLayout( this, 5 );
    vbox->addWidget( ed );
    QHBoxLayout *hbox = new QHBoxLayout( vbox );
    hbox->addWidget( ok );
    hbox->addStretch( -1 );
    hbox->addWidget( cancel );
    resize( 400, 400 );
}

void Editor::setCode( const QString &c )
{
    if ( QSEditor::activeEditor() )
        QSEditor::activeEditor()->release();
    ed->setText( c );
    ed->activate();
}

ScriptButton::ScriptButton( QSInterpreter *i,
                            QWidget *parent, const char* name )
    : QPushButton( parent, name )
{
    init( i );
}

ScriptButton::ScriptButton( QSInterpreter *i, const QString &text,
                            QWidget *parent, const char* name )
    : QPushButton( text, parent, name )
{
    init( i );
}

void ScriptButton::init( QSInterpreter *i )
{
    ip = i;
    popup = 0;
    edit = 0;
    connect( this, SIGNAL(clicked()), this, SLOT(executeScript()) );
}

void ScriptButton::setScriptCode( const QString &c )
{
    code = c;
}

void ScriptButton::executeScript()
{
    if ( !code.isEmpty() )
        ip->evaluate( code );
}

void ScriptButton::contextMenuEvent( QContextMenuEvent *e )
{
    if ( !popup ) {
        popup = new QPopupMenu( this );
        popup->insertItem( "Rename Button", this, SLOT(renameButton()) );
        popup->insertItem( "Edit Code", this, SLOT(editCode()) );
    }
    popup->exec( e->globalPos() );
    e->accept();
}

void ScriptButton::renameButton()
{
    bool ok;
    QString n = QInputDialog::getText( "Script Button",
                                       "Enter new button name",
                                       QLineEdit::Normal,
                                       text(), &ok, this );
    if ( ok )
        setText( n );
}

void ScriptButton::editCode()
{
    if ( !edit ) {
        edit = new Editor();
        edit->setCaption( QString( "%1 Script Code" ).arg( name() ) );
    }
    edit->setCode( scriptCode() );
    if ( edit->exec() == QDialog::Accepted )
        setScriptCode( edit->code() );
}


Main:

#include "scriptbutton.h"

#include <qsinterpreter.h>
#include <qapplication.h>
#include <qwidget.h>
#include <qlcdnumber.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <qgroupbox.h>
#include <qlayout.h>
#include "widgetwrapper.h"

int main( int argc, char **argv )
{
    QApplication app( argc, argv );
    QWidget widget;

    // create two sample widgets
    QGroupBox *lcdGroup = new QGroupBox( 2, Qt::Vertical, "lcd", &widget );
    QGroupBox *editGroup = new QGroupBox( 2, Qt::Vertical, "edit", &widget );
    QLCDNumber *lcd = new QLCDNumber( lcdGroup, "lcd" );
    QLineEdit *edit = new QLineEdit( editGroup, "edit" );
    edit->setText( "text" );

    // some help text
    QLabel *help = new QLabel( "Right-click on any of the buttons to edit "
                               "its properties.", &widget );
    new QLabel( "Properties: <ul><li>value</li>"
                "<li>setHexMode()</li><li>...</li></ul>", lcdGroup );
    new QLabel( "Properties: <ul><li>text</li><li>maxLength</li>"
                "<li>clear()</li><li>...</li></ul>", editGroup );

    QSInterpreter ip;

    // add script buttons
    ScriptButton *button1 = new ScriptButton( &ip, "Increase Counter",
                                              &widget, "button1" );
    ScriptButton *button2 = new ScriptButton( &ip, "Reset Counter",
                                              &widget, "button2" );
    ScriptButton *button3 = new ScriptButton( &ip, "Convert to uppercase",
                                              &widget, "button2" );

    ScriptButton *button4 = new ScriptButton( &ip, "&Quit",
                                              &widget, "button3" );

    button1->setScriptCode( "Application.lcd.value++;" );
    button2->setScriptCode( "Application.lcd.value = 0;" );
    button3->setScriptCode( "Application.edit.text = Application.edit.text.upper();" );
    button4->setScriptCode( "Application.exit();" );

    // layout widgets
    QVBoxLayout *ml = new QVBoxLayout( &widget, 10 );
    ml->addWidget( help );
    QHBoxLayout *hbox = new QHBoxLayout( ml );
    hbox->addWidget( lcdGroup );
    hbox->addWidget( editGroup );
    QVBoxLayout *vbox = new QVBoxLayout( hbox );
    vbox->addWidget( button1 );
    vbox->addWidget( button2 );
    vbox->addWidget( button3 );
    vbox->addStretch( -1 );
    vbox->addWidget( button4 );

    // teach interpreter about widgets
    (void)new WidgetWrapperFactory;
    ip.addObject( lcd );
    ip.addObject( edit );

    app.setMainWidget( &widget );
    widget.show();

    return app.exec();
}

See also QSA Examples.


Copyright © 2001-2002 TrolltechTrademarks
QSA version 1.0.0-beta1