1

In a Qt Quick application, I want to animate the main window height when I click on a toggle button, in order to show or hide a kind of tray panel. The main form content contains a header frame, a swipe view and a grid view below it.

To reach the desired effect, I added the following animations in my qss code, which are run depending of my toggle button state:

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}
}

When I try to open the tray, the animation cause a huge flickering on my whole interface. However, when I close the tray, the animation cause no flickering at all, and the effect is smooth, as I expected.

Flickering on opening tray

My main window is declared as follow:

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

    ....

Can someone explain me why I'm facing a such flickering? What should I change to fix it?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Jean-Milost Reymond
  • 1,833
  • 1
  • 15
  • 36

2 Answers2

1

First I tried to reproduce your behavior with a small app, which is listed below:

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}
    }
}

Then I activated the application attribute AA_ShareOpenGLContexts and the flickering vanished. There might be many reasons for flickering and this might just remove one reason. I already experienced flickering by a non fitting graphics card driver. You should also consider to run your program on a different machine.

Please report back, if my solution didn't solved your problem.

Aleph0
  • 5,816
  • 4
  • 29
  • 80
  • 1
    Thank you for the reply, unfortunately this doesn't work for me. The issue seems in fact to be widely known (e.g I tried to search "qt quick fix resize flickering" on Google). It's as if the background was erased every time or if the widgets weren't double buffered, pointing thus a probable configuration issue. However I tried several solution I found, none of them worked for me. The strangest thing is that I created the exact same application interface with standard Qt Widgets, and the issue never appeared. Do you have any further idea about that? – Jean-Milost Reymond Sep 13 '19 at 15:20
  • 1
    @Jean-MilostReymond: Did you tried my program and did you tried my program on a different machine? It is very difficult for me to help you, as I reproduced the error on my machine and setting the window attribute resolved the issue. Maybe you can try all OpenGL related application attributes. https://doc.qt.io/qt-5/qt.html#ApplicationAttribute-enum – Aleph0 Sep 16 '19 at 06:33
  • Yes I tried the app you mentioned, it doesn't flick at all on my computers, with or without the AA_ShareOpenGLContexts flag. I also played around them in my app. A flag like double-buffering should be missing in my window configuration, it's the only logical reason I can find to explain why the content of my app flickers this way. I spanned hours to search on the web, without success, unfortunately. I only found answers like that: https://stackoverflow.com/questions/30818886/qml-window-resize-move-flicker/, but I sincerely don't understood how to apply such solutions in my case... – Jean-Milost Reymond Sep 17 '19 at 23:45
1

Playing with the parameters, I finally found an acceptable solution.

Here's what I noticed:

  • Following the Aleph0's reply, I played around the OpenGL flags. I noticed that using the Qt::ApplicationAttribute::AA_UseOpenGLES flag resolved completely the flickering, however it caused a strange side effect in my case: the height of all components contained in my window became inconsistent while the main form height changed, causing a kind of wobbling during the animation, even with the correct anchoring and min and max height constraints defined.
  • On my main interface I removed the anchoring and used layouts instead. This resolved the strange wobbling during the height change, and almost all the flicker issues. I tested on different computers with different OS, the flickering appear only rarely in several particular cases.
  • However the wobbling still appears while the layouts are used if OpenGLES is used.

So replacing anchors by layouts was the solution in my case, even if it works not perfectly. But at least the result is acceptable.

Jean-Milost Reymond
  • 1,833
  • 1
  • 15
  • 36