Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

DragHandler Translation Property Bug ?



  • Hello,

    I think there is a bug on DragHandler translation property.
    It seems that the translation is not reset when the handler go inactive. Then the next drag start with the translation of the previous drag.
    This causes sometimes visual artefacts when implementing a basic rectangle selection.

    Below, code to reproduce the issue.

    main.qml

    import QtQuick 2.14
    import QtQuick.Window 2.14
    
    Window
    {
        visible: true
        width: 1280
        height: 720
        title: qsTr("Hello World")
    
        //Selection rectangle
        Rectangle
        {
            id: componentContainerSelectID
            color: "orange"
            opacity: 0.5
            enabled: !isReady ? false : true
            visible: !isReady ? false : true
            x: !isReady ? 0.0 : (containerLeftDragHandler.translation.x < 0.0 ? containerLeftDragHandler.startCentroidPosX + containerLeftDragHandler.translation.x : containerLeftDragHandler.startCentroidPosX)
            y: !isReady ? 0.0 : (containerLeftDragHandler.translation.y < 0.0 ? containerLeftDragHandler.startCentroidPosY + containerLeftDragHandler.translation.y : containerLeftDragHandler.startCentroidPosY)
            width: !isReady ? 0.0 : (Math.abs(containerLeftDragHandler.translation.x))
            height: !isReady ? 0.0 : (Math.abs(containerLeftDragHandler.translation.y))
    
            property bool isReady: containerLeftDragHandler.active ? true : false
        }
    
        //Drag handler with left mouse button for selection rectangle
        DragHandler
        {
            id: containerLeftDragHandler
            target: null
            grabPermissions: PointerHandler.TakeOverForbidden
            acceptedButtons: Qt.LeftButton
            property real startCentroidPosX: 0
            property real startCentroidPosY: 0
    
            onActiveChanged:
            {
                if(active)
                {
                    console.log("containerLeftDragHandler is active with translation x = " + translation.x + ", y = " + translation.y);
                    startCentroidPosX = centroid.position.x;
                    startCentroidPosY = centroid.position.y;
                }
                else
                {
                    console.log("containerLeftDragHandler is inactive with translation x = " + translation.x + ", y = " + translation.y);
                }
            }
        }
    }
    
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    

    Console Log Output :
    cd37d0b3-19d2-4a12-b35c-052dc04904e4-image.png

    You can easily see that during the activation of the first drag, translation is 0 (and this is what I actually expect for all subsequent drags).
    But during the activation of the second drag, translation is not 0 and is the translation of the previous drag.
    This is what causes sometimes visual artefacts when starting dragging. But those artefacts are not always happen. I don't knwo why ?

    Can you please help me identify the issue ?
    Do I need to create a JIRA ticket to report the bug ?

    Thanks in advance for your help.



  • Hello,

    Nobody encounter the same issue ?
    Is it a bug ?

    Tks



  • Hello,

    I finally report the bug on JIRA :
    https://bugreports.qt.io/browse/QTBUG-81399?filter=-2

    Tks



  • Yep, this is probably a bug. If you want to go in unsafe way you can use quick-private module and some magic. Add this to yor *.pro file:

    quick-private
    

    Then extend default drag handler. I've used main.cpp for this, but better way to use a separate files:

    ...
    #include <QtQuick/private/qquickdraghandler_p.h>
    ...
    class CustomDragHandler : public QQuickDragHandler
    {
        Q_OBJECT
    public:
        explicit CustomDragHandler(QQuickItem* parent = nullptr)
            : QQuickDragHandler(parent) {}
    
    protected:
        void onActiveChanged() override {
            if (!active())
                setTranslation(QVector2D(0.0, 0.0));
            QQuickDragHandler::onActiveChanged();
        }
    };
    

    Register you custom type in main() function, lets say like this:

    qmlRegisterType<CustomDragHandler>("Test", 1, 0, "CustomDrag");
    

    In case of coding in main.cpp do not forget to add #include "main.moc" at the end of file (also probably you need to run qmake). Import import Test 1.0 in your qml file and use CustomDrag instead of DragHandler.
    Enjoy.



  • Thanks @IntruderExcluder for the suggestion. You're absolutely right :) I had never thought about it before.
    And this technique can be used for any Qt quick native type actually.


Log in to reply