QtGui初探
放假的一天,但是源码的分析不能间断,继续做分析。
在完成了之前几天的分析之后,对于Qt最基本的两条语句有了初步的了解,接下来的事情就是看一个应该程序窗口是如何建立起来的了。
通常情况下,我们都会在创建应用程序时选择QMainWindow方式,而这个类继承自QWidget,其他所有的GUI相关的类也都继承自该类。所以,今天从QWidget开始。
最基本的两行代码是:Widget w;w.show();
这样的话,我们就Widget类的整体描述,进行下简单分析,之后再最构造函数,以及show方法进行一下专门的研究。
在QtGui/kernel/qwidget.h 中,首先看到的是QWidgetData类的什么,该类主要用于存储QWidget类的数据。
class QWidgetData
{
public:
WId winid;
uint widget_attributes;
Qt::WindowFlags window_flags;
uint window_state : 4;
uint focus_policy : 4;
uint sizehint_forced :1;
uint is_closing :1;
uint in_show : 1;
uint in_set_window_state : 1;
mutable uint fstrut_dirty : 1;
uint context_menu_policy : 3;
uint window_modality : 2;
uint in_destructor : 1;
uint unused : 13;
QRect crect;
mutable QPalette pal;
QFont fnt;
#if defined(Q_WS_QWS)
// QRegion req_region; // Requested region
// mutable QRegion paintable_region; // Paintable region
// mutable bool paintable_region_dirty;// needs to be recalculated
// mutable QRegion alloc_region; // Allocated region
// mutable bool alloc_region_dirty; // needs to be recalculated
// mutable int overlapping_children; // Handle overlapping children
int alloc_region_index;
// int alloc_region_revision;
#endif
QRect wrect;
};
为了最大程度的对程序进行优化,该处又用到了位域的概念。这里同样的用到了,将类的数据提取成一个独立的类,这样,在传递参数的时候,就不需要考虑形参以及拷贝构造等问题了。
接下来就是QWidget类了,继承自QObject和QPaintDevice,其中的属性主要是对窗口类的描述,猜测整体的图像绘制还是靠QPaintDevice部分完成的,作为底层的图形引擎。不过需要进一步分析之后才能得到结论。该类的方法中,目前我比较关注的有
void createWinId(); // internal, going away
void render(QPaintDevice *target, const QPoint &targetOffset = QPoint(),
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
#if defined(Q_WS_WIN)
HDC getDC() const;
void releaseDC(HDC) const;
QPaintEngine *paintEngine() const;
#if defined(Q_WS_WIN)
virtual bool winEvent(MSG *message, long *result);
void create(WId = 0, bool initializeWindow = true,
bool destroyOldWindow = true);
void destroy(bool destroyWindow = true,
bool destroySubWindows = true);
这些里面,最想看看的应该是render函数了,看看Qt的图形引擎是个什么样子。
该函数提供了两个方式,分别是界面渲染和在图片上渲染,该方法首先对渲染条件做出判定,最终调用QWidgetPrivate类的drawWidget方法。在这里看到了很多对QPaintEngine类的调用,界面的主要绘制过程应该都来自这个类了。
好了,今天就到这里,毕竟是休息,少做一些分析了,明天继续,看看绘图引擎类的实现过程。
2009年11月4日星期三 23:09