QT学习笔记1

这段时间在看C++ Primer,才发现我喜欢的是C++ Primer Plus。前面那本书感觉比较零散,后者讲的非常透彻,比如引用的由来和用途,即使是在Kindle上看也能理解清楚。抽出本科上课的那本电子工业出版社的C++程序设计基础,看着很亲切,大概是因为编的简单。

想着把C++的基础打牢一些,光看书敲例子代码似乎不能很好的理解提高。于是结合QTCreater复习C++的同时学习一下怎么写嵌入式系统的GUI界面。


QTCreater安装

QTCreater比较大,可能还需要安装OpenGL函数库,开发包等。我使用原始的命令进行安装,亲测可用,快速方便。

sudo apt-get install qt4-dev-tools #开发包   
sudo apt-get install qtcreator     #IDE  
sudo apt-get install qt4-doc       #开发帮助文档  
sudo apt-get install qt4-qtconfig  #配置工具   
sudo apt-get install qt4-demos     #DEMO源码 

一张图

下图说明了QT窗口所有控件的继承家族关系。其中QDialog是各种对话框的基类,QMainWindow是带有菜单栏和工具栏的主创口类,两者都继承自Qwidget。所有的窗口部件都继承自Qwidget。

图片


例子才不用HelloWorld

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget *widget=new QWidget;
    widget->setWindowTitle("This is widget");

    QLabel *label=new QLabel();
    //Default parameter of parent is 0, so it is a window.
    label->setWindowTitle("This is label");
    label->setText("This is Text of label");
    label->resize(200,150);
    label->show();

    QLabel *label2=new QLabel(widget);
    //Default parameter of parent is widget
    label2->setText(("Label is part of Widget"));
    label2->resize(400,200);
    label2->show();

    widget->show();
    return a.exec();
}

程序定义了一个QWidget类对象的指针widget和两个QLable对象指针label与label2。其中label没有父窗口,而label2在widget中,widget是父窗口。

QMainWindow和QDialog子类是一般的窗口类型。窗口是没有父部件的部件,成为顶级部件(top-level widget),与其相对的是非窗口部件,又称为子部件(child widget).


SIGNAL AND SLOT

在一些自己写的继承类中会看到宏定义Q_OBJECT

class MainWindow : public QMainWindow
{
    Q_OBJECT
    public:
    ...
}

它定义如下:

#define Q_OBJECT \
public: \
Q_OBJECT_CHECK \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
QT_TR_FUNCTIONS \
virtual int qt_metacall(QMetaObject::Call, int, void **); 
private: \
Q_DECL_HIDDEN_STATIC_METACALL static void  \
qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
struct QPrivateSignal {};

The Q_OBJECT macro at the beginning of the class definition is necessary for all classes that define signals or slots。

只有加入了Q_OBJECT,自己定义的类中才能使用QT中的SIGNAL&&SLOT机制。

#include <QApplication>
#include <QTextEdit>
#include <QPushButton>
#include <QVBoxLayout>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextEdit *textEdit=new QTextEdit;
    QPushButton *quitbutton=new QPushButton("&Quit");

    QObject::connect(quitbutton,SIGNAL(clicked()),qApp,SLOT(quit()));

    QVBoxLayout *layout=new QVBoxLayout;
    layout->addWidget(textEdit);
    layout->addWidget(quitbutton);

    QWidget window;
    window.setLayout(layout);
    window.show();

    return a.exec();
}

运行生成的GUI界面如下:

图片

这段程序中使用connect(quitbutton,SIGNAL(clicked()),qApp,SLOT(quit()))来关联quitbuttonquit(),就像事件驱动一样。这就是使用了SIGNAL&&SLOT机制。

在官方文档上这么描述SIGNAL&&SLOT机制的由来

In GUI programming, when we change one widget, we often want another widget to be notified. More generally, we want objects of any kind to be able to communicate with one another.

可以看出这个机制和CallBack回调机制很像,它将两个对象的事件进行绑定,一个事件的执行造成另一个事件的触发。绑定的方式如图所示:

图片

这个例子中把quitbutton提交的信号发送到系统调用quit槽中,如果点击按钮,界面就会退出。


Reference

[1].http://www.qter.org/?page_id=161

[2].http://qt-project.org/doc/qt-4.8/gettingstartedqt.html#hello-notepad

[3].http://www.ibm.com/developerworks/cn/linux/guitoolkit/qt/signal-slot/index.html

[4].http://qt-project.org/doc/qt-4.8/signalsandslots.html



Previous     Next
/
Published under (CC) BY-NC-SA in categories C&&C++  tagged with