【问题标题】:QML window resize/move flickerQML 窗口调整大小/移动闪烁
【发布时间】:2015-08-29 09:32:06
【问题描述】:

我现在正在开发一个简单的QML 应用程序,我注意到与QtWidgets 窗口相比,调整和移动QML 窗口的大小和移动会产生难看的闪烁。

所以我创建了 2 个测试应用程序来显示差异:

QWidgets:

QML:

如您所见,QML 版本的应用程序闪烁非常难看,而QtWidgets 版本则干净。现在,当您的 UI 变得越来越复杂时,这会变得非常难看。

你有这方面的知识吗?这是一个错误吗?此问题是否有任何修复/解决方法?

【问题讨论】:

  • 您使用哪种显卡?
  • @Milovidov 我正在使用集成在英特尔酷睿 i5-3360M 中的集成英特尔高清显卡 4000。
  • 英特尔的 OpenGL 实现有问题。尝试在没有 OpenGL 的情况下获取或编译 qt。在这种情况下,Qt Quick 将绘制为原生小部件,例如 qt 小部件解决方案。
  • 另外,您可以尝试更新您的显卡驱动程序。
  • 我希望我有你的问题。您应用的用户多久调整一次窗口大小?

标签: qt qml qt5 qt-quick qtquickcontrols


【解决方案1】:

你可以试试这个:

int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
or
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);

第一个选项使用 OpenGl2DirecX 角度库(如 Google Chrome)

第二个使用软件的OpenGL模拟...对于小程序运行非常好,并且与Windows XP等旧操作系统100%兼容。

注意:您可以尝试使用 Qt 5.7 和新的 Qtquick.Controls 2.0 ...性能更好... https://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/

【讨论】:

  • 在我的装有 Qt 5.6.2 和 Intel Graphics 4000 的 Windows 7 PC 上试用过。使用 Qt::AA_UseOpenGLES 性能要好得多!谢谢!
【解决方案2】:

QML 应用程序大小调整的问题在于用过时 几何图形更新窗口。解决方法是同步更新和调整大小。

由于更新计时器可能会突然更新到渲染场景图,它可以随时更新窗口,因此会导致绘制带有过时几何图形的内容。 https://bugreports.qt.io/browse/QTBUG-46074

应使用基本同步或扩展同步来同步调整大小和窗口更新。 目前在 Qt 中使用并实现了基本同步,但仍需要将窗口更新(来自计时器)与来自 Windows 管理器的调整大小事件同步。

但是,与往常一样,存在一系列问题:

当窗口大小调整过快时会出现问题。 由于应该一致地发送同步事件(来自 WM),因此下一个在上一个之后:

  1. _NET_WM_SYNC_REQUEST 由应用接收和处理。

  2. .. 更新内容,swapBuffers。

  3. => 将 _NET_WM_SYNC_REQUEST_COUNTER 发送回 WM。

  4. .. swapBuffers // 这里是问题所在,更新是在窗口改变其几何形状时执行的。

  5. _NET_WM_SYNC_REQUEST 已收到并再次处理。

因此,当 (7) swapBuffers 出现在 _NET_WM_SYNC_REQUEST 发送但尚未接收/处理之后,就会出现问题。

最后的结论:

  • 窗口的实际大小调整是在 _NET_WM_SYNC_REQUEST 由窗口管理器发送后立即开始的。 而不是在应用程序接收到它时。此时窗口甚至可以在发送同步请求时更新,但尚未由应用程序处理。这将使用过时的几何图形绘制内容。
  • _NET_WM_FRAME_DRAWN 可以帮助在调整大小和更新之间进行同步,但窗口管理器可能不支持(并且猜测它不支持)。

换句话说,无论是基本同步还是扩展同步都无济于事,(至少没有 _NET_WM_FRAME_DRAWN),因为无法知道实际调整大小的时间。

扩展同步协议试图解决这个问题,但由于几何的实际更改是在没有与客户端同步的情况下完成的,正如我所见,没有 _NET_WM_FRAME_DRAWN 总是有机会用过时的几何更新窗口。

https://lists.freedesktop.org/archives/xcb/2019-February/011280.html

【讨论】:

    【解决方案3】:

    就我而言,我通过添加下一个标志解决了这个问题:

    QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
    

    但这会增加其他渲染问题。或者不。

    【讨论】:

      【解决方案4】:

      在 golang 配方/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")
      

      系统:Linux debian 10 显卡:Radeon 570

      但动画更快,因为并非所有帧都被渲染...

      【讨论】:

        猜你喜欢
        • 2014-12-29
        • 1970-01-01
        • 2018-09-07
        • 1970-01-01
        • 2016-03-19
        • 1970-01-01
        • 2018-07-27
        • 2022-10-13
        • 2019-01-09
        相关资源
        最近更新 更多