2010年4月12日星期一

Qt框架简述

Qt is a cross-platform application and UI framework.
以上是Qt官方的定义,地址是 http://qt.nokia.com/
最基本的,Qt是一个XWindow函式库,可用于基于Widget的图形UI开发。
但更重要的是也提供了跨平台的C++语言扩展和众多实用库,以及一些开发工具。
这些对于高效的开发跨平台程序是强有力的支撑。
以下内容根据Qt4.5的文档,这是NOKIA收购后Trolltech推出的重要版本,具有很好的向后兼容性。
传送在线文档地址 http://doc.trolltech.com/4.5/index.html

Qt通过预编译器moc和类型QObject来对C++的class特性进行了扩展,它是Qt的物件的基础类
class MyClass : public QObject {
Q_OBJECT
public:
MyClass(QObject *parent = 0);
~MyClass();
signals:
void mySignal();
public slots:
void mySlot();
};
这样就可以清晰地使用Qt的Signals and Slots机制,
这是Qt物件间常用的通信方式与解耦合方式。
signal按 emit mySignal(arg); 语句使用,Slot则是可以被connect的特殊的成员函数。
比如通过这样的方式使用
QObject::connect(
&QObjectA, SIGNAL(valueChanged(int)),
&QObjectB, SLOT(setValue(int))
);

下面是一个简单的GUI实例
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget window;
window.show();
return app.exec();
}
}
QWidget是GUI组件的基础类
通过构造时指定parent构件,组成层次关系。子对象会被其父对象自动delete或show。
比如增加一个按钮
QPushButton *button = new QPushButton("Press me", &window);
如果这里在QObject里可以用tr("Press me")包裹的QString来实现i18n。
除了使用构件的resize或move方法,Qt提供QLayout来布局构件的位置。
比如使用水平布局
QLabel *label = new QLabel(tr("Name:"));
QLineEdit *lineEdit = new QLineEdit();
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(label);
layout->addWidget(lineEdit);
window->setLayout(layout);
layout并不派生自QWidget。它是通过addWidget或addLayout来添加构件或布局,然后在窗口中用setLayout来使用。
一般来说,窗口是通过继承QMainWindow来实现。
class MainWindow : public QMainWindow{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
在这里的构造函数中,除了用来创建(QWidget)this的子对象外,还可以使用QMainWindow的添加菜单工具栏以及停靠构件的操作。这里菜单项是添加了QAction对象。
构建的事件处理也需要在此用Signals and Slots机制来connect,
connect(button, SIGNAL(clicked()), this, SLOT(on_button_clicked()));
这里on_button_clicked()是为MainWindow定义好的Slot成员。
事件也会用到QEvent对象,通过重写QWidget中event相关的虚函数来处理。
消息框使用QMessageBox,
StandardButton QMessageBox::information ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton ) [static]
对话框则通过QDialog派生出。dialog用show();hide()操作可见性,exec()执行模式对话框,accept()在对话框中确认对话框完毕。
对文件的操作会用到的有 QFile,QDataStream,QFileDialog。其中前两者类似C++库中相应的类,但增强了对Qt类型的支持。
QVariant包含了基本的Qt类型,其中
QString的arg()可以用来替换"%1, %2, ...",number和toInt方法用来在数字和字符串间转换。
也提供相应的数据结构QStringList:QList和一些算法。
这些Qt类型属于QtCore模块,而GUI组件属于QtGui模块。来使用时需要引入类型的头文件。
Qt也提供若干实用的模块,比如网络数据库脚本方面的功能。

相关的工具:
使用QtDesigner是Qt提供的可视化GUI生成工具,通过.ui文件创建布局和设置信号。
布局通过Form菜单中Lay Out使用布局,构件间可以使用事件的关联,可以定义新的槽。
本地化使用QtLinguist。
使用QtTest可以进行单元测试,可以实现测试驱动的开发。
程序生成使用qmake,可以跨平台使用。
其他Core和Gui上的特性要点:
复杂的表格或树形视图是通过Model/View结构的编程实现。
图像的操作是通过Paint System,主要用QPainter对象,图片用QPixmap表示。
拖放由QDrag和QEvent实现。
继承QThread用来实现多线程。
GraphicsView是用来代替QCanvas实现2D对象显示。

Qt的API设计
http://www.cuteqt.com/bbs/viewthread.php?tid=195
Qt是作为库是可以在多种语言中使用的,但本身API是按C++设计。
其中处理相关的技术要点,值得关注的是类的继承关系,Public和Protected的Type,Property ,Function,Signal&Slot以及Static Member。其中Property涉及getter和setter两个方法。

See Also
http://qt-apps.org/
http://www.kde.org/
http://www.telegraph-road.org/writings/gtkmm_vs_qt.html

----
相比于其他选择如Glib/GTK,.net,...
通过Qt可以增强对C++的使用,获得跨平台的特性,提供易用OO的API。
而且这里更在意的是,使用了Qt能够以如何的代价获得什么。
Python感觉用PyGTK和wxPython的更多一点,他自身还带了简单易用的Tk。
思考着C++,安装好QtCreator,就算是Qt使用的开始了。。。
Qt的官方教程叫 C++ GUI Programming with Qt 4, Second Edition。

----
关于i18n问题,还是要补充一下的。
首先是字符串编码的问题:
Qt的处理方式是QString对象存放Unicode(和源码编码无关),而如果和系统使用的编码不一致就会显示乱码。
所以在QString与系统会文件间字符串转递时如过需要,就要对编码进行转换了。
如果仅是中文显示问题,可用这个
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());

另一个,是涉及到的Qt中翻译工具的使用:
待补。。。
----
Qt处理Qui库,也是个开发框架,支持库的复用和设计的复用。通过moc有对C++语法的扩展比如foreach。Qt4之前版本下编译的文件可以在之后的dll或so文件下使用的。
Qtcreater是Qt自带的IDE,可以同时使用支持多版本Qt库的,编辑器支持VIM操作模式。

没有评论: