全部博文(584)
分类: C/C++
2011-01-23 23:22:51
类管理图形用户界面应用程序的控制流和主要设置。 可以说 是的整个后台管理的命脉
它包含主事件循环,在其中来自窗口系统和其它资源的所有事件被处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理。它也处理绝大多数系统范围和应用程序范围的设置。
对于任何一个使用的图形用户界面应用程序,都正好存在一个对象,而不论这个应用程序在同一时间内是不是有0、1、2或更多个窗口。
对象是可以通过全局变量访问。它的负责的主要范围有:
* 它执行事件处理,也就是说它从低下的窗口系统接收事件并且把它们分派给相关的窗口部件。通过使用sendEvent()和(),你可以发送你自己的事件到窗口部件。
* 它分析命令行参数并且根据它们设置内部状态。关于这点的详细情况请参考下面的构造函数文档。
* 它定义了由QStyle对象封装的应用程序的观感。在运行状态下,可以通过setStyle()来改变。
* 它指定了应用程序如何分配颜色。详细情况请参考setColorSpec()。
* 它定义了默认文本编码(请参考setDefaultCodec())并且提供了通过translate()用户可见的本地化字符串。
* 它提供了一些像desktop()和clipboard()这样的魔术般的对象。
* 它知道应用程序的窗口。你可以使用widgetAt()来询问在一个确定点上存在哪个窗口部件,得到一个()(顶级窗口部件)的列表和通过closeAllWindows()来关闭所有窗口,等等。
* 它管理应用程序的鼠标光标处理,请参考setOverrideCursor()和setGlobalMouseTracking()。
* 在X窗口系统上,它提供刷新和同步通讯流的函数,请参考flushX()和syncX()。
* 它提供复杂的对话管理支持。这使得当用户注销时,它可以让应用程序很好地结束,如果无法终止,撤消关闭进程并且甚至为未来的对话保留整个应用程序的状态。 详细情况请参考isSessionRestored()、sessionId()、commitData()和saveState()。
应用程序排演实例包含了一个通常用法的典型完整的main()。
因为对象做了如此多的初始化,它必须在所有与用户界面相关的其它类被创建之前被创建。
因为它也处理命令行参数,在应用程序中对解释和修改之前创建它通常是一个好主意。(注意,也对于X11,setMainWidget()可以根据-geometry选项来改变主窗口部件。为了保持这个功能,你必须在setMainWidget()和它的任何重载之前设置你的默认。)
二、QApplication两类构造的讲解QApplication::QApplication ( int & , char ** )初始化窗口系统并且使用在中的个命令行参数构造一个应用程序对象。
全局指针指向这个应用程序对象。应该只有一个应用程序对象被创建。
这个应用程序对象必须在任何绘制设备(包括窗口部件、像素映射、位图等等)之前被构造。
注意argc和argv也可以被改变。Qt会移除它能够识别的命令行参数。原来的argc和argv稍后可以通过qApp->argc()和qApp->()来访问。()的文档中包含如何处理命令行参数的详细描述。
调试选项(如果被使用被定义的QT_NO_DEBUG标记进行编译,这些选项就是不可用的):
更详细的解释请参考调试技术。
所有的Qt程序自动支持下面这些命令行选项:
X11版本的Qt也支持传统的X11命令行选项:
构造一个使用中个命令行参数的应用程序对象。如果为真,图形用户界面应用程序被构造,否则非图形用户界面(命令行)应用程序被创建。
对于没有图形用户界面的程序,设置为假可以在没有窗口系统的情况下运行。
在X11下,如果为真,窗口系统被初始化。如果为假,应用程序不连接X服务器。在Windows和Macintosh,现在窗口系统总是被初始化,而不管的值。在Qt未来的版本这也许会改变。
对于线程配置(也就是说当Qt已经被作为线程库建立),应用程序全局互斥量在构造函数中将被锁定并且当使用()进入事件循环中时解锁。如果你不调用(),你必须明显地对这个互斥量解锁,否则你将会在应用程序退出时得到警告。
下面这个例子显示如何创建在可能情况下使用图形界面的应用程序。
在方面,对于独立的1个进程,lication 提供的成员函数有(多进程的,这里暂不介绍):
QDesktopWidget * ::desktop () [静态]桌面窗口部件对于获得屏幕大小很有用。在桌面上绘制也是可能的。我们建议不要假设可以在桌面上绘制,因为它不能在所有的操作系统上工作。
这个列表必须使用new来被创建并且必须被调用者删除。
如果没有窗口部件,这个列表为空(QPtrList::isEmpty())。
注意一些窗口部件也许被隐藏。
更新所有窗口部件的实例:
这个列表是使用new创建的并且必须由调用者删除。
如果没有顶级窗口部件,这个列表是空的(QPtrList::isEmpty())。
注意一些顶级窗口部件也许被隐藏了,例如如果当前没有工具提示被显示的工具提示。
实例:
lication 的事件循环,就是MainLoop的事件循环,当然它的原理和的原理是一样的。
void QCoreApplication::processEvents ( ::ProcessEventsFlags flags = ::AllEvents ) [static]Processes all pending events for the calling thread according to the specified flags until there are no more events to process.
You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file).
In event you are running a local loop which calls this function
continuously, without an event loop, the DeferredDelete events will not
be processed. This can affect the behaviour of widgets, e.g. QToolTip,
that rely on DeferredDelete events to function properly. An alternative
would be to call sendPostedEvents() from within that local loop.
Calling this function processes events only for the calling thread.
大体意思就是预先调用处于队列状态的事件,直到全部处理完毕。这个函数大多用于系统繁忙时,导致一些事件被延后了(如绘制事件等),用此函数可保证全部事件处理完毕后在继续执行。常见于show(),update()之后调用。
Note: 这个函数
关于事件的发送有两种方式:
1、bool ::sendEvent ( * receiver, QEvent * event ) [静态]这个事件在它被发送时,不能被删除。通常的访问方式是在栈中创建这个事件,例如:
QMouseEvent me( QEvent::MouseButtonPress, pos, 0, 0 );
::sendEvent( mainWindow, &me );
如果你在堆中创建这个事件,你就必须删除它。
这个时间必须在堆中被分配,因为递送事件队列将会得到事件的所有权并且一旦它被递送就删除它。
当控制返回主事件循环,存储在队列中的所有事件将被使用notify()函数发送。
基本上大部分的地方都是用到sendEvent, 而少部分地方会用到, 研究的童鞋可以多看看这方面的资料