Designing User Interfaces

Before we can begin we must start Qt Designer. On Linux, run designer & in a console (assuming it is in your path), or invoke it from your menu system. On Windows XP, click Start^Qt by Trolltech^Designer, and on Mac OS X launch it using Finder. Qt Designer starts with a New Form dialog; click Dialog with Buttons Bottom and then click Create. This will create a new form with a caption of "untitled", and with the QDialogButtonBox as shown in Figure 7.2.

Tkinter Dialog Example
Figure 7.2 A dialog with buttons bottom dialog

When Qt Designer is run for the first time it defaults to "Multiple Top-Level Windows" mode—this can be confusing, except for Mac OS X users for whom this approach is the norm. To get everything in one window as shown in Fig ure 7.1, click Edit^User Interface Mode^Docked Window.* Qt Designer will remember this setting, so it needs to be done only once.

Qt Designer is not difficult to use, but it does take some initial practice. One thing that helps is to do things in a particular order, as shown in the following list of steps. For steps 1 and 2, always work from "back" to "front", that is, always start with containers (group boxes, tab widgets, frames), and then go on to the normal widgets that belong inside, that is, on top of them. We will go through an example step-by-step in a moment, but first here is a general description of how to create a dialog using Qt Designer.

1. Drag a widget onto the form and place it in approximately the right position; there is no need to place it exactly, and normally only container widgets need to be resized.

2. Set the widget's properties if necessary; if the widget will be referred to in code, at least give it a sensible name.

3. Repeat steps 1 and 2 until all the required widgets are on the form.

4. If there are large gaps, drag in horizontal or vertical spacers (these appear as blue springs) to fill them; sometimes, when gaps are obvious, spacers are added during steps 1 and 2.

5. Select two or more widgets (or spacers or layouts) to be laid out (Shift+Click each one), and then lay them out using a layout manager or a splitter.

6. Repeat step 5 until all the widgets and spacers are in layouts.

7. Click the form (to deselect everything) and lay out the form by using one of the layout managers.

8. Create buddies for the form's labels.

9. Set the form's tab order if the order is wrong.

10. Create signal-slot connections between built-in signals and slots where appropriate.

11. Preview the form and check that everything works as intended.

12. Set the form's object name (this is used in its class name), and the form's title, and save it so that it has a filename. For example, if the object name is "PaymentDlg", we would probably give it a title of "Payment" and a filename of paymentdlg.ui.

If the layout is wrong, use undo to go back to where you think you could start laying things out again, and have another go. If that is not possible or does not work, or if the layout is being changed some time after it was originally created, simply break the layouts that need changing and then redo them. Usually, it is necessary to break the form's layout (click the form, then the Break

★From Qt 4.3 this option is available by clicking Edit^Preferences.

Layout toolbar button) before changing the layouts within the form; so at the end the form itself must be laid out again.

Although it is possible to drag layouts onto the form and then drag widgets into the layouts, the best practice is to drag all the widgets and spacers onto the form, and then repeatedly select some widgets and spacers and apply layouts to them. The one situation where it makes sense to add widgets to an existing layout is if we want to drag widgets into gaps—for example, into empty cells in a grid layout.

Now that we have the overall principles in mind, we will go step by step through the design of the Find and Replace dialog shown in Figure 7.3.

H Find and Replace


1 1

Find what: | coincidence! Replace with: Q

Find Replace | Replace All |

1 I Case sensitive 0 Whole words

Syntax: Literal text


Figure 7.3 A Find and Replace dialog

Figure 7.3 A Find and Replace dialog

Create a new form based on one of the "Dialog" templates. This will give us a form with a button box. The button box has two buttons, OK and Cancel, with signal-slot connections already set up.

Click the button box and then click Edit^Delete. This will leave us with a completely blank form. For this example we will use QPushButtons instead of a QDialogButtonBox. This will allow us to exercise finer control than can be achieved using a QDialogButtonBox inside Qt Designer, and gives us the chance to do signal-slot button connections in Qt Designer. In most of the other examples, and in the exercise, we use a QDialogButtonBox.

By default, Qt Designer has a dock window on the left called Widget Box. This contains all the widgets that Qt Designer can handle. The widgets are grouped into sections, and toward the end is a group called Display Widgets; this contains the Label widget. (Qt Designer does not use class names for its widgets, at least not in the user interface it presents to us, but in almost every case it is obvious which class a particular name refers to.)

Click and drag a Label onto the form, toward the top left. We don't care what this label is called because we will not refer to it in code, but the default text of "TextLabel" is not what we want. When a widget is first dragged and dropped it is automatically selected, and the selected widget is always the one whose properties are shown in the property editor. Go to the Property Editor dock window (normally on the right), and scroll down to the "text" property. Change this to "Find &what:". It does not matter that the text now appears to be truncated on the form; once the label is laid out the layout manager will make sure that the text is displayed in full.

Now drag a Line Edit (from the Input Widgets group), and put this to the right of the Label. Go to the property editor and change the Line Edit's "objectName" (the very first property of all widgets) to "findLineEdit". We are giving it a sensible name because we want to refer to this line edit in our code.

Now drag another Label and another Line Edit below the first two. The second Label should have the text "Replace w&ith" and the second Line Edit should be called "replaceLineEdit". The form should now look very similar to Figure 7.4.

Multiple Form Pyqt
Figure 7.4 Two Labels and two Line Edits

At any time we can save the form by pressing Ctrl+S or File^Save. When we save we will use the filename, findandreplacedlg.ui.

Every editable property (and some read-only properties) are shown in the property editor. But in addition, Qt Designer provides a context menu. The first option in the context menu is normally one that allows us to change the widget's most "important" property (e.g., a Label's or a Line Edit's "text" property), and a second option that allows us to change the widget's object name. If we change a checkbox, radio button, or push button's text using the context menu, the editing is done in-place, in which case we must press Enter to finish. We will always talk of changing properties in the property editor, but you can, of course, use the context menu if you prefer.

We will now add the two checkboxes. Drag a Check Box from the Buttons group (near the top of the Widget Box) and put it underneath the second Label. Change its object name to "caseCheckBox" and its text to "&Case sensitive", by using the property editor or the context menu. Drag a second Check Box to the right of the first: Change its object name to "wholeCheckBox" and its text to "Wh&ole words", and set its "checked" state to "true". The form should now be similar to the one shown in Figure 7.5.

EV Dialog - untitled*

Find &wh<.

Replace v.

1 1 Case sensi Jzi Whoje woP

Figure 7.5 Two Labels, two Line Edits, and two Checkboxes

Figure 7.5 Two Labels, two Line Edits, and two Checkboxes

Now we will add the Syntax label and combobox. Drag a Label below the case-sensitive checkbox and set its text to "&Syntax:". Now drag a Combo Box (from the Input Widgets group) to the right of the Syntax Label. Change the Combo Box's object name to "syntaxComboBox". Right-click the Combo Box and choose the first menu option, Edit Items. Click the "+" icon, and type in "Literal text". Repeat this to add "Regular expression". Click the OK button to finish.

If the user resizes the form we want the widgets to stay neatly together rather than spreading out, so drag a Vertical Spacer (from the Spacers group near the top of the Widget Box) and put it below the Combo Box. When we design forms using code we use stretches, but when we design them visually we use spacers: They both expand to fill empty space. Adding a stretch to a layout is essentially the same as inserting a QSpacerltem into a layout, but is less to type.

To make the buttons visually separate from the widgets we have just created, we will put a vertical line between them and the other widgets. Drag a Vertical Line (actually a QFrame with shape QFrame.VLine) from the Display Widgets group (near the bottom of the Widget Box) and put it to the right of all the widgets in the form, but leaving space to the right of it for the buttons. Now the form should look like Figure 7.6.

We are now ready to create the buttons. Drag a Push Button (from the Buttons group near the top of the Widget Box) to the top right of the form. Change its object name to "findButton" and its text to "&Find". Drag another button beneath the Find button, and give it the object name "replaceButton" and set its text to be "&Replace". Create a third button, below the Replace button. Give it an object name of "replaceAllButton" and change its text to "Replace &All". Now drag a Vertical Spacer under the Replace All button. Finally, drag a fourth button below the spacer. Give this button the object name "closeButton" and change its text to "Close".

Now we have all the widgets and spacers we need and we have set all their properties appropriately. The form should look like that shown in Figure 7.7.

Figure 7.6 A Find and Replace dialog without buttons

P/ Dialog - untitled*



1 Find &.wh<





1 1 Case sensi

1 1 Whole wor

; :

Replace All


Literal te* v

. £ ... .




Figure 7.7 A Find and Replace dialog that is not laid out

Figure 7.7 A Find and Replace dialog that is not laid out

What is the best way to lay out this form? What is the best design for this form? The answers to these questions are matters of taste and practice. Here, we simply show the mechanics, and leave the aesthetics to you.

We will begin by laying out the first two Labels and their Line Edits. Click the form to deselect everything, then Shift+Click the Find what Label and its Line Edit, and the Replace with Label and its Line Edit. Once these four widgets are selected, click Form^Lay Out in a Grid (or click the corresponding toolbar button). The layout is indicated by a red line—layout lines are not visible at runtime.

Now deselect everything (by clicking the form), and select the two Check Boxes. Click Form^Lay Out Horizontally. Again, deselect everything, and this time lay out the Syntax Label and Combo Box using a horizontal layout. There should now be three layouts—a grid and two horizontal layouts, like those shown in Figure 7.8.

We can now lay out the layouts on the left-hand side of the form. Click the form to deselect everything. It can be tricky to select layouts (rather than widgets), so instead of selecting by using Shift+Click, we will use a selection rectangle. Click near the bottom left of the form, and drag the selection rectangle: This

Pyqt4 Pushbutton
Figure 7.8 A Find and Replace dialog with some layouts

rectangle only needs to touch an object to select it, so drag up and right so that it touches the left-hand Vertical Spacer and the three layouts—and nothing else (not the Vertical Line, for example). Now, release and click Form^Lay Out Vertically.

We can use the same selection technique to lay out the buttons. Click the form to deselect everything. Now click near the bottom right of the form and drag so that the selection rectangle touches the Close button, the right-hand Vertical Spacer, and the other three buttons—and nothing else. Now, release and click Form^Lay Out Vertically. We should now have a form with every widget in the left- or right-hand layout and a Vertical Line in the middle, as shown in Figure 7.9.

Figure 7.9 A Find and Replace dialog almost laid out

We are now ready to lay out the form itself. Deselect everything by clicking the form. Now click Form^Lay Out Horizontally. The form will now look a bit too tall, so just drag the bottom of the form up until the form looks better. If you drag a lot, the spacers may "disappear"; they are still there, but just too small to be seen.

We can now preview the form to see what the layout really looks like, and during the preview we can drag the form's corner to make it smaller and larger to check that its resizing behavior is sensible. To preview, click Form—Preview (or press Ctrl+R). It is also possible to preview in different styles using the Form—Preview in menu option. The form should now look like the one in Figure 7.10. If this is not the case, use Edit—Undo to unwind your changes, and then lay things out again. If you have to redo a layout, it sometimes helps to resize and reposition some of the widgets to give Qt Designer more of a clue about how you want the layout to go, especially when using grid layouts.

Pyqt Layout Widget Best Practice
Figure 7.10 A laid out Find and Replace dialog

We are now ready to set the labels' buddies, set the form's tab order, do any connections we need, and name and save the form.

We will start with buddies. Click Edit—>Edit Buddies to switch on buddy mode. To set up buddy relationships we click a Label and drag to the widget we want to be its buddy. So in this example, we must click the Find what Label and drag to its Line Edit, and then do the same for the Replace with Label and its Line Edit, and then for the Syntax Label and the Combo Box. To leave buddy mode, press F3. Now, no ampersands (&) should be visible in the Labels.

Next we will set the form's tab order. Click Edit—Edit Tab Order, and then click each numbered box in turn, in the tab order that you want. To leave tab order mode, press F3.

The Find, Replace, and Replace All buttons will need to be connected to our own custom methods; we will do this outside of Qt Designer. But the Close button can be connected to the dialog's reject() slot. To do this, click Edit—Edit Signals/Slots, and then drag from the Close button to the form. When you release, the Configure Connection dialog will pop up. Click the (no-argument) clicked() signal from the list of signals on the left, and the reject() slot from the list of slots on the right, and then click OK. To leave signal-slot mode, press F3.

Click the form to deselect everything. This also has the effect of making the property editor show the form's properties. Set the dialog's object name (which will be used in its class name) to "FindAndReplaceDlg", and set the "windowTitle" property to "Find and Replace". Now click File—Save to save the user interface, giving it a filename of findandreplacedlg.ui.

In this section, we have confined ourselves to using Qt Designer to create a custom dialog using one of the "Dialog" templates, since this is sufficient to learn the basics of how to use Qt Designer. However, Qt Designer can be used to create much more complex dialogs than the one we have created here, including dialogs with tab widgets and widget stacks that are often used for configuration dialogs that have dozens or even scores of options. It is also possible to extend Qt Designer with plug-ins that contain custom widgets. These widgets are normally written in C++, but from PyQt 4.2, it is also possible to incorporate custom widgets written in Python.

The Qt documentation includes a comprehensive Qt Designer manual that goes into more depth and covers more of the facilities available. The material covered in this section is sufficient to get started, but the only way to learn Qt Designer properly is to use it.

Having designed a user interface, the next step is to make it usable in our code.

Was this article helpful?

+4 0
Tube Traffic Ninja

Tube Traffic Ninja

Discover How You Can Quickly And Easily Dominate Google and YouTube... With Simple Cash Generating Videos. Did you know that YouTube is the second largest search website on the entire Internet? YouTube gets more daily searches than Bing and Yahoo. In fact, there is only one search engine that gets more action.

Get My Free Ebook


  • grace clabaugh
    How to add a push button in pyqt 4?
    8 years ago
  • abdul
    What do spacers do PyQt4?
    8 years ago
  • Poppy
    How to connect button and checkbox pyqt4?
    7 years ago
  • Rodolfo
    What do spacers do pyqt]?
    7 years ago

Post a comment