Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# TQt Tutorial - Chapter 4: Let There Be Widgets

This example shows how to create your own widget, describes how to control the minimum and maximum sizes of a widget, and introduces widget names.

    /****************************************************************
    **
    ** TQt tutorial 4
    **
    ****************************************************************/

    #include <ntqapplication.h>
    #include <ntqpushbutton.h>
    #include <ntqfont.h>

    class MyWidget : public TQWidget
    {
    public:
        MyWidget( TQWidget *parent=0, const char *name=0 );
    };

    MyWidget::MyWidget( TQWidget *parent, const char *name )
            : TQWidget( parent, name )
    {
        setMinimumSize( 200, 120 );
        setMaximumSize( 200, 120 );

        TQPushButton *quit = new TQPushButton( "Quit", this, "quit" );
        quit->setGeometry( 62, 40, 75, 30 );
        quit->setFont( TQFont( "Times", 18, TQFont::Bold ) );

        connect( quit, TQ_SIGNAL(clicked()), tqApp, TQ_SLOT(quit()) );
    }

    int main( int argc, char **argv )
    {
        TQApplication a( argc, argv );

        MyWidget w;
        w.setGeometry( 100, 100, 200, 120 );
        a.setMainWidget( &w );
        w.show();
        return a.exec();
    }

## Line-by-line Walkthrough

        class MyWidget : public TQWidget
        {
        public:
            MyWidget( TQWidget *parent=0, const char *name=0 );
        };

Here we create a new class. Because this class inherits from TQWidget, the new class is a widget and may be a top level window or a child widget (like the push button in Chapter 3).

This class has only one member, a constructor (in addition to the members it inherits from TQWidget). The constructor is a standard TQt widget constructor; you should always include a similar constructor when you create widgets.

The first argument is its parent widget. To create a top-level window you specify a null pointer as the parent. As you can see, this widget defaults to be a top-level window.

The second argument is the widget's name. This is not the text that appears in the window's title bar or in the button. It is a name associated with a widget to make it possible to look up this widget later, and there is also a handy debugging function that will list a complete widget hierarchy.

        MyWidget::MyWidget( TQWidget *parent, const char *name )
                : TQWidget( parent, name )

The implementation of the constructor starts here. Like most widgets, it just passes on the `parent` and `name` to the TQWidget constructor.

        {
            setMinimumSize( 200, 120 );
            setMaximumSize( 200, 120 );

Because this widget doesn't know how to handle resizing, we fix its size by setting the minimum and maximum to be equal. In the next chapter we will show how a widget can respond to resize event from the user.

            TQPushButton *quit = new TQPushButton( "Quit", this, "quit" );
            quit->setGeometry( 62, 40, 75, 30 );
            quit->setFont( TQFont( "Times", 18, TQFont::Bold ) );

Here we create and set up a child widget of this widget (the new widget's parent is `this`) which has the widget name "quit". The widget name has nothing to do with the button text; it just happens to be similar in this case.

Note that `quit` is a local variable in the constructor. MyWidget does not keep track of it, but TQt does, and will by default delete it when MyWidget is deleted. This is why MyWidget doesn't need a destructor. (On the other hand, there is no harm in deleting a child when you choose to, the child will automatically tell TQt about its imminent death.)

The setGeometry() call does the same as move() and resize() did in the previous chapters.

            connect( quit, TQ_SIGNAL(clicked()), tqApp, TQ_SLOT(quit()) );
        }

Because the MyWidget class doesn't know about the application object, it has to connect to TQt's pointer to it, `tqApp`.

A widget is a software component and should know as little as possible about its environment in order to be as general and reusable as possible.

Knowing the name of the application object would break this principle, so TQt offers an alias, tqApp, for the cases in which a component such as MyWidget needs to talk to the application object.

        int main( int argc, char **argv )
        {
            TQApplication a( argc, argv );

            MyWidget w;
            w.setGeometry( 100, 100, 200, 120 );
            a.setMainWidget( &w );
            w.show();
            return a.exec();
        }

Here we instantiate our new child, set it to be the main widget, and execute the application.

## Behavior

This program is very similar in behavior to the previous one. The difference lies in the way we have implemented it. It does behave slightly differently, however. Just try to resize it to see.

(See Compiling for how to create a makefile and build the application.)

## Exercises

Try to create another MyWidget object in main(). What happens?

Try to add more buttons or put in widgets other than TQPushButton.

You're now ready for Chapter 5.

[Previous tutorial] [Next tutorial] [Main tutorial page]