主窗口高度动画化时,巨大的闪烁

时间:2019-09-12 23:44:11

标签: qt animation qml flicker qt-quick

在Qt Quick应用程序中,我想在单击切换按钮时设置主窗口的高度动画,以便显示或隐藏一种托盘面板。主要表单内容包含标题框架,滑动视图和下方的网格视图。

为了达到理想的效果,我在我的qss代码中添加了以下动画,这些动画的运行取决于我的切换按钮状态:

ParallelAnimation
{
    id: one_dev_connected_toggle_window_height_increase
    running: false
    NumberAnimation { target: mainWindow; property: "height"; to: 750; easing.type: Easing.InOutQuad; duration: 500}
}

ParallelAnimation
{
    id: one_dev_connected_toggle_window_height_decrease
    running: false
    NumberAnimation { target: mainWindow; property: "height"; to: 450; easing.type: Easing.InOutQuad; duration: 500}
}

当我尝试打开托盘时,动画会在整个界面上引起巨大的闪烁。但是,当我合上托盘时,动画完全不会闪烁,并且效果也很平滑。

Flickering on opening tray

我的主窗口声明如下:

ApplicationWindow
{
    id: mainWindow
    visible: true
    width: 700
    height: 750
    color: "#000000"
    title: qsTr("Drag&Drop App")
    flags: Qt.Window | Qt.FramelessWindowHint

    ....

有人可以解释一下我为什么要面对这样的忽悠吗?我应该修改什么来解决它?

2 个答案:

答案 0 :(得分:1)

首先,我尝试使用以下小应用程序来重现您的行为:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char* argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    QQmlContext* context = engine.rootContext();
    // Adding the following line helps to remove the flickering
    app.setAttribute(Qt::ApplicationAttribute::AA_ShareOpenGLContexts, true);
    engine.load(QUrl("./data/main.qml"));
    return app.exec();
}

main.qml

import QtQuick 2.13
import QtQuick.Controls 2.5

ApplicationWindow {
    id: mainWindow
    width: 800; height: 1000
    title: "Animation Flickers"
    visible: true
    property bool large:true
    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (mainWindow.large) {
                decr.start()
            } else {
                incr.start();
            }
            mainWindow.large=!mainWindow.large;
        }
    }

    ParallelAnimation
    {
        id: incr
        running: false
        NumberAnimation { target: mainWindow; property: "height"; to: 750; easing.type: Easing.InOutQuad; duration: 500}
    }

    ParallelAnimation
    {
        id: decr
        running: false
        NumberAnimation { target: mainWindow; property: "height"; to: 450; easing.type: Easing.InOutQuad; duration: 500}
    }
}

然后,我激活了应用程序属性AA_ShareOpenGLContexts,并且闪烁消失了。闪烁可能有很多原因,而这可能只是其中一个原因。我已经经历了不合适的显卡驱动程序的闪烁。您还应该考虑在其他计算机上运行程序。

如果我的解决方案未能解决您的问题,请报告。

答案 1 :(得分:0)

使用这些参数,我终于找到了可以接受的解决方案。

这是我注意到的:

  • 在Aleph0的回复之后,我在OpenGL标志周围玩耍。我注意到使用Qt::ApplicationAttribute::AA_UseOpenGLES标志可以完全解决闪烁问题,但是在我的情况下却产生了一个奇怪的副作用:当主窗体的高度发生变化时,窗口中包含的所有组件的高度都变得不一致,从而引起了某种摇摆在动画期间,即使定义了正确的锚定以及最小和最大高度限制。
  • 在主界面上,我删除了锚点,而是使用了布局。这解决了高度变化期间的奇怪摆动,以及几乎所有的闪烁问题。我在具有不同操作系统的不同计算机上进行了测试,这种闪烁在某些特定情况下很少出现。
  • 但是,如果使用OpenGLES,则在使用布局时仍会出现摆动。

因此,就我而言,用布局替换锚点是解决方案,即使它不能完美运行。但是至少结果是可以接受的。