Ralph Corbett, M.S.

Web DesignerSoftware Engineer




My

Master's Degree Project

Qt Creator Documentation

A TiddlySpace


Was located at: http://rcorbett.tiddlyspace.com/
R.I.P.


Here is the HTML version.   Same content.

Menu




The purpose of this project is to make the documentation of the most commonly used features of the GUI program Qt easier to read and code.

Qt’s own documentation, found at Qt Documentation, is very detailed. So detailed that is difficult to find the code needed to make Qt preform some basic functions. Functions like mouse over, getting the Enter key from keyboards, mouse clicks, and hyperlinks. This will be an easy to read and preform documentation project using IDT techniques and theories.

Qt writes for the Computer Scientist who knows all the jargon of computers. This is an excellent toolkit to create GUI programs; however, the documentation was not written for the layman.

Most of Qt’s documentation will only list the function header. The code to make it work is up to the software developer to discover on their own. This is a poor method of instruction especially for such an outstanding product.

Each chapter will show the original documentation from Qt’s website, followed by easier to follow documentation I have created from both research and my own trial-and-error usage.

There will be easy to follow code, which can be cut-and-paste-ed into Qt Creator, and live interaction spaces showing the lines of code which are being activated as the user clicks the various widgets.

Project layout


Creating the tiddlers was a 3 step process.
For each tiddler:

  • Gather the data for the Qt Creator tutorial – how it functions and its code

  • Create the interactive windows on a separate webpage

  • Develop the tiddler with the data sorted, organized into a meaningful structure including hypertext reading, writing, and tagging, and have the interactive window(s) iframe’d in as a separate embedded tiddler.



This is for version Qt Creator 2.0.1 released August 2010


About Qt Creator

Theories used

Icon Representation

I have used Icon Representation on the TopMenu, Main Menu, and the tiddlers. Inside each tiddler is an img tag with position elements to place both the icon and a small white jpeg square, to cover up parts of the tiddler, in the top-left corner.

The meanings of icons as written by Sturken, and Cartwright (2009) is an "image that regress to something outside of its individual components, something, or someone, that has great symbolic meaning for many people. Icons are often perceived to represent universal concepts, emotions, and meanings"(p. 36). It was found that words and pictures are stronger together than separate (Sturken, and Cartwright, 2009, p. 33)

Color Theory

Qt’s coding forms have a very colorful layout. When a programmer types in a key word correctly, it will change color. Different colors for different categories of keywords.

The class highlighting in blue was added to each form.

The blue highlighting on each .h and .cpp form was added by myself to help the viewer understand which form the tutorial was currently on.

I have taken screen captures of the Qt coding area, placed them on Photoshop CS5, and used the Eyedropper Tool for an exact color hex number. These are the numbers for further reference:

#000099 – Blue for #include.
#009900 – Green for libraries, comments, strings/text.
#990099 – Purple for Qt Classes QString, QTableWidget, QLabel, QMainWindow, QEvent.
#999900 – Yellow for signals/slots, private/public/protected, bool, new, this, void.

It seems the people who created Qt enjoy the 9 and the 0 in their colors.

I have kept this color coding to make it easier for the novice programmer to follow along. They will see the colored text in this tutorial, and match it on their Qt coding area, making an easier transfer of knowledge.

Consistency

If a key word in the Qt coding area has a certain color, the color in the text describing it will be that same color. Code to copy from this tutorial to a Qt coding area, will be in color and bold. The design principle of consistency is being employed so each tiddler will have this same color representation in the text and code examples.

This design principle was written about by Lidwell, Holden and Butler (2010) as "systems are more usable and learnable when similar parts are expressed in similar ways. Consistency enables people to efficiency transfer knowledge to new contexts, learn new things quickly, and focus attention on the relevant aspects of a task." (p. 56).

Highlighting

Another design principle used is highlighting. Bold is used in this category, and Lidwell, Holden and Butler (2010) write that "bolding is generally preferred over other techniques as it adds minimal noise to the design and clearly highlights target elements" (p. 126). Bolding is use to enhance code to type-in with the exception of Capturing Keyboard Keystrokes as there is so much code, it would be distracting for the viewer.

Simulations

Interactive windows behave as a simulator, and are a separate embedded tiddler. These tiddlers will show what happens if the code is either applied or not.

Simulators are a reflection of a real-world process or event at a fraction of the cost. They come in two categories, the about and the how to do. As Alessi and Trollip (2001) write, the about something category will be a teaching tool, so students can learn what a things is, while the how to do will teach the step-by-step methods on various operations (p. 214). This project involves both categories.

Sense-Making Triangle

Dervin writes about Sense-Making as a triangle to represent information problems (Jacobson, 2000, p. 46). This triangle has the components of situation, bridge/gap, and outcome. The Situation is where the person is at the point the problem arose, while gap is the difference between what is actually happening and what is desired to happen (Jacobson, 2000, p. 47). Outcome is what will happen after a decision is made, and finally is bridge, which is the means of closing the gap between situation and outcome (Jacobson, 2000, p. 47).



For this project, the situation is a young programmer is trying to get Qt to perform some basic program functions and cannot understand the technical documentation. The gap is wanting their program to preform like every other program (mouse clicks/mouseover, hypertext, Enter key) vs. not being able to get it to do anything. The bridge is having the technical documentation be written for the layman, making it so easy anybody can follow it. The outcome is having their program being able to receive inputs from the user.

Organization by category

The sections presented in this project are organized by category. As Jacobson (2000) writes, categories "are grouped together according to some important attribute. The specific categories however, are crucial as they communicate more easily that other organizations the designer's prejudices and understandings" (p. 277).

The continuum of understanding

The steps of the continuum of understanding progress from data, information, knowledge, and then to wisdom (Jacobson, 2000, p. 272).
The continuum of understanding

The new programmer has a basic understanding of coding, but lacks the Qt knowledge to create the specific code for the Qt environment. They are at a loss at step 1, data, in the continuum of understanding. This tutorial will take step 3, knowledge, and scale it down so the beginning programmer can go through the steps of data, information, and then achieve knowledge without merely being "spoon-fed" the code.

The low cannot reach up to the high levels of understanding; the high must be scaled down to the low.

Hypertext

This tutorial is using the theories of hypertext reading, writing, and tagging. Larger tutorials are broken down into many smaller tiddlers, which is the purpose of a tiddlyspace:

Contact

I can be reached at: ralph@ralphcorbett.com
WebSites: www.Extreme-Typing.com
www.RalphCorbett.com
www.Word-Shadows.com
TiddlySpace Interactive Resume


To Top


Mouseclick


Mouse clicks are the corner stone of human-computer interaction. It is the primary method of inputting commands into the software. Qt has inputs for the mouse. QT Documentation - mousePressEvent.
The mousePressEvent is at the lower part of the page. This is how it reads:


QT Documentation - mousePressEvent - image

What this means is, especially the part inside the blue box, if you want the mouse click to activate a widget, then there needs to be an IF statement inside this function to tell the program to ignore everything else except the widget named inside the IF statement.

Without the IF statement, then clicking anywhere on the window’s widgets or background will active the code you are wishing to execute. Clicking the background to start playing a song is not a normal function. That is reserved for the Play button.

Just the QT documentation looks like this. This will change the label’s color no matter what a user clicks.

void className::mousePressEvent( QMouseEvent *event )
{
ui->label->setStyleSheet("color: blue; font-size: 12pt;");
}

Interactive window

This will demonstrate the non-selective nature of having just the header.
We only want the yellow box with the QLabel to have its text changed to blue when it is clicked with the mouse.
Instead we get any area clicked to make this change.

What to do:

  • Place mouse anywhere over the thickly bordered box.
  • Click the left mouse button.
  • Note the QLabel's text changed to blue.
  • Follow the code below to the right.
  • Click the Reset button.

Interactive window. The mouse click is not selective as the *event in the header cannot find a match below in the function. The entire window is treated as one giant widget.



The added IF statement looks like this:


void className::mousePressEvent( QMouseEvent *event )
{
if(    event->button() == Qt::LeftButton && ui->label->underMouse()   )
{
ui->label->setStyleSheet( "color: blue; font-size: 12pt;");
}
}



Interactive window


This will demonstrate the selective nature of including an IF statement.

As before, we only want the yellow box with the QLabel to have its text changed to blue when it is clicked with the mouse. Now things are different. The If with another *event makes things more precise.

What to do:

  • Place mouse anywhere over the thickly bordered box.
  • Click the left mouse button.
  • Notice how nothing happens.
  • Now place the mouse anywhere over the yellow colored QLabel.
  • Click the left mouse button.
  • Note the QLabel's text changed to blue.
  • Follow the code to the right.
  • Click the Reset button.


Interactive window. The *event in the header finds a match in the function's IF statement. The mouse click is more selective.

The name of the widget to be accessed is at the end of the IF statement.

Now the entire window is ignored unless the widget named is under the mouse ( underMouse() ). (Try finding that in QT's documentation.)

Other mouse buttons can be accessed, and mouse-click up can be used also. Use these:

  1. Left Button - Qt::LeftButton
  2. Right Button - Qt::RightButton
  3. Middle Button - Qt::MiddleButton


  4. Mouse click down - mousePressEvent
  5. Mouse click up - mouseReleaseEvent


This does not work with QPushButton. This widget has its own mouse clicking functions built into it.


The Code

The library needed is #include < QMouseEvent >
If using the entire < QtGui > library, this is included inside it, and does not need to be included separately.

In the .h file, under protected:, add the following so it looks like this:

protected:
virtual void mousePressEvent( QMouseEvent * ); // for mouse down
virtual void mouseReleaseEvent( QMouseEvent * ); // for mouse up



In the .cpp file add this anywhere below the constructor:

void className::mousePressEvent( QMouseEvent *event )
{
if(event->button() == Qt::LeftButton && ui->label->underMouse() )
{
ui->label->setStyleSheet( "color: blue; font-size: 12px");
// qDebug("mouse down test 1");
}
// Other widget's code
}



For mouse up code, just change mouse PressEvent to mouseReleaseEvent.
void className::mouseReleaseEvent( QMouseEvent *event )
{
if(event->button() == Qt::LeftButton && ui->label->underMouse() )
{
ui->label->setStyleSheet( "color: black; font-size: 12px");
// qDebug("mouse up test 1");
}
// Other widget's code
}

To Top


Mouse over / mouse out

These are another of the most basic human-computer interactions. Qt calls these events, and they require filtering out with a process called Event Filters.

When an Event Filter is applied, the program will seek and find the event the programmer as identified as important. It will filter the event out from all the others and will perform the code the programmer has created.

This breaks down into two parts. What is the object, widget, to be affected (the noun), and what is the event (the verb). What we want, is for Qt to preform Mouse Over and Mouse Out. Qt calls these events Qt::Enter and Qt::Leave.

This is the function header:
bool className::eventFilter(QObject* object, QEvent* event )

It is very basic, as many events can be done inside it. Capturing keyboard key strokes can be done here also. Our focus is on getting the mouse to identify a widget.

The library to add is:

#include < QObject >

.h file

protected:
bool eventFilter(QObject* obj, QEvent* e);

.cpp file
add this anywhere under the constructor.

bool className::eventFilter(QObject* obj, QEvent* e)
{
if(obj == ui->labelDisplay)
{
if(e->type() == QEvent::Enter)
{
ui->startButton->setStyleSheet( "color: red; font-size: 12pt;");
}

if(e->type() == QEvent::Leave)
{
ui->startButton->setStyleSheet( "color: black; font-size: 12pt;");
}

}
return false;
}


The first IF statement is identifying the widget. Any events connected to this widget will be place here.

In this case there is a QLabel named labelDisplay to be singled out for an application. The two IF statements inside this are events for entering and leaving the label.

Mouse over is QEvent::Enter
Mouse out is QEvent::Leave

The QPushButton will have its text color changed from black to blue with the setStyleSheet code.

Here is an example showing the code in action. It is greatly slowed down for analysis.

Interactive window

This will demonstrate the eventFilter for mouseover and mouseout, showing the code in action.

What to do:

  • Mouseover anywhere in the center box labled QLabel.
  • Watch the code to the right.
  • Note the QPushButton's text changed to blue.
  • Mouseout of the box labeled QLabel.
  • Watch the code to the right.
  • Note the QPushButton's text changed to black.
  • Click the Reset button.

Interactive window 1. Event Filters can be done for many types of entry: Key Strokes, mouse clicks, accepting and ignoring them.



Many widgets can be affected in this function.

Very Important

The last part is very important, or nothing will work. The widget needs to be told an event will be coming its way, and it should respond to it. An installEventFilter(this) needs to be added.

In the .cpp file, add this in the constructor:

ui->labelDisplay->installEventFilter( this);

An installEventFilter(this) needs to be added for every widget to be effected by the program having an Event Filter applied to it.


To Top


Debugging with qDebug()

JavaScript calls it alert("..."). That little box that pops up on the Internet asking if you really want to leave a webpage, also helps JavaScript software coders find troublesome code. QT has something like this, only the messages appear at the bottom of the output console while writing the program.

This is a little talked about aid in writing code. When the code reaches this device, it will sound off at the bottom of the Qt Creator console with what ever message or variable the coder wants.

This is what the little bugger looks like: qDebug();
It requires the library < QtDebug >, and is part of < QtGui >. Use it like this:

.h file
#include < QtDebug>

This is how to use it with a variable QStringList sl;

  • qDebug("Code Test");
  • qDebug() << "Code Test";
  • qDebug() << "String List 1" << sl;
  • qDebug() << sl;

Messages can be put inside it.
Messages can be put outside it.
Variables can be seen with a description of it.
Or just the variable alone.



This will not work:

  • qDebug("String List 1") << sl; Mixing the two, inside and outside, will not work.



qDebug() can see the contents of an array or other container.

Figure 1 below shows a QStringList being populated with users of a chat room. Separate messages are added for more clarity of what the variable is.


Figure 1. Contents of a QStringList with messages.

Test to see if the IF statement is working

Interactive window

This will demonstrate the qDebug() is operation. At the end of each IF statement is a qDebug() with a message custom for each IF.



What to do:
  • Place cursor over QLabel
  • Click and hold the left mouse button down.
  • Watch the QPushButton's text color change to blue.
  • Follow the qDebug() output, to the right of the code, in the Application Output box.
  • Release the mouse button.
  • Watch the QPushButton's text color return to black.
  • Follow the Application Output box.
  • Click the Reset button.


When the qDebug() is displaying messages, the code is working up to that point.

IF not working


Interactive window

This will demonstrate the qDebug() is operation. At the end of each IF statement is a qDebug() with a message custom for each IF.

What to do:

  • Place cursor over QLabel
  • Click and hold the left mouse button down.
  • Note the illogical of the second IF.
  • No qDebug() output for MousePressEvent, as the code never reaches it.
  • Release the mouse button.
  • Note the output in the Application Output box.
  • Click the Reset button.



  • The second IF in the MousePressEvent function has a faulty condition. The addition of 2 and 2 will never equal 5, meaning the qDebug() will not sound off. This is how the qDebug() is very useful in finding difficult code.


    To Top


    Capturing Keyboard Keystrokes

    Sometimes a program requires a specific keyboard character or key to be captured. The Enter key is the most common.

    The codes will only acknowledge the key has been pressed and received by the Qt program. They will not preform the designated function of the key. The code for the Backspace key is Key_Backspace. Just typing this in will not move the cursor back one space. That would be up to the programmer to supply that coding.

    Most of the key codes are named after the symbol or key’s wording, with the exception of the caret ^. Qt was developed in Finland, and in this country this is called an AsciiCircum. (I’d hate to see how they spell or pronounce: tomato.)

    Examples:

    A is Qt::Key_A
    B is Qt::Key_B
    C is Qt::Key_C


    Number 1 is Qt::Key_1
    Number 2 is Qt::Key_2
    Number 3 is Qt::Key_3
    ...and so on.

    It requires the library < QKeyEvent >, and is part of < QtGui >. Use it like this:

    #include < QKeyEvent >

    .h file

    protected:
    virtual void keyPressEvent(QKeyEvent *event);

    .cpp file

    void className::keyPressEvent(QKeyEvent *event)
    {
    . . .
    }


    Return vs. Enter


    The most common keyboard capture is the Enter key. This is also listed on the number pad.
    For Qt coding, the Return is the key next to right pinky. Enter is part of the number pad.
    Here is the code to distinguish the two:

    void className::keyPressEvent(QKeyEvent *event)
    {

    switch(event->key())
    {

    //Key next to right pinky.
    case Qt::Key_Return: ui->display->setText("Return Key Entered");
    break;

    //Key next to number pad.
    case Qt::Key_Enter: ui->display->setText("Enter Key Entered");
    break;

    }
    }

    ABC's and Numbers

    The numbers will access both the number line and the number pad

    void className::keyPressEvent(QKeyEvent *event)
    {

    switch(event->key())
    {

    //ABC's
    case Qt::Key_A: ui->display->setText("A");
    break;
    case Qt::Key_B: ui->display->setText("B");
    break;

    //Numbers
    case Qt::Key_1: ui->display->setText("1");
    break;
    case Qt::Key_2: ui->display->setText("2");
    break;

    }
    }


    Special characters

    These are both above the number line and scattered around the keyboard. These codes have the Shift key built into it. After the user hits the Shift + 2, the @ will then be displayed. The mathematical symbols,   / ,   * ,   - ,   + ,   will also access the number pad.
     

    void className::keyPressEvent(QKeyEvent *event)
    {

    switch(event->key())
    {

    //Special characters above number line
    case Qt::Key_Exclam: ui->display->setText(" ! ");
    break;
    case ;Qt::Key_At: ui->display->setText(" @ ");
    break;
    case ;Qt::Key_NumberSign: ui->display->setText(" # ");
    break;

    // This will access the * on the number pad.
    case Qt::Key_Asterisk: ui->display->setText(" * ");
    break;

    //Right hand keys
    case Qt::Key_Less: ui->display->setText(" < ");
    break;
    case Qt::Key_Comma: ui->display->setText(" , ");
    break;
    case Qt::Key_Greater: ui->display->setText( ");
    break;
    case Qt::Key_Period: ui->display->setText(" . ");
    break;

    }
    }

    Entire Keyboard

    Keyboard Notes

    Note on the Space Bar ( Qt::Key_Space )

    By default, when some widgets have focus, usually by using the Tab key, pressing the Space Bar will activate them. If your program needs the Space Bar pressed, then all of these widgets will need to have their focus policy turned off. QPushButton, QRadioButton, and QToolButton are some of the more common ones.

    This is an easy matter:

    1. Go to the Qt Creator Form layout.
    2. Select the widget to be affected.
    3. On the right under Properties is a section called: focusPolicy.



    Click the far right of this box.





    A pull-down menu will appear.
    Select the first option “NoFocus”





    Press the Enter key.
    Do this for all such widgets.
    The tab key will skip over this widget.


    To Top


    Connecting Two Forms Together

    Many times a person needs one form to talk to another form, or one Dialog box sending information to another Dialog box.

    One method is to create an entire form directly from the parent form. This is done with code from the C++ side, and not the GUI form designer. This can be clumsy, frustrating and not very pretty. Another method is to create a child form class, and then connect it to the parent class. This is a much better method, as the designer can create, alter and position the new form's widgets with ease like they did with the first form.

    I have not seen any Qt Documentation on this. It is trial, and great error, on the side of the new programmer. This is a simple method for the new Qt'er.

    Start with a form already created. We will use className as being already created, and we want to add another one to it. We'll call this secondForm.

    Creating the new form




    File: "New File or Project..."



    Choose a Template:   1) QT     2) Qt Designer Form Class    3) "Choose…"



    Choose a Form Template:  1) Main Window     2) "Next"



    Default name of MainWindow is displayed.



    Class Name:   For this, we will use "secondForm"



    Project management:   1) add to project: className.pro     2) "Finish"

    Files to be added in:
    C:\Qt\2010.05\className:
    secondForm.h
    secondForm.cpp
    secondForm.ui

    Project now opens in Qt Creator’s design window.


    Note the additional files added under the .ui, .h and .cpp folders

    The forms are still not connected to each other.

    Under the newly created class secondForm:
    In the .h file, move

    Ui::secondfForm *ui;

    from private to public. It must be seen by the other classes / forms.

    In the original className's .h file, add:
    At the top under the #include section

    class secondForm;


    This is telling className that a new class is being added to it.

    Next, a variable needs to be declared for this newly added class.
    Add the following under private:

    secondForm *sf;

    In the className .cpp
    Add the following to the #include

    #include "secondForm.h"
    #include "ui_secondForm.h"

    This is telling clasName to expect the following form elements and other libraries at some point.

    We now need to create the secondForm object. This is making the path from secondForm to className. Think of it as official secondForm ambassador. It oversees all secondForm widget activities.

    In the className constructor, add:

    f2 = new secondForm( this);
    f2->show();

    The show() is added as the new form is hidden by default.

    The two forms are now connected.
    It should look like this.

    Parent accessing child's widgets



    In className’s constructor, start typing with sf (secondForm) followed with a period. The pull-down menu will appear, including ui. Select this, and now all the widgets in the class secondForm will be available for accessing by the class className.

    Changing a lable's color


    For this section we will use this layout


    Try this. Put this in the constructor of className.cpp:

    sf->ui->lable2->setStyleSheet( "color: blue; font-size: 14px;"); // Widget in secondForm.

    Run the program, and the text of widget label2 is now blue.

    This setup is
    one way communication
    from the parent class to the child class.

    Now, how to make the child talk to the parent


    Many forms in the world are only receiving data from other forms.This is one of those forms.

    We want secondForm to send text to the original className. For this, we will use the same layout as above. We will have a simple QLineEdit or "text box" called lineEdit2 to send text to another QLineEdit in className called lineEdit1.

    The changes in secondForm .h

    We need a signal and a slot to send the text.

    Slots can be private or public. Signals are always private and do not need, nor will function with, the word private.

    It is worth noting, in the .h file these two are lowercase and plural, while in the .cpp file they are uppercase and singular. They require the library , and this is part of

    In the .h file, create this anywhere in the class declaration, as signals and slots are not listed when a class is created.

    public slots:
    void sendText();

    signals:
    void byby( QString);

    The slot is calling the function sendText(), and the signal is inside this function actually launching the text into cyber-land with byby( QString). From there it will be picked up by className. This requires a QString as that is the data type that is being sent.

    The changes in secondForm .cpp

    In the constructor, we need a connect for the widget lindEdit2, as this is where the text is. The SIGNAL options include returnPressed(). Select this, as it will access the Return key on the keyboard, only when the lineEdit has focus! Since there are not any other widgets on the layout, this will not be a problem today.

    The connect will look like this:
    connect(ui->lineEdit2, SIGNAL(returnPressed()), this, SLOT(sendText()));

    ui->lineEdit2 is what is being connected. It is being connected to the widget this, which is referring to the entire form. The program is smart enough to know what is going on if it sees this as the receiver.

    The function looks like this

    void secondForm::sendText()
    {
    emit byby( ui->lineEdit2->text() ); // Sending out.
    //ui->lineEdit2->clear(); // Clearing text box after sending.
    }

    Un-comment the last line if you wish to have the lineEdit cleared after sending the text. Think of all the forms you have filled out and entered. Some forms clear themselves after being submitted, and some don't. It depends on the situation.

    Code for className .h

    This is receiving the text from secondForm. We want to drop it off directly into lineEdit1.

    We need a slot to grab the signal from secondForm and display its text into the lineEdit1.

    This is what we need.

    public slots: void displayText();

    Code for the className .cpp



    In the constructor add this connect:



    The sf is telling the program that the form secondForm (sf) is connecting with className ( this). It is being connected with the SIGNAL byby().

    The SLOT function displayText() looks like this:

    void className::displayText()
    {
    ui->lineEdit1->setText(   sf->ui->lineEdit2->text()    );
    }

    The lineEdit1 is displaying the text sent from secondForm with setText(). This is why there is another sf in the code. It is telling the system this is coming in from another form.


    Dual communication between the two forms

    Something like a chat room, these two forms can send text back and fourth between the two of them.

    You might think just do the same process as above for the other class. Fortunately, it is much easier than that. The child class needs the emit to get the attention of the parent. The parent class does not need this. Perk of being a parent.

    To make things more interesting, we are going to add a QTextEdit to both forms to make it more of a chat room. These will receive the text.

    • className's will be called textEdit1

    • secondForm's will be called textEdit2


    This is what the new layout looks like.


    As demonstrated above with "changing a label's color," the parent can access the child form's widgets directly.

    Keep the form class secondform like it is. All the changes will be with className. Even with the addition of the new QTextEdit, the text is being sent from the QLineEdit.

    It might be easier to un-commnet the line:
    ui->lineEdit2->clear(); in secondForm. This will clear the lineEdit after text has been sent out.

    Changes to className .h


    We need to add a single slot to the one we already have, one to send text to secondForm. Lets call this sendText2(); Our slots should look like this:

    public slots:
    void displayText();

    void sendText2();

    Changes to className .cpp


    To the already entered connect statement, we are going to add another one. This one will sent text out to secondForm's textEdit2.

    connect(ui->lineEdit1, SIGNAL(returnPressed()), this,SLOT(sendText2()));

    As before, the ui->lineEdit1 is where the text in entered. It is being connected to the form itself, with this, and the function call is sendText2().

    The function sendText2() looks like this:

    void className::sendText2()
    {
    sf->ui->textEdit2->append(   ui->lineEdit1->text()   ); //Sending.
    ui->lneEdit1->clear(); // Clearing text box after sending.
    }


    QTextEdit does not have a setText() property. It uses append().

    This is what the entire code should look like

    Many forms require opening and closing of another window. We will be using our parent class className to open and close two child forms called secondForm and thirdForm.

    Start with a form called className. Follow the steps in "Connecting Two Forms Together & Accessing Their Widgets" to create secondForm and then another called thirdForm.

    We now have 2 new form classes. They are the children of className. In both of the new child classes,
    move each of their UI private declarations into

    public
    Ui::secondForm *ui;
    Ui::thirdForm *ui;




    secondForm.h


    thirdForm.h

    They need to be seen by other classes / forms.
    The rest of the work is in className


    Changes in className .h

    At the top under the #include section, add the following classes

    class secondForm;
    class thirdForm;

    This tells className to include two other classes.
    Under the private, add a variable for each of these two new classes. Let's use the following:

    secondForm *sf;
    thirdForm *tf;

    It should look like this:

    className.h


    changes in className .cpp

    At the top, under the #include section, we need to add the other two form's .h files and ui interfaces.
    Add the following:

    #include "secondForm.h"
    #include "ui_secondForm.h"

    #include "thirdForm.h"
    #include "ui_thirdForm.h"

    Below this, in the constructor, we need to create the object's for each of the new classes.
    Add the following:

    sf = new secondForm(this);'
    tf = new thirdForm(this);

    It should look like this:

    className.cpp

    We have just connected all three forms together, and are now ready to do some coding.


    To Top


    One Window Opening and Closing Other Windows

    Many forms require opening and closing of another window.
    We will be using our parent class className to open and close two child forms called secondForm and thirdForm.

    Start with a form called className. Follow the steps in "Connecting Two Forms Together & Accessing Their Widgets" to create secondForm and then another called thirdForm.

    Creating 2 form classes

    We now have 2 new form classes. They are the children of className.

    In both of the new child classes, move each of their UI private declarations into public

    Ui::secondForm *ui;
    Ui::thirdForm *ui;


    secondForm.h


    thirdForm.h

    They need to be seen by other classes / forms.
    The rest of the work is in className

    Changes in className .h

    At the top under the #include section, add the following classes

    class secondForm;
    class thirdForm;

    This tells className to include two other classes.
    Under the private, add a variable for each of these two new classes. Let's use the following:

    secondForm *sf;
    thirdForm *tf;


    It should look like this:

    className.h

    Changes in className .cpp

    At the top, under the #include section, we need to add the other two form's .h files and ui interfaces.
    Add the following:

    #include "secondForm.h"
    #include "ui_secondForm.h"

    #include "thirdForm.h"
    #include "ui_thirdForm.h"

    Below this, in the constructor, we need to create the object's for each of the new classes.
    Add the following:

    sf = new secondForm(this);
    tf = new thirdForm(this);

    It should look like this:


    className.cpp

    We have just connected all three forms together, and are now ready to do some coding.

    Opening other Windows

    The UI layouts In this section, we are going to use this layout for coding:

    className.ui



    secondForm.ui



    thirdForm.ui


    The code in className.cpp

    There are a few different ways of doing this, and for this example, we are going to control everything from className. This will be the center of activity.

    In className.cpp constructor, we will need four connects, 2 to open windows and 2 to close them.

    secondForm will be opened by openButton1, and closed by closeButton1. thirdForm will be opened by openButton2, and closed by closeButton2.

    This SIGNAL will be a mouse click called clicked(), and the SLOT will be custom made.

    connect(ui->openButton1, SIGNAL(clicked()), this, SLOT(showSecondForm()));

    connect(ui->openButton2, SIGNAL(clicked()), this, SLOT(showThirdForm()));


    connect(ui->closeButton1, SIGNAL(clicked()), sf, SLOT(close()));
    connect(ui->closeButton2, SIGNAL(clicked()), tf, SLOT(close()));


    We we now be using the variables we created earlier for the two forms, sf and tf.
    Widgets will be made visible with show();, and made invisible with close();.

    Making secondForm visible will be the SLOT showSecondForm() and the variable sf.

    void className::showSecondForm()
    {
    sf->show();
    sf->move(650, 50);
    // left,   top // Added to avoid window overlap.
    }

    The closing of secondForm is all in the connect statement. Instead of connecting with this, as we have been doing, we will use the object sf, and use the SLOT close() like so:

    connect(ui->closeButton1, SIGNAL(clicked()), sf, SLOT(close()));

    Repeat for thirdForm and the cpp file should look like this:

    className.cpp Bigger picture

    className .h



    Since we have created 2 slots, we need the add them here. The close() slots were already created by the system, and do not need to be added.

    public slots:
    void showSecondForm();
    void showThirdForm();


    It should look like this:


    className.h Bigger picture

    Open Windows Notes

    Use hide() instead of close()

    If the child starts closing other windows, it might be better to have the SLOT use the function hide()
    instead of close().

    Closing another child might cause all the children to close.

    Example:
    connect(ui->closeButton1, SIGNAL(clicked()), sf, SLOT(hide()));

    Other close method

    If needing many things to be done before closing another window, use this:
    create a new SLOT

    void className::closeSecondForm()
    {
    // Other pre-closing code here.
    sf->close();
    }


    To Top


    Creating Links to Internet

    Internet links are almost everywhere. They are expected to be on anything possible, and Qt can make it happen on your application.

    Qt has the Web tool kit, which is very extensive and well beyond this tutorial. This tutorial will show how to install a simple link to the Internet.


    Screen capture from Qt Documentation

    As you can sees from the above text, unless a person knows what Rich Text Format is or dose, they will skim over it and keep reading. The Rich Text area is where a person adds html tags with the anchors a to the Internet.

    Creating the QLabel's Rich Text


    Right click on QLabel





    Click on "Change rich text..."





    Stretch out window or things will become cluttered.
    Click on tab: "Source"





    Enter html text like any webpage: anchors and targets. When done, click "OK"





    Part one of this is finished.




    Activating the links

    Still not finished. Nothing in life, or Qt, is easy. Next step is to turn the links on.

    Make sure the QLabel is highlighted.


    On the right side of the form editor, scroll down to "openExternalLinks" and click True.
    It should be False by default.



    Below is "textInteractionFlags". "LinksAccessibleByMouse" is True by default, if not, make it so. This will let the link be activated by a mouse click.

    Add any other ways to activate the links you need - "LinksAccessibleByKeyboard" is another easy method for the user to activate the link.

    You are now ready to surf the web.


    To Top


    Adding Foreign Text

    Making an application multilingual will increase your software product’s awareness, number of customers, and it will be a more interesting product.

    Qt has a method to make an application display foreign text. It is a bit complicated. A programmer should:

    * Download their manager Qt Linguist if not part of the newer versions of Qt
    * Create an XML file with the names of widgets to display the foreign text
    * Enter this into the Qt Linguist.
    * Add code in main() and the PRO file to activate the translations
    * For each string in the .cpp file, surround this with tr(), so to read:
    label->setText( tr( "Hi") );
    * If using non-Latin1 strings need to add:
    QTextCodec::setCodecForTr(~QTextCodec::codecForName("utf8"));
    * Qt Writes that if the programmer needs translations out of a function, they should use :

    String ~FriendlyConversation::greeting(int greet_type)
    {
    static const char* greeting_strings[] = {
    QT_TR_NOOP("Hello"),
    QT_TR_NOOP("Goodbye") };
    return tr(greeting_strings[greet_type]);
    }


    * With a host of symbols for global DEFINE variables.

    Does any of this look like fun? Let me just say:

    It’s not gonna happen!!

    This method, one of many, should take a whopping 10 minutes.

    Regardless which method a programmer uses, the translations themselves must come from another source. These programming methods will only ''display'' the text. There are dozens of free on-line translators for simple phrases. Go to 2-3 and compare them to make sure they are correct. For more complicated text, do yourself a favor and hire a translator. You don’t want to release a product with a mistranslation. Interactive window

    This will demonstrate how pushing a button will change all the text on a screen.

    This is what foreign text looks like in Qt. These are 7 labels to display the days of the week. To be more accurate, the buttons Russian and Japan should be displayed in their native language,Русский and 日本 . They are kept in English for this example.

    What to do:

    1. Click one of the 3 language buttons.

    2. Watch the days of the week change language.



    These languages, English, Russian (Cyrillic), and Japanese ( Kana, Hiragana, and Katakana) were chosen to demonstrate the wide range of possibilities.

    Let's get started.

    Single Line of Text

    Qt's form editor can handle Unicode.
    This is where the foreign, and local, text will be placed, and then retrieved for usage. We will use a QTableWidget to store it. At run time, the table will become hidden.

    On the form editor, create 7 labels, named label1 to label7, to display the days of the week, and then follow
    the steps below to create and load the table with text in 3 languages.

    Translations are from:


    Drag a QTableWidget to the editor. Right click and select first option: "Edit Items ..."



    First add columns. Click + at bottom to add columns.



    Click OK when finished.



    Next add rows. Click + at bottom to add rows.



    Click OK when finished.



    Last is the the table's data. Click cells to add text.




    This is a 2-diminisional array, and numbering starts at zero. Row is left number, and columns are right.
    We will need this next.

    Add 3 QPushButtons to change the languages. We will add the code for this next section. Name them:

    pushEnglish;     pushRussian;     pushJapan;

    Adding Foreign Text - Single Line Coding

    We will still use className as the name of the form. There are not any libraries to add for this.

    in the .h file, we will need three slots, as there are three buttons to be pressed. Add the following:

    public slots:
    void allEnglish();
    void allRussian();
    void allJapan();


    On to the ''.cpp'' file...

    In the constructor, we will need three connects, one for each button to call a custom function.

    connect(ui->pushEnglish, SIGNAL(clicked()), this, SLOT(allEnglish()));

    The function allEnglish() will be using the label's setText() with the table's data cell accessing code inside it.
    We are displaying the English word "Monday."




    The item(row, col) uses the tables 2D array to access the table's data and place it inside the label.


    Here is the entire array for this example.



        

    QTableWidgets 2D array layout.

    This is what the entire function looks like. If a programmer needs to use the foreign text elsewhere in the program, they will use the code inside the setText: ui->table->item(0,0)->text()

    void className::allEnglish()
    {
    // Row, Col
    ui->label1->setText( ui->table->item(0,0)->text() );
    ui->label2->setText( ui->table->item(1,0)->text() );
    ui->label3->setText( ui->table->item(2,0)->text() );
    ui->label4->setText( ui->table->item(3,0)->text() );
    ui->label5->setText( ui->table->item(4,0)->text() );
    ui->label6->setText( ui->table->item(5,0)->text() );
    ui->label7->setText( ui->table->item(6,0)->text() );
    }


    Repeat for the other 2 functions, except the columns will increment by 1 number for each. the allRussian will be start with item(0, 1) and allJapan will be item(0,2).

    In the constructor, include the start language function allEnglish(); and the code to make our text-table hidden at run time: ui->table->hide();

    The Code
    Here is the entire code. Bigger picture


    className.h for foreign text.



    className.cpp for foreign text.

    Adding Foreign Text - Paragraphs

    The above example is good for a single line of text; however, sometimes a paragraph is desired, and the table method is not going to work. For this, the hide-the-label method is needed.

    Create a label for the English, one for the Russian, and one for the Japanese. Add the text for all three languages in their own label. They will be layered on top of each other, and should make a nice Rorschach picture.

    Three language
    label's overlapped.
    Is it art?


    Inside the allEnglish(), make the other two labels hidden with:

    ui->label8_Russian_paragraph->hide();
    ui->label8_Japan_paragraph->hide();

    and make English visible with:
    ui->label8_English_paragraph->show();


    For allRussin() and allJapan() do the same, except make their own nationality shown.

    Make sure the labels are big enough so as not to truncate the text.

    Foreign Text - Notes

    This method works for all system text:

    Window title:
    Status bar:
    Menu headings:

    ui->setWindowTitle(   ui->table->item(6,0)->text()   );
    ui->statusBar()->showMessage(   ui->table->item(6,0)->text()   );
    ui->actionMenu1->setText(   ui->table->item(6,0)->text()   );


    The .h and .cpp area will not support foreign text. If added here, then the output at run time will be a field of question marks: ????? This includes qDebug() usage.


    To Top




    The End


References
Alessi, S. M., & Trollip, S. R. (2001). Multimedia of learning: Methods and development (3rd ed.). Needham Heights, Ma: Allyn and Bacon.

Sturken. M., & Cartwright, L., (2009). Practices of looking: An introduction to visual culture. Oxford, NY: Oxford University Press Inc.