Qt GUI Toolkit

This GUI toolkit makes porting graphics to multiple platforms a snap.
Dialog Boxes

Finally, let's use our component to put together a dialog box. Most GUI applications contain these boxes. Dialogs are windows with a number of widgets as children. A typical example of a dialog is an input form for a database with a text field for each database field.

Qt contains the standard widgets needed to build dialogs for most purposes. This custom built dialog box class has been taken from www.troll.no/qt

class RotateDialog : public QDialog
{
    Q_OBJECT
public:
    RotateDialog( QWidget *parent=0,
                const char *name=0 );
    void resizeEvent( QResizeEvent * );
private slots:
    void updateCaption();
private:
    QPushButton   *quit;
    QPushButton   *load;
    QPushButton   *print;
    QScrollBar    *scrollBar;
    QFrame        *frame;
    PixmapRotator *rotator;
};

The RotateDialog class inherits from QDialog and contains 3 pushbuttons, a scrollbar, a frame and the custom made pixmap rotator. The dialog only has three member functions. The constructor initializes the different widgets in the dialog, resizeEvent sets the position and size of the widgets, and the slot updates the caption text of the dialog.

Let's take a look at the constructor:

RotateDialog::RotateDialog( QWidget *parent, const char *name )
        : QDialog( parent, name )
{
    frame = new QFrame( this, "frame" );
    frame->setFrameStyle( QFrame::WinPanel |
                          QFrame::Sunken );
    rotator = new PixmapRotator("this, rotator");
    rotator->raise();  // put it in front of frame
    quit = new QPushButton("Quit", this, "quit");
    quit->setFont(QFont("Times", 14,
                QFont::Bold));
    load = new QPushButton("Load", this, "load");
    load->setFont( quit->font() );
    print = new QPushButton("Print", this,
                        "print");
    print->setFont( quit->font() );
    scrollBar = new QScrollBar(QScrollBar::Horizontal,
                        this, "scrollBar" );
    scrollBar->setRange( -180, 180 );
    scrollBar->setSteps( 1, 10 );
    scrollBar->setValue( 0 );
    connect( quit, SIGNAL(clicked()), qApp,
                SLOT(quit()) );
    connect( load, SIGNAL(clicked()), rotator,
                SLOT(load()) );
    connect( print, SIGNAL(clicked()), rotator,
                SLOT(print()) );
    connect( scrollBar, SIGNAL(valueChanged(int)),
             rotator  , SLOT(setAngle(int)) );
    connect( rotator, SIGNAL(angleChanged(int)),
                SLOT(updateCaption()) );
    connect( rotator,
                SIGNAL(filePathChanged(const char *)),,
                SLOT(updateCaption()) );
    setMinimumSize( 200, 200 );
}

The different widgets have now been instantiated and initialized. We also want to put a frame around the pixmap rotator, so it is raised (popped to the front of the window stack) in order to make sure it is in front of the frame.

The scroll bar is set up to represent a value in the range [-180,180] with line and page steps set to 1 and 10 respectively. A line step is used when the user clicks on a scroll bar arrow, page step when the user clicks between the arrows and the scroll bar slider.

Then the different widgets are connected. The quit pushbutton is connected to the applications quit slot (qApp is a pointer to Qt's application object). The load and print pushbuttons are connected to their respective slots in the pixmap rotator, and the scrollbar is connected to the pixmap rotators angle value.

Next we connect the rotator's signals to the private slot updateCaption. We are here using a connect function that only takes three arguments, where the this pointer is implicit as the receiver. Note that the slot we connect to has fewer arguments than the signal. All or some of the last arguments of a signal can always be discarded in this way, if we are not interested in receiving them in a slot.

Note how we use the standard widgets to control our custom made widget. PixmapRotator is a new software component which can be plugged into many different standard interface controls. We could easily have added a menu in addition by plugging it into the rotator's slots. Keyboard accelerators or a text field, used to enter a numerical value for the angle, could likewise have been added without a single change to PixmapRotator.

Finally, we tell Qt that this widget should never be allowed to have a size smaller than 200x200 pixels. Note that the class does not have a destructor. Child widgets are always deleted by Qt when the parent is deleted.

There is no interactive dialog builder for Qt at the time of this writing (July 1996), but there is one in the works that will probably be ready by the time you read this article. Check Troll Tech's home page for details (http://www.troll.no/). The resize event is implemented as follows:

const int border     = 10;
const int spacing    = 10;
const int buttonH    = 25;
const int buttonW    = 50;
const int scrollBarH = 15;
void RotateDialog::resizeEvent( QResizeEvent * )
{
    quit->setGeometry(border, border, buttonW,
                        buttonH );
    load->setGeometry((width() - buttonW)/2,
                        border, buttonW, buttonH );
    print->setGeometry(width() - buttonW - border,
                        border, buttonW, buttonH );
    scrollBar->setGeometry( border,
                quit->y() + quit->height() + spacing,
                width() - border*2, scrollBarH );
    int frameTop = scrollBar->y() +
                scrollBar->height() + spacing;
                frame->setGeometry( border, frameTop,
                width() - border*2,
                height() - frameTop - border );
    rotator->setGeometry( frame->x() + 2,
                frame->y() + 2, frame->width() - 4,
                frame->height() - 4 );
}

Each widget is moved and resized according to the dialogs width and height. The three buttons are placed 10 pixels from the top of the dialog, one on each side and one in the middle. The scrollbar is placed right beneath them, followed by the frame. The rotator is put inside of the frame.

Writing code like the above is not difficult, but it's not always easy to read. A geometry manager solves resizing of dialogs in a more elegant way. Qt's geometry manager is currently under internal testing at Troll Tech and will soon be added to the toolkit. The slot is implemented like this:

void RotateDialog::updateCaption()
{
    QString s;
// we do not want the full path
    QFileInfo fi( rotator->filePath() );
    s = fi.fileName();          // only the filename
    if ( rotator->angle() != 0 ) {   // rotated?
        s += " rotated ";
        QString num;
// convert number to string
        num.setNum( rotator->angle() );
        s += num;
        s += "degrees";
    }
    setCaption( s );    // set dialog caption
}

We build a message string by using the image file name and its rotation angle. The string is then used as the dialog's caption.

See www.troll.no/qt for the full code. When run, the user can press on the load button and Qt's standard file dialog will pop up. If the print button is clicked, the standard print dialog pops up letting the user choose if the output should go to a file or to a printer. Under X, Qt generates postscript printer output; under Windows, the Windows printer driver system is used.

In Figure 3 you can see a screen shot of the RotateDialog together with the print dialog.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

GUI deveopment using QT

Anonymous's picture

i wanted to know as to how a GUI can be developed using QT with C++ program give an example .

linux

sowmya's picture

sir,
i am troubling about qt.i am begineer of linux.In my project i am doing in linux.for gui designing we use qt design.i not very well about qt:gui design and where we write code in qt,and how to complie in c++ coding.i am using fedora.pls give me steps for designing and coding... i am waiting..

White Paper
Linux Management with Red Hat Satellite: Measuring Business Impact and ROI

Linux has become a key foundation for supporting today's rapidly growing IT environments. Linux is being used to deploy business applications and databases, trading on its reputation as a low-cost operating environment. For many IT organizations, Linux is a mainstay for deploying Web servers and has evolved from handling basic file, print, and utility workloads to running mission-critical applications and databases, physically, virtually, and in the cloud. As Linux grows in importance in terms of value to the business, managing Linux environments to high standards of service quality — availability, security, and performance — becomes an essential requirement for business success.

Learn More

Sponsored by Red Hat

White Paper
Private PaaS for the Agile Enterprise

If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.

Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.

Learn More

Sponsored by ActiveState