QT中模态和非模态问题

tt2com 2011-08-15 03:42:30
我看assist上面用
QWidget::setWindowModality();
但我的代码如下

test_d *a = new test_d;
a->setWindowModality(Qt::WindowModal);
a->show();

这样的话根本不是模态的,如果改成

test_d a;
a.setWindowModality(Qt::WindowModal);
a.show();

则会一闪而过啥都看不到,我的这个widget 我是想做一个类似window 弹出的模态对话框的样子,不过好像不行。
哪位大侠说说看?
...全文
2175 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
chrisforbt 2014-05-09
  • 打赏
  • 举报
回复
1、对QWidget设置模态窗口有两种方法: 第一种是在构造函数中 setWindowFlags(Qt::FramelessWindowHint); setAttribute(Qt::WA_showModal, true); 但这种方法已经在Qt4.5中被摒弃了,因为按照这样设置,对话框是无法使用触摸屏输入法的,只能用按键输入; 第二种是在构造函数中 setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); setWindowModality(Qt::WindowModal); 其中Qt::Dialog这个属性是要加的,因为这个属性会告诉Qt这个窗口是要被当做对话框对待的,从而实现预期的效果。而下面那个函数的参数有3种: Qt::NonModal :该窗口不是模态,不会阻塞其它界面接受输入信息; Qt::WindowModal:该窗口是一个当以层次的模态窗口,会阻塞它的父窗口、祖父窗口和各个兄弟窗口接受输入信息; Qt::ApplicationModal:该窗口是应用模态窗口,会阻塞所有窗口接受输入信息。 用第二种就能够在弹出来的对话框中接收输入法信息。 2、设置了模态却没有用的原因: 因为设置模态会的时候,Qt会根据当前窗口的父窗口是哪个,一步步往上找,然后将应该阻塞的全部阻塞,故没有效果的原因是没有父窗口。 比如在一个QWidget中new一个自定义对话框,该对话框设置为setWindowModality(Qt::WindowModal),然后将这个QWidget里面的按键clicked()信号和对话框的show()槽函数连接起来,一旦点击就show对话框。这样创建完后却发现窗口不是模态的,原因就是没有父窗口!首先对话框是不可能用布局将其管理起来,所以其父窗口是默认0。或许有些人说在new的时候将父窗口的this传进去了,但是模态窗口的属性是在对话框创建的时候确定的,可此时父窗口QWidget根本就还没有完全创建完,因此parent还是0,故设置对话框失效!解决办法就是自定义一个槽函数,当按键按下时才在槽函数里面创建对话框,此时QWidget已经创建完成,可以将this传入,这样就能够获得预想的结果。
hidxl 2014-02-28
  • 打赏
  • 举报
回复
34楼会导致消息栈逐步加深,用一下方法改进: Avc_set * pset = new Avc_set(this); Avc_set &set = *pset; set.setWindowFlags(Qt::Dialog); set.setWindowModality(Qt::WindowModality::WindowModal); set.setAttribute(Qt::WA_DeleteOnClose,true); set.show(); QEventLoop eventLoop(NULL); eventLoop.connect(&set,SIGNAL(destroyed ()),&eventLoop,SLOT(quit())); int ret = eventLoop.exec(QEventLoop::DialogExec);
hidxl 2014-02-21
  • 打赏
  • 举报
回复
可以这么写:测试有效,虽然还没明白原理. Avc_set set(this); set.setWindowFlags(Qt::Dialog); set.setWindowModality(Qt::WindowModality::ApplicationModal); set.show(); QEventLoop eventLoop(&set); eventLoop.exec(QEventLoop::DialogExec);
piaopiaolanghua 2013-10-26
  • 打赏
  • 举报
回复
下面的代码也可以: QWidget *testWidget = new QWidget; testWidget->setWindowFlags(Qt::Window); testWidget->setWindowModality(Qt::ApplicationModal); testWidget->show(); 是写在QMainWindow的构造函数中的,在其他地方不知道行不行,可以试一下。
piaopiaolanghua 2013-10-26
  • 打赏
  • 举报
回复
实践证明,这样就可以设置模态了。 pMdiSubWindow->setWindowFlags(Qt::Window); pMdiSubWindow->setWindowModality(Qt::ApplicationModal);
Ibanezsc 2013-09-11
  • 打赏
  • 举报
回复
搜到这个帖子了,眼前一亮,可是各位朋友,QMainWindow怎么设置为模态呢,查了很多例子发现好像不能。各位大神能不能指点下。
xiaoqiyong617 2013-01-24
  • 打赏
  • 举报
回复
楼主你好 我也遇到这样的问题 关于QWidget模态设置的问题。。 QWidget *get_qwidget; get_qwidget = new QWidget; //get_qwidget->setWindowFlags(windowFlags() &~ Qt::WindowMinMaxButtonsHint);//取消窗口最小化功能 //get_qwidget->setWindowModality(Qt::ApplicationModal);//在对qwidget 操作时,不能操作其他东西 get_qwidget->setMaximumSize(615,150); get_qwidget->setMinimumSize(615,150); get_qwidget->setWindowTitle("Get data"); get_qwidget->move ((QApplication::desktop()->width() - get_qwidget->width())/2,(QApplication::desktop()->height() - get_qwidget->height())/2); //让子窗口显示在中央 get_qwidget->show();//弹出新的qwidget_1 这个模态咋设置的呀?怎么不管用呀?
tt2com 2013-01-24
  • 打赏
  • 举报
回复
引用 29 楼 xiaoqiyong617 的回复:
楼主你好 我也遇到这样的问题 关于QWidget模态设置的问题。。 QWidget *get_qwidget; get_qwidget = new QWidget; //get_qwidget->setWindowFlags(windowFlags() &~ Qt::WindowMinMaxButtonsHint);//取消窗口最小化功能……
你啥都没设 想有啥子
引用 26 楼 tt2com 的回复:
QWidget 可以使用为模态形式由 setAttribute(Qt::WA_ShowModal, true); 进行设置。 使用setWindowModality()也可以达到要求 一开始没有设置对提出的QWidget设置父类及 QWidget t(0,Qt::Window);这样设置无法完成模式对话框的工作,将父类设置了就能够形成模式对话框。 对于……
我在26楼已经提供的解决办法
TDB1111 2012-12-14
  • 打赏
  • 举报
回复
引用 15 楼 foxyz 的回复:
你show以后马上a->exec() 建立消息循环。
这个可以,我试过!!!虽然不懂
blueliuyun 2011-09-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 dbzhang800 的回复:]
引用 10 楼 tt2com 的回复:

引用 9 楼 dxms8 的回复:

test_d类继承mainWindow应该也可行,总之test_d要是个windows,setWindowModality才会有效

也就是说需要类似window或者dialog等的基类,这个模态的才起作用?

不对,任何一个QWidget的派生类都可以设置模态还是非模态。


注意:setWin……
[/Quote]
3Q!
测试了……ok!
tt2com 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 dbzhang800 的回复:]

引用 22 楼 tt2com 的回复:

[Quote=引用 21 楼 dbzhang800 的回复:]

另外,可以瞅瞅这个 http://blog.csdn.net/dbzhang800/article/details/6300519

对于Qdialog我可以理解,但我使用Qwidget,我按

QWidget a(0,Qt::Window);
a……
[/Quote]
恩我先研究下 在试试,上午太忙没有认真看
dbzhang800 2011-08-16
  • 打赏
  • 举报
回复
顺便补充一点(我一直希望你自己能反应过来):

你一开始提到的代码:
a->setWindowModality(Qt::WindowModal);
a->show();

对于QDialog来说,等效的效果是:
a->open();

而不是
a->exec();

大部分人回答时,显然没注意到对话框是 3中显示方式,show()、open()、exec() (后面两个需要调用第一个,相信大家都没有异议,毕竟,显示还是隐藏一个widget,只能通过setVisible(bool)这个函数,show() 是它的马甲)

你也没注意到 模式设置有3个值,而你用的是最不常用的一个。

再就是,

模态在不同的平台下可能会有不同的效果,比如在X11下,同样是模态窗口,和Win32下的行为有很大差异,这个不是Qt所能控制的。
dbzhang800 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 tt2com 的回复:]

[Quote=引用 21 楼 dbzhang800 的回复:]

另外,可以瞅瞅这个 http://blog.csdn.net/dbzhang800/article/details/6300519
[/Quote]
对于Qdialog我可以理解,但我使用Qwidget,我按

QWidget a(0,Qt::Window);
a.setWindowModal……
[/Quote]
看来我前面都白说了,...,认真看看我第一次给你连接,有你需要的所有东西!!

1. 一个QWidget 是否模态只取决于一个属性,任何一个Widget都可以设置
2. QDialog::exec()究竟做了什么,我在帖子中都重复一遍了。
3. 不要受其他人误导(以讹传讹 的危害太过强大,对此,我是一点办法都没有...)
tt2com 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 dbzhang800 的回复:]

另外,可以瞅瞅这个 http://blog.csdn.net/dbzhang800/article/details/6300519
[/Quote]
对于Qdialog我可以理解,但我使用Qwidget,我按

QWidget a(0,Qt::Window);
a.setWindowModality(Qt::WindowModal);

还是不能使用为模态的,还有你们都说应用exec()
但exec并非QWidget的内部成员,根本就调用不来的啊。

还是我一开始就问错了,QWidget本来就没有模态和非模态,对于模态和非模态的定义
只用
QDialog 和MFC 对于对话框来定义模态非模态一样?
dbzhang800 2011-08-16
  • 打赏
  • 举报
回复
dbzhang800 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 tt2com 的回复:]

引用 18 楼 victory200888 的回复:

同意15楼的说法,使用show()显示的是非模态的,用exec()的是模态,这和C++里面还是有点区别的

你实践过没?widget你如何调用exec?
[/Quote]
15 的说法是错的 ,exec() 是启动局部的事件循环,如果你看了我前面的给的链接,我想,无论怎么变化,都难不倒你。

QDialog::exec()
不就是做了3步了:

1. 设置model属性
2. 调用 show()
3. 启动事件循环


而对于任何一个QWidget,你都可以做这3步!!!
tt2com 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 victory200888 的回复:]

同意15楼的说法,使用show()显示的是非模态的,用exec()的是模态,这和C++里面还是有点区别的
[/Quote]
你实践过没?widget你如何调用exec?
victory200888 2011-08-16
  • 打赏
  • 举报
回复
同意15楼的说法,使用show()显示的是非模态的,用exec()的是模态,这和C++里面还是有点区别的
dxms8 2011-08-16
  • 打赏
  • 举报
回复
刚看了下文档,Qt4.5中Qt::WA_ShowModal已经不推荐使用了,改用QWidget::windowModality代替,而QWidget::windowModality又是只对windows有效的。其实生成个windows也很简单,只要QWidget构造函数的第2个参数QWidget::windowModality设成Qt::Window就可以了。
方法可以很多,至于具体如何抉择就看情况吧~~
dxms8 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 dbzhang800 的回复:]
引用 10 楼 tt2com 的回复:

引用 9 楼 dxms8 的回复:

test_d类继承mainWindow应该也可行,总之test_d要是个windows,setWindowModality才会有效

也就是说需要类似window或者dialog等的基类,这个模态的才起作用?

不对,任何一个QWidget的派生类都可以设置模态还是非模态。


注意:setWin……
[/Quote]
哦哦,这么说来QWidget也是可以直接设置模态的,关键是要用setAttribute(Qt::WA_ShowModal, true),而不是setWindowModality()了。
加载更多回复(16)

16,203

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧