QMLwindowresize/move闪烁
QML window resize/move flicker
我现在正在开发一个简单的 QML
应用程序,我注意到调整大小和移动 QML
window 与 QtWidgets
window,例如。
所以我创建了 2 个测试应用程序来显示差异:
QWidgets:
QML:
如您所见,QML
版本的应用程序闪烁得非常难看,而 QtWidgets
版本是干净的。现在,当您的 UI 变得越来越复杂时,这会变得非常丑陋。
你有这方面的知识吗?这是一个错误吗?这个问题有没有fix/workaround?
你可以试试这个:
int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
or
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
第一个选项使用 OpenGl2DirecX 角度库(如 Google Chrome)
第二个通过软件使用 OpenGL 仿真...对于小程序来说效果很好,并且 100% 兼容旧的 OS,例如 Windows XP。
注意:您可以尝试使用 Qt 5.7 和新的 Qtquick.Controls 2.0 ...性能更好...
https://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/
就我而言,我通过添加下一个标志解决了这个问题:
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
但这会增加其他渲染问题。还是不行。
调整 QML 应用程序大小的问题是关于用 过时的 几何更新 window。解决方法是同步更新和调整大小。
由于更新计时器可能会突然更新渲染场景图,可以随时更新window,因此会导致绘制的内容具有过时的几何图形。
https://bugreports.qt.io/browse/QTBUG-46074
应使用基本同步或扩展同步来同步调整大小和 window 更新。
当前基本同步在 Qt 中使用和实现,但仍需要将 window 更新(来自计时器)与来自 Windows 管理器的调整大小事件同步。
但是,一如既往,有一个问题列表:
当 window 调整大小过快时会出现问题。
由于同步事件(来自 WM)应该一致发送,下一个在上一个之后:
<= _NET_WM_SYNC_REQUEST 是从WM发来的,现在大小有变化。
_NET_WM_SYNC_REQUEST 由应用程序接收和处理。
<= 收到了一些其他事件,例如新几何体。
..更新内容,swapBuffers.
=> 已将 _NET_WM_SYNC_REQUEST_COUNTER 发送回 WM。
<= _NET_WM_SYNC_REQUEST 再次从WM发送,大小正在改变。
.. swapBuffers // 这就是问题所在,更新是在 window 改变其几何形状时执行的。
_NET_WM_SYNC_REQUEST 收到再处理
因此,当 (7) swapBuffers 在 _NET_WM_SYNC_REQUEST 发送后出现但尚未 received/processed 时出现问题。
最后得出结论:
- window 的实际大小调整是在 _NET_WM_SYNC_REQUEST 由 Window 经理发送后立即开始的。 而不是当应用程序收到它。 window 甚至可以在此时更新,当发送同步请求但应用程序尚未处理时。这将使用过时的几何图形绘制内容。
- _NET_WM_FRAME_DRAWN 可以帮助在调整大小和更新之间进行同步,但 Window 管理器也可能不支持(并且猜测不支持)。
换句话说,基本同步或扩展同步都无济于事(至少没有 _NET_WM_FRAME_DRAWN),因为无法知道实际调整大小何时完成。
扩展同步协议试图解决这个问题,但是由于几何的实际更改是在没有与客户端同步的情况下完成的,正如我所见,没有 _NET_WM_FRAME_DRAWN 总是有机会更新 window 具有过时的几何形状。
https://lists.freedesktop.org/archives/xcb/2019-February/011280.html
在 golang 中 therecipe/qt 这对我有帮助:
func main() {
var format = gui.NewQSurfaceFormat()
format.SetVersion(4, 5)
format.SetProfile(gui.QSurfaceFormat__CoreProfile)
format.SetRenderableType(gui.QSurfaceFormat__OpenGL)
format.SetSwapInterval(0)
format.SetDefaultFormat(format)
os.Setenv("QT_SCALE_FACTOR", "1")
ap := widgets.NewQApplication(len(os.Args), os.Args)
ap.SetApplicationName("APP 1.1")
系统:Linuxdebian 10
显卡:Radeon 570
但动画速度更快,因为并非所有帧都被渲染...
我现在正在开发一个简单的 QML
应用程序,我注意到调整大小和移动 QML
window 与 QtWidgets
window,例如。
所以我创建了 2 个测试应用程序来显示差异:
QWidgets:
QML:
如您所见,QML
版本的应用程序闪烁得非常难看,而 QtWidgets
版本是干净的。现在,当您的 UI 变得越来越复杂时,这会变得非常丑陋。
你有这方面的知识吗?这是一个错误吗?这个问题有没有fix/workaround?
你可以试试这个:
int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
or
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
第一个选项使用 OpenGl2DirecX 角度库(如 Google Chrome)
第二个通过软件使用 OpenGL 仿真...对于小程序来说效果很好,并且 100% 兼容旧的 OS,例如 Windows XP。
注意:您可以尝试使用 Qt 5.7 和新的 Qtquick.Controls 2.0 ...性能更好... https://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/
就我而言,我通过添加下一个标志解决了这个问题:
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
但这会增加其他渲染问题。还是不行。
调整 QML 应用程序大小的问题是关于用 过时的 几何更新 window。解决方法是同步更新和调整大小。
由于更新计时器可能会突然更新渲染场景图,可以随时更新window,因此会导致绘制的内容具有过时的几何图形。 https://bugreports.qt.io/browse/QTBUG-46074
应使用基本同步或扩展同步来同步调整大小和 window 更新。 当前基本同步在 Qt 中使用和实现,但仍需要将 window 更新(来自计时器)与来自 Windows 管理器的调整大小事件同步。
但是,一如既往,有一个问题列表:
当 window 调整大小过快时会出现问题。 由于同步事件(来自 WM)应该一致发送,下一个在上一个之后:
<= _NET_WM_SYNC_REQUEST 是从WM发来的,现在大小有变化。
_NET_WM_SYNC_REQUEST 由应用程序接收和处理。
<= 收到了一些其他事件,例如新几何体。
..更新内容,swapBuffers.
=> 已将 _NET_WM_SYNC_REQUEST_COUNTER 发送回 WM。
<= _NET_WM_SYNC_REQUEST 再次从WM发送,大小正在改变。
.. swapBuffers // 这就是问题所在,更新是在 window 改变其几何形状时执行的。
_NET_WM_SYNC_REQUEST 收到再处理
因此,当 (7) swapBuffers 在 _NET_WM_SYNC_REQUEST 发送后出现但尚未 received/processed 时出现问题。
最后得出结论:
- window 的实际大小调整是在 _NET_WM_SYNC_REQUEST 由 Window 经理发送后立即开始的。 而不是当应用程序收到它。 window 甚至可以在此时更新,当发送同步请求但应用程序尚未处理时。这将使用过时的几何图形绘制内容。
- _NET_WM_FRAME_DRAWN 可以帮助在调整大小和更新之间进行同步,但 Window 管理器也可能不支持(并且猜测不支持)。
换句话说,基本同步或扩展同步都无济于事(至少没有 _NET_WM_FRAME_DRAWN),因为无法知道实际调整大小何时完成。
扩展同步协议试图解决这个问题,但是由于几何的实际更改是在没有与客户端同步的情况下完成的,正如我所见,没有 _NET_WM_FRAME_DRAWN 总是有机会更新 window 具有过时的几何形状。
https://lists.freedesktop.org/archives/xcb/2019-February/011280.html
在 golang 中 therecipe/qt 这对我有帮助:
func main() {
var format = gui.NewQSurfaceFormat()
format.SetVersion(4, 5)
format.SetProfile(gui.QSurfaceFormat__CoreProfile)
format.SetRenderableType(gui.QSurfaceFormat__OpenGL)
format.SetSwapInterval(0)
format.SetDefaultFormat(format)
os.Setenv("QT_SCALE_FACTOR", "1")
ap := widgets.NewQApplication(len(os.Args), os.Args)
ap.SetApplicationName("APP 1.1")
系统:Linuxdebian 10 显卡:Radeon 570
但动画速度更快,因为并非所有帧都被渲染...