Coding between Mouse and Keyboard, Part I

This article shows you how to create the GUI of a tiny text editor without being a C++ guru. In Part II, we'll add missing functionality and translate the program into languages other than English.
Adding Some Code

Closing a widget in Qt is easy: every Qt widget inherits a close() function from the mother of all Qt widgets, QWidget. This is not really much code, so it would be nice if we could fill the fileClose() slot with this one line.

A right-mouse click on the ljeditor form opens a context menu. The choice of its Source... entry does the trick. A code editor window appears and allows us to fill in the one-liner (see Figure 8):

void ljeditor::fileClose()

Figure 8. Simple code lines are easily added to the slot skeleton.

So why not fill the fileExit() slot as well? To quit the entire application, the application object's closeAllWindows() function is called:

void ljeditor::fileExit()

As the Designer usually does not deal with QApplication objects itself, qapplication.h (which provides the qApp proxy for the real application object) is not included by default, and the code generated from the ui description would not compile.

Fortunately, the Object Explorer allows us to include additional header files. By default it shows the Widgets tab (see Figure 4, bottom left), but we need the Source tab right now. Right-clicking the empty Includes (in Implementation) folder allows us to add a header file (New). Don't forget the <> brackets around a global include like <qapplication.h> (Figure 9).

Figure 9. The Object Explorer allows one to include additional header files.

Another slot we can fill with life without being afraid of getting too many compilation errors is helpAbout(). It is called when the user opens the About... entry in ljeditor's Help menu and simply pops up a message box with the caption About ljedit and some information about the program. By surrounding all text strings with tr() we make sure that the program can be localized painlessly, a task we will fulfill in Part II. For example:

void ljeditor::helpAbout()
    QMessageBox::about( this, tr( "About ljedit" ),
        tr( "A tiny text editor.\n"
        "(C) 2002 Patricia Jung for Linux Journal\n"
        "Using Qt 3.0.4 and Qt Designer." ) );

To be able to use QMessageBox::about(), we have to include <qmessagebox.h> the same way we did with <qapplication.h>. We add the remaining functionality in a subclass next time. Thus, all we have left to do with the Designer is clean up the new GUI.

Important Cosmetics

Before we leave the Designer for good, we check that none of the assigned keyboard shortcuts has been used twice. This is done by choosing Check Accelerators from the Edit menu.

Additionally, we clean up all the ljeditor slots that we weren't going to implement anyway or that we used TextEdit slots for instead. By choosing Slots from the Edit menu (one way to do it), we open the dialog that allows us to mark editUndo() and remove it with a mouse click on Delete Slots (Figure 7). The same fate applies to editRedo(), editCut(), editCopy(), editPaste(), editFind(), helpIndex(), helpContents() and filePrint().

Furthermore, we check the GUI preview for separators that don't fit. As we decided against using the editFindAction, a single separator can be found at the end of ljeditor's Edit menu: once upon a time there was a Find entry below. To erase the separator, right-click on it in the form and choose Delete Item. The same applies to one of the two separators above the Exit entry in the file menu.

All GUI elements are in their place—time to let Qt adjust the widget proportions. Once again, we choose the entire form and select Lay Out Vertically from Layout in the main menu. If a user adjusts the application window size now, the TextEdit widget will follow. If we wish to place widget elements differently onto the form, we need to break the layout first.

Last but not least, we want this GUI to be stamped as ours. To do this we fill in the Author name and a description in the dialog raised by choosing Form Settings from the Edit menu (see Figure 10). Here it is possible to decide whether we want to store the icons in a subdirectory of our project directory or whether we include them directly in the user-interface description.

Figure 10. Let the world know who designed this GUI.

A final selection of Save all from the File menu and an XML file with the user-interface description (best named after the relevant class, e.g., ljeditor.ui) along with ljeditor.ui.h, the file storing the code we typed into the code editor, becomes part of the project.

Patricia Jung ( has a background as a system administrator, technical writer and editor, and as such is happy to have the privilege of dealing with Linux/UNIX exclusively.