现在的位置: 首页 > 综合 > 正文

How to read Qt documentation, basic concepts

2013年10月18日 ⁄ 综合 ⁄ 共 6941字 ⁄ 字号 评论关闭
文章目录

 

How to read Qt documentation, basic concepts

I hope previous tutorial satisfied your Qt impatience. Since this tutorial is meant for real beginners it's necessary to explain some thing about Qt documentation. Some basic concepts of Qt and C/C++ are also explained.

Basic look at class documentation

Let's have a look at http://doc.trolltech.com/4.2/qlineedit.html

Public Types

We see the part named Public Types. This is a list of public enumerated types we can use with this class. We see:

Public Types
      enum EchoMode { Normal, NoEcho, Password, PasswordEchoOnEdit }

This says we can use type QLineEdit::EchoMode.

// some code
..
QLineEdit::EchoMode mode;
mode = myLineEdit->echoMode();
 
...
 
mode = QLineEdit::NoEcho;
myLineEdit->setEchoMode( mode );
// or directly myLineEdit->setEchoMode( QLineEdit::NoEcho );

Public types are usually used in Properties. Property can have values of some of public types. We have already used Qt::WindowFlags public type in previous tutorial.

Properties

Properties can be get and set. Previous code show usual way to do it. Most important is probably text property.

Some of the properties of QLineEdit:

acceptableInput : const bool
alignment : Qt::Alignment
cursorPosition : int
displayText : const QString
dragEnabled : bool
echoMode : EchoMode
..

Public Functions

Public functions are what we are most often interested in. These functions do something with an instance of the class.

// we used this in previous tutorial
textEdit->append( "Path to file: " + lineEdit->text() );

Public Slots

Public Slots are functions to which we can connect signals.

In previous tutorial, we connected the signal "clicked()" of pushButton called "pushButton_clear" to slot "clear()" of "this". this means pointer to actual instance of the class (myQtApp in our case).

    connect( pushButton_clear, SIGNAL( clicked() ), this, SLOT( clear() ) );

Assume we want to add a new button to the form in the previous tutorial. If we click it, the contents of QLineEdit will be selected. The button is named pushButton_select_all.

    connect( pushButton_select_all, SIGNAL( clicked() ), lineEdit, SLOT( selectAll() ) );

You can try to add it to myQtApp.

Signals

Signals are emitted from class, and we can connect them to a slot (or multiple slots). Signals can have parameters (a signal is actually a function). Parameters are passed to a slot when a signal is emitted. You can try this out with signal void textEdited ( const QString & text ) like this:

Define custom slot in myQtApp, in myqtapp.h.

public slots:
..
void mySlot(const QString&);

Implement mySlot in myqtapp.cpp

void myQtApp::mySlot(const QString& passedStr)
{
    QMessageBox::information(this, "Some window label here", "String: " + passedStr);
}

And connect in constructor myqtapp.cpp.

myQtApp::myQtApp(QWidget *parent)
{
..
// signals/slots mechanism in action
..
..
connect( lineEdit, SIGNAL( textEdited (const QString&) ), this, SLOT( mySlot(const QString&) ) );

Now if you edit the contents of lineEdit, QMessageBox will show up.

How to define a custom signal

We can also define a custom signal.

Please note that example below uses custom slot we defined above. Before you proceed add custom slot as shown above.

myqtapp.h

public:
    myQtApp(QWidget *parent = 0);
 
signals:
    void customSignal( const QString& );
..

myqtapp.cpp - adjust myQtApp::clear(). The signal is emitted using the emit keyword.

void myQtApp::clear()
{
    emit customSignal( textEdit->toPlainText() );
    textEdit->clear();
}

Connect in constructor myqtapp.cpp. Note we connect it to custom slot (function) mySlot. When signal customSignal is emited mySlot will be called with string as parameter.

connect( this, SIGNAL( customSignal (const QString&) ), this, SLOT( mySlot(const QString&) ) );

Recompile and press Clear button. Note that we connected 2 signals to same slot.

Read http://doc.trolltech.com/4.2/signalsandslots.html and about automatic connections naming convenience.

Sources with custom slot and custom signal for download and compile

my_first_qt_app-custom-sig-slot.zip

Protected Functions

Protected functions are like public functions. The only difference is that these functions can be called from this class, classes derived from it and friendly classes. For better explanation refer to some C++ reference.

Static Public Members

QLineEdit doesn't have them so please look at QString documentation.

Static public members are functions we can call anywhere in the program (as long as we include <QString> or <QtCore>/<QtGui>).

In myQtApp we used QString public static function number(int):

// use of static public member function QString number ( int n, int base = 10 )
textEdit->append( "Number 1 value: " + QString::number(value1) );

Remember 2 things:

  • static public functions don't need an instance of class (QString) to invoke them
  • if you do use an instance of a class, they won't influence it

We can nicely illustrate second statement with QProcess class.

QProcess myProcess;
 
myProcess.execute("some_program.exe"); // e.g. regedit.exe or whatever
 
// let's say we want to terminate execution of program some_program.exe
myProcess.terminate(); // doesn't work, does actually nothing because execute is static function
 
// if we check state of process with myProcess.state() before myProcess.terminate()
// we'll find out that it's not even running
// we must use public function to create controllable instance
// i.e. void start ( const QString &amp; program, OpenMode mode = ReadWrite )
// instead of static execute

const QString &

Parameter definition const QString & can be found throughout all Qt documentation.

We defined our custom slot like this.

void myQtApp::mySlot(const QString& passedStr)

If you ask why we didn't define the parameter like this:

void myQtApp::mySlot(QString passedStr)

Answer is that we could with no problem. The reason why use const & is performance.

void myQtApp::mySlot(QString passedStr) {
// with this definition, a copy of passedStr is created and any changes made 
// to it are lost when the subroutine ends so
passedStr = "abcd";
// would leave the variable it was called with unchanged and not set to "abcd"
..

void myQtApp::mySlot(const QString& passedStr) { // this means pass reference to the passedStr (no copy is created - saves resources) // and const says - do not allow reference to be modified ..

See this link for detail const keyword explanation.

Memory allocation on stack vs. heap

Stack/heap memory allocation is one of the fundamentals of C++ memory management. What to bear in mind is following:

We want to start a program using QProcess class.

void myQtApp::function() 
{
    QProcess proc; // we create this proc variable on stack
    proc.start("regedit.exe"); // start program regedit.exe
}

If you call this function you would expect program regedit.exe to start. However it is actually not the case. No program is started. You'll see following error in console window instead (make sure your .pro file contains CONFIG += console).

QProcess: Destroyed while process is still running.

Idea behind this is that when variables are created in a C++ program (when the variables are in scope like we did it above), the memory required to hold the variable is allocated from the program stack. When the variable goes out of scope, the memory which was taken on the stack is freed.

In our situation it means that proc variable will be destroyed right after function() returns. Brackets "{" and "}" define scope of variable, an area where proc exists. This is particularly important to remember.

Solution to this is to create variable on heap.

When memory is allocated dynamically (by the programmer using new operator) memory is taken from the heap (which consists of all of the computers virtual memory, which includes onboard RAM and space available on the disk drive.

void myQtApp::function() 
{
    QProcess *proc; // pointer definition
    proc = new QProcess( this ); // memory allocation from heap, created with parent
    proc->start("regedit.exe"); // start program
}

Please notice that the QProcess constructor is invoked with this parent (which actually points to instance of myQtApp). If parent is destroyed all it's children is also destroyed.

Another solution is to declare proc as member variable of myQtApp.

抱歉!评论已关闭.