解决Qt使用动画更改窗口大小时窗口内部件闪烁的问题

生命不息, 趟坑不止. 还好都能解决, 可喜可贺.
先来说下这次踩的又是什么坑吧, 当你使用QPropertyAnimation修改windowsize的时候, window内的widget会出现闪烁的现象, 当时的猜测应该是因为widget没有参加到渲染中去, 但是就是不知道该怎么解决, 今天还真被我证实了我的猜测是正确的, 挺高兴的呢, 下面就来说下解决方案, 其实就一行代码, 现实就往往是这么残酷, o(╯□╰)o

官方解释

Native Widgets vs Alien Widgets

Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing system. They do not have a native window handle associated with them. This feature significantly speeds up widget painting, resizing, and removes flicker.

Should you require the old behavior with native windows, you can choose one of the following options:

  • Use the QT_USE_NATIVE_WINDOWS=1 in your environment.
  • Set the Qt::AA_NativeWindows attribute on your application. All widgets will be native widgets.
  • Set the Qt::WA_NativeWindow attribute on widgets: The widget itself and all of its ancestors will become native (unless Qt::WA_DontCreateNativeAncestors is set).
  • Call QWidget::winId to enforce a native window (this implies 3).
  • Set the Qt::WA_PaintOnScreen attribute to enforce a native window (this implies 3).

原文地址: http://doc.qt.io/qt-5/qwidget.html

英语渣这里就不翻译了, 大概意思就是Qt 4.4里面引用了一种机制可以消除闪烁的现象, 但是不知道为什么在5.0之后又移除了这个功能, 只做一个选项供大家使用(Ps: 这一点上文并没有提到, 但是联想到这是Qt5的文档应该也能想到, 但是我还是找到了有人在社区的提问, 单是没人回, 这就很微妙了->_->传送门)

解决方法

上文已经说了不过我这里还是写一下, 都是我测试过的哦..
上文中提到的方法, 我只试了两个, 其他的并未尝试, 故不做说明, 见谅

全局设置

作用于整个应用

1
qApp->setAttribute(Qt::AA_NativeWindows, true);

单个设置

作用于单个QWidget

1
widget->setAttribute(Qt::WA_NativeWindow, true);

注意

当全局设置该属性后, 会导致QTextEditQPlainTextEdit无法输入中文

参考资料

http://doc.qt.io/qt-5/qwidget.html
https://forum.qt.io/topic/22933/qt5-resize-or-animation-of-qmainwindow-causes-flicker