您的位置:首页 > 编程语言 > Qt开发

[原]Qt/Qtopia源代码分析之应用程序窗口的显示层次

2008-01-05 10:29 323 查看
本次分析是通过源代码来搞清楚以下的Qt窗口特性,以下特性是通过测试得到的:

1) 新弹出的全屏窗口(指使用了QWidget::showFullScreen方法显示的窗口)能覆盖已经存在的全屏窗口,以及所有其它窗口(包括带WStyle_StaysOnTop属性的窗口)

2)当一个全屏窗口正在显示,而这时如果有其它的窗口被激活(调用QWidget::setActiveWindow)时,这个全屏窗口会被隐藏,一个有窗口的应用程序被启动时,因为它的主窗口会被激活,因此也会隐藏掉正在显示的全屏窗口

3)一个带WStyle_StaysOnTop窗口弹出时,会覆盖掉其它带WStyle_StaysOnTop属性的窗口和不带WStyle_StaysOnTop属性的窗口,但不能覆盖全屏窗口(指使用了QWidget::showFullScreen方法显示的窗口)

----------------------------------------------------------------------------------------------------------------------

代码分析:
针对为什么新弹出的全屏窗口能覆盖正在显示的全屏窗口以及所有其它窗口(包括带WStyle_StaysOnTop属性的窗口),而新弹出的非全屏窗口就算有WStyle_StaysOnTop也不能覆盖正在显示的全屏窗口,针对些特性看了一下代码,发现全屏窗口确实得到了“优待” :)
1、我们是调用showFullScreen来显示一个全屏窗口的,在showFullScreen()
函数中会设置fullscreen=1, 并调用raise();
void QWidget::showFullScreen()
{
...
if ( !isTopLevel() )
return;
topData()->fullscreen = 1;
resize( qApp->desktop()->size() );
raise();
show();
setActiveWindow();
}
2、在下面的raise函数中,全屏窗口的属性被设置为值2
void QWidget::raise()
{
...
int al = topData()->fullscreen ? 2 :
testWFlags(WStyle_StaysOnTop) ? 1 : 0;
qwsDisplay()->setAltitude( winId(), al, TRUE);
}
3、setAltitude函数最后会触发 QWSServer类的invokeSetAltitude函数的调用,这里invokeSetAltitude函数要走的分支是调用 raiseWindow 来显示窗口,
再往下看,全屏窗口就是raiseWindow函数中得到了优待, 只要altitude为2,全屏窗口总是插入到窗口列表的最前面,不管屏幕上正在显示什么窗口,如果不是全屏窗口(即altitude不为2的分支),会用新窗口与当前列表中的窗口进行比较,如果新窗口带 WStyle_StaysOnTop标志,就插入到所有全屏窗口后面的第一个位置,如果不带 WStyle_StaysOnTop 标志,则窗口会被插入到所有全屏窗口和所有WStyle_StaysOnTop 标志窗口的后面
void QWSServer::raiseWindow( QWSWindow *changingw, int alt )
{
if ( changingw->d->altitude == 2 ) {
windows.prepend( changingw ); //QList::prepend函数是将节点插入到列表的最前面
} else {
// insert after "stays on top" windows
bool in = FALSE;
w = windows.first();
while ( w ) {
if ( (changingw->onTop && w->d->altitude != 2 ) || !w->onTop ) {
windows.insert( windows.at(), changingw );
in = TRUE;
break;
}
w = windows.next();
}
if ( !in )
windows.append( changingw );
}
}

当一个全屏窗口正在显示,而这时如果有其它的窗口被激活(调用QWidget::setActiveWindow)时,这个全屏窗口会被隐藏,一个有窗口的应用程序被启动时,因为它的主窗口会被激活,因此也会隐藏掉正在显示的全屏窗口,全屏窗口到底在什么地方被隐藏呢?
经过分析,找到了主要的代码位于qapplication_qws.cpp中的 QApplication::qwsProcessEvent函数中,如下:
case QWSEvent::Focus:
if ( ((QWSFocusEvent*)event)->simpleData.get_focus ) {
...
} else { //窗口失去了焦点的分支
if ( widget == desktop() || !active_window || widget != active_window)
return TRUE; // not interesting
if (widget->topData()->fullscreen) { //如果是全屏窗口失去焦点,则做一些手脚
bool endFullScreen = TRUE;
if ( widget->children() ) {
...
}
if (endFullScreen)
widget->hide(); //全屏窗口在这里被隐藏
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐