Making it Work
So, the last time around, we had a look at the template application generated by QtCreator. This time I promised that it would do something. All this starts in the designer view of QtCreator (you get there by double clicking on mainwindow.ui). Lets go through the different parts of the window one by one, just so that you get a grip of what’s going on.
The widget list is where all the available widgets are shown. It can be shown in two modes – list mode and icon mode. I prefer the icon mode (used in the picture) but the list mode can be better when you are getting started. Simply right click to get a menu where you can change the mode. To add a widget to your form, simply drag from here and drop it where you want it.
The properties shows the settings for the current widget. Try selecting a widget in your form, or even the form it-self, and you get a whole bunch of properties that you can tweak here.
The object hierarcy shows how everything relates to each other. For instance, all widgets will be placed within your QMainWindow instance (called MainWindowClass). If you use group boxes or tabbed interfaces, you will see that your widgets are placed in a hierarcy tree here.
The action list contains actions, which is a special class, making it possible to use the same object in a toolbar, menubar and keyboard short-cuts. This is really convenient when building classic desktop applications.
The Designer toolbar is simply the toolbar beloning to the Designer, which is the tool that you are using when editing .ui files. Here, you can change between the working modes of designer (edit, connections, buddies and tab order), as well as applying and breaking up layouts.
Encircled by all these docked lists and toolbars is your form, the main window, dialog or widget that you actually are designing. In this case, we are working with a main window.
What is the difference between a widget, dialog and main window then? Everything visible on screen is a widget. This includes buttons, labels, group boxes as well as top-level windows. So what does a dialog or a main window bring in addition to this? The dialog can be used in a modal (that is blocking) way, i.e. you show the dialog and wait for a result. A main window can be used to dock windows into, can have a tool bar, menu bar and a status bar. Then the question – when do I create a widget then? You can either create it to join together a set of widgets and use them to populate dialogs, main windows and other widgets, or you can use a widget as a base for a simple window, where you don’t need the extra bells and whistles of the main window.
So, the goal of today is to get the application to actually do something. We will split this into two sub-goals: run some code of our own and to make a connection to one of Qt’s slots. The first step to achieve this is to add some actions for the user to use to trigger our application.
In the menu bar of the form it says “Type Here”. Double click at the text and write “File”. This lets you open the menu and type more. Create two entries – “Exit” and “Hello Qt”. Each of these entries will appear as actions in the action list. There you can associate them with keyboard short-cuts and change texts and icons (icons requires resources, which we have not looked at yet, so just skip that part for now).
For the actionHello_Qt action, right click and select Go to slot…. A list of signals now appears. Pick triggered() from that list. This will bring you to mainwindow.cpp, in a method called on_actionHello_Qt_triggered. This method will be executed when the user triggers the action.
In the slot, we simply change the title of the window to read “Hello Qt!” using the code below. Now, try building your application and run it. Choosing the “Hello Qt” menu entry will change the title of the window. So, mission accomplished, the application now does something.
void MainWindow::on_actionHello_Qt_triggered()
{
setWindowTitle( tr("Hello Qt!") );
}
Why did we just put the string in a the tr function? This has to do with the internationalizations tools that Qt provides. We will look at this at a later point, for now, just try to keep in mind that all strings that are shown to the users should be enclosed in a tr-call.
The actionHello_Qt’s triggered signal was automatically connected to the slot that we provided. This might be conventient in many situations, but I prefer to give my slots names from what they do, not what they are connected to. This not only makes the code more readable, it also allows me to re-use the same slot for several signals.
In order to be able to do this, one must make the connections manually and this is what I intend to do for the actionExit. Looking at the constructor below, we find all user interface elements defined using Designer through the ui member variable. Before the elements of the ui variable are valid, we must call the setupUi function. Just after that call is the natural place to make manual connections as well as populating and initializing a user interface.
In this case we connect the triggered() signal from the actionExit user interface element to the close slot of this, i.e. the window. This simply means that when the user activates the exit action, the window will close, thus exiting the application. As the close slot is called close and not on_actionExit_triggered, we must make the connection manually. Naming the slot close not only forces us to make a manual connection, it also makes the use of the slot more clear – especially when called from within other code as an ordinary member function.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
connect( ui->actionExit, SIGNAL(triggered()), this, SLOT(close()) );
}
This concludes the activities for today. Next time I plan to look more in depth at signals and slots.
This entry was posted on Thursday, April 9th, 2009 at 10:23 and is filed under Tutorial. You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.
Leave a Reply
You must be logged in to post a comment.


