想让一个Widget成为模态,我们只需要对其设置:

setAttribute(Qt::WA_ShowModal, true);

注意:这是QWidget的成员函数 ,也就是说,QWidget可以显示为模态或非模态!

setWindowModality

除了直接调用setAttribute外,QWidget 提供了一个易用的函数,来设置窗体的模态。其源码如下:

void QWidget::setWindowModality(Qt::WindowModality windowModality)
{
data->window_modality = windowModality;
// setModal_sys() will be called by setAttribute()
setAttribute(Qt::WA_ShowModal, (data->window_modality != Qt::NonModal));
setAttribute(Qt::WA_SetWindowModality, true);
}

注意:该函数的参数取值:NonModal、WindowModal、ApplicationModal 分别对应默认情况下的

  • QDialog::show()
  • QDialog::open()
  • QDialog::exec()

如果你没有使用QDialog::open()的需求,你可能也不需要该函数。

setModal

除了QWidget提供的成员,QDialog 提供了 setModal 的成员函数,我们看看其代码:

void QDialog::setModal(bool modal)
{
setAttribute(Qt::WA_ShowModal, modal);
}

不用解释了吧?我们要显示模态对话框,只需要类似下面的代码:

QDialog * dlg = new QDialog();
dlg->setAttribute(Qt::WA_ShowModal, true);
dlg->show();

exec()

有问题是不?为啥exec() 直接可以显示模态对话框呢?看QDialog源代码吧

int QDialog::exec()
{
Q_D(QDialog);
...
setAttribute(Qt::WA_ShowModal, true);
...
show();
...
QEventLoop eventLoop;
(void) eventLoop.exec(QEventLoop::DialogExec);
...
}

看到答案没:exec() 先设置modal属性,而后调用 show() 显示对话框,最后启用事件循环

事件循环

Qt 程序时事件驱动的,每个程序,我们需要调用 QApplication::exec() 来启用事件循环。

int QCoreApplication::exec()
{
...
QEventLoop eventLoop;
int returnCode = eventLoop.exec();
...
return returnCode;
}

用前面的 QDialog::exec() 一样,都是调用的 QEventLoop::exec()

int QEventLoop::exec(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
...
while (!d->exit)
processEvents(flags | WaitForMoreEvents | EventLoopExec);
...
return d->returnCode;
}

bool QEventLoop::processEvents(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
if (!d->threadData->eventDispatcher)
return false;
if (flags & DeferredDeletion)
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
return d->threadData->eventDispatcher->processEvents(flags);
}

进一步:这将调用平台相关的函数,比如在windows下

bool QGuiEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
{
if (!QEventDispatcherWin32::processEvents(flags))
return false;
if (configRequests) // any pending configs?
qWinProcessConfigRequests();
return true;
}

事件循环和线程没有必然的联系,事件循环可以用在QThread中,而且从Qt4.4开始,QThread的run函数默认就调用了自己的事件循环。

对与QDialog来说,当它自己的QEventLoop启用时,主程序的 QEventLoop 当然是处于暂停状态了。说到底,就是两个死循环,一个在内,一个在外,只有里面的退出后,外边的循环才会执行。不过由于两个循环执行的命令是基本一样的,都是调用并处理程序收到的各种事件,所以,可能变得不容易理解

http://doc.qt.io/qt-4.8/qwidget.html

想让一个Widget成为模态,我们只需要对其设置setAttribute(Qt::WA_ShowModal, true);的更多相关文章

  1. Qt - QDialog,QWidget实现模态及非模态(模态Widget不能有父窗口,如果设置无边框就不能阻塞父窗口,但是可以强行设置指定Qt::Dialog,还可以setAttribute(Qt::WA_ShowModal),很多讲究)good

    在Qt中QDialog为“窗口”,而QWidget为“部件”,首先还是了解下<Qt 窗口与部件的概念>. 对于 QDialog 的模态及非模态是直接可以实现的,很多课本中都会提到,此处总结 ...

  2. “医疗信息化行业之中的联发科”- 我们在医疗行业中的定位及目标 想做一个面对中小企业的专业上游软件供应商 台湾联发科技颠覆掉的是一个封闭的手机产业系统 解决方案,即AgileHIS.NET数字化医院基础方案

    “医疗信息化行业之中的联发科”- 我们在医疗行业中的定位及目标   我们做中国医疗信息化行业之中的联发科 ---我们在医疗行业中的定位及目标 从我个人来讲,我从2001年到现在这10年之间基本上一直在 ...

  3. 可想实现一个自己的简单jQuery库?(九)

    Lesson-8 事件机制 在讲事件机制之前呢,我们有一个很重要的东西要先讲,那就是如何实现事件委托(代理). 只有必须先明白了如何实现一个事件委托,我们才能更好的去实现on和off.在我看来,on和 ...

  4. 35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n

      35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现in ...

  5. QScrollArea可以帮助我们实现让一个widget的内容带有滚动条(QWidget里内置QScrollArea,QScrollArea里再内置其它QWidget)

    使用QScrollArea可以帮助我们实现让一个widget的内容带有滚动条,用户可以通过拖动滚动条来查看更多内容, 代码示例如下: 1.带有滚动条的widget列表 #include "w ...

  6. Javascript里,想把一个整数转换成字符串,字符串长度为2

    Javascript里,想把一个整数转换成字符串,字符串长度为2.  想把一个整数转换成字符串,字符串长度为2,怎么弄?比如 1 => "01"11 => " ...

  7. 你想建设一个能承受500万PV/每天的网站吗?服务器每秒要处理多少个请求才能应对?

    你想建设一个能承受500万PV/每天的网站吗?服务器每秒要处理多少个请求才能应对? 你想建设一个能承受500万PV/每天的网站吗? 500万PV是什么概念?服务器每秒要处理多少个请求才能应对?如果计算 ...

  8. 你想建设一个能承受500万PV/每天的网站吗?

    (如果感觉有帮助,请帮忙点推荐,添加关注,谢谢!你的支持是我不断更新文章的动力.本博客会逐步推出一系列的关于大型网站架构.分布式应用.设计模式.架构模式等方面的系列文章) 你想建设一个能承受500万P ...

  9. 想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研

    想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研 http://blog.csdn.net/testing_is_believing/article/details/22 ...

随机推荐

  1. 简洁常用权限系统的设计与实现(四):不维护level,用递归方式构造树

    第三篇中,我们通过维护节点的深度level,通过迭代所有的节点,只需要一次,就构造了树.  本篇,换一种方式. 好处是:不维护节点的深度level,增加和修改节点时,也不用维护.递归实现,代码比较清晰 ...

  2. svn X在Xcode中使用

    1 在终端输入命令:清除以前的svn链接地址( /Users/mac/Desktop/SHiosProject/SVNmangerfiles) nie-xiao-bo-mac-pro:~ mac$ s ...

  3. POJ 1985 - 树的直径

    传送门 题目大意 给一颗n个点的树,求树的直径(最长的一条链) 题解 先随便找一个点u,dfs出离它最远的点v 于是有以下情况: 直径就是这条链 直径经过u,是这条链的延长 直径不经过u 只需要从v再 ...

  4. matlab 高级函数 —— colfilt/blockproc (图像)矩阵的分块处理

    colfilt 执行功能与 blockproc/nlfilter 类似,但效率更高. B = colfilt(A,[m n],block_type,fun),block_type:distinct/s ...

  5. Js之全局函数

    全局函数 encodeURI()decodeURI()encodeURIComponent()decodeURIComponent()escape()unescape()eval() String() ...

  6. 2013级别C++文章9周(春天的)工程——运算符重载(两)

    课程主页中:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 [程序阅读]阅读程序"简单C++学生 ...

  7. 《深入浅出WPF》笔记——资源篇

    原文:<深入浅出WPF>笔记--资源篇 前面的记录有的地方已经用到了资源,本文就来详细的记录一下WPF中的资源.我们平时的“资源”一词是指“资财之源”,是创造人类社会财富的源泉.在计算机程 ...

  8. opengl实现直线扫描算法和区域填充算法

    总体介绍 1.   使用线性扫描算法画一条线,线性离散点 2.   利用区域填充算法画多边形区域,区域离散的点 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel H ...

  9. Servlet 3.1实践

    Servlet 3.1 新特性详解 参考: IBM developerworks: Servlet 3.0 新特性详解 开涛的博客: Servlet3.1规范(最终版) 关键特性 Asynchroni ...

  10. Touch panel DTS 分析(MSM8994平台,Atmel 芯片)

    Touch panel DTS 分析(MSM8994平台,Atmel 芯片) 在MSM8994平台,Touch panel的DTS写节点/kernel/arch/arm/boot/dts/qcom/m ...