Qt:窗口界面不刷新,模态对话框不显示等问题

任何问题,只要能重现,就离解决不远了。

最初发现这个问题时,一直放着没管,毕竟程序尚在早期开发阶段。今天抽空看了一下,也网络搜索了一下。网络的看法,基本上是围绕 setAttribute(Qt::WA_Mapped) 这个进行处理,个人感觉怪怪的。所以,本人倾向于是Qt5的bug,但Qt5已经发布多年,能有这样的bug实不应该,所以这种可能性很小。

几种出现这个bug的情况:

  1. 模态弹窗触发

QWidget * pWnd = new MyWidget();MyWidget的构造函数里面有个初始化,初始化时加载配置,加载配置失败弹出模态对话框。

将pWnd再加入到父窗口。

实际上,由于初始化的模态弹窗,后面设置父窗口实际没执行,所以,这个模态弹窗的顶层父窗口就是 MyWidget,而 MyWidget在初始化过程中,实际是隐藏的,进而导致模态弹窗也是不可见的(实际情况是可见,但是如果断点调试,切换回去就看不到了)。

所以,本质是,由于无父窗口的模态弹窗,改变了程序应该有的逻辑,导致整个Qt的事件循环出现了错误,进而导致UI刷新问题。

解决方法有多种。比如 new MyWidget(this) ,new的时候就设置父窗口。或者new之后,不初始化,而是设置父窗口之后再初始化。

起初,虽然知道有这样的问题存在,但认为和窗口不刷新两者无直接关系,所以想着先解决窗口不刷新的问题。实际两个问题是同一个问题。

2. 也是模态弹窗触发

模态弹窗,然后里面再模态弹窗,然后按ESC键关闭两个模态弹窗,之后,也会出现主窗口的界面不刷新的问题。实际这也是一种错觉。

一般,窗口不刷新,在windows平台,多为调用了winId()这个函数。该函数会将窗口转换为windows原生控件。而在模态弹窗时,同样由于窗口设置了父窗口,但还没显示时,此时调用winId,实际是会将父窗口也转换为windows的native原生窗口。此时,当模态弹窗关闭之后,父窗口已经不再是原先的父窗口,实际是,从模态弹窗被创建之后就这样了,只是模态弹窗阻塞了鼠标键盘事件,给人的感觉就是模态弹窗关闭之后父窗口才出问题。

解决方法,可以在模态弹窗初始化时,先调用show再调用winId,如果还要exec,也可以之后再exec。

 

 

有偿解决C++编程遇到的问题,项目定制开发,联系邮箱:[email protected]

转载请注明来源,谢谢。


老刀的技术日志 » Qt:窗口界面不刷新,模态对话框不显示等问题

发表评论