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

Not possible to reset a `date` property?



  • I understand the proper way to reset a qt property in qml is by assigning undefined to it. This does not seem possible with the date type. I need to do this both for properties defined in qml and in my c++ models which appropriately use the QDateTime type.

    Here is a simple example:

    import QtQuick 2.12
    import QtQuick.Controls 2.5
    import QtQuick.Layouts 1.12                                                                                                                                                           
    
    ColumnLayout {
    
        property date myDate
    
        Button {
            text: 'Reset'
            onClicked: {
                print('Default value:', myDate)
                myDate = undefined
                print('After reset attempt:', myDate)
            }
        }
    }
    

    which prints the following output:

    qml: Default value: Invalid Date
    file:///Users/patrick/dev/pkdiagram/test.qml:14: Error: Cannot assign [undefined] to QDateTime
    

    The evidence suggests that there are only two states for a date property: 1) Invalid Date - no idea what value that implies though it is the default, 2) a valid Date object.

    Then what is the reset state and how do you achieve it? It seems like that default ought to be something similar to a null QDateTime()?


  • Moderators

    @patrickkidd
    I haven't tested it, but my guess would be

    myDate = new Date()
    


  • @J.Hilk said in Not possible to reset a `date` property?:

    @patrickkidd
    I haven't tested it, but my guess would be

    myDate = new Date()
    

    Unfortunately, constructing a new Date object sets it to today's date, at least in the implementation included in qml.



  • @patrickkidd
    I don't know anything about QML, but I do know about JavaScript. So don't know if this helps, but....

    In JS Date object has no "invalid" state. new Date() always sets to date now. In Qt QDate::QDate() "Constructs a null date. Null dates are invalid.".

    I don't know how you marry those two, as they are incompatible, and I don't really know why you need "to reset a date property". But if, for whatever reason, it gives you that error about undefined, have you at least tried myDate = null, which is valid in JS and maybe is acceptable to QML, whatever that is doing behind the scenes?



  • @JonB said in Not possible to reset a `date` property?:

    @patrickkidd
    I don't know anything about QML, but I do know about JavaScript. So don't know if this helps, but....

    In JS Date object has no "invalid" state. new Date() always sets to date now. In Qt QDate::QDate() "Constructs a null date. Null dates are invalid.".

    I don't know how you marry those two, as they are incompatible, and I don't really know why you need "to reset a date property". But if, for whatever reason, it gives you that error about undefined, have you at least tried myDate = null, which is valid in JS and maybe is acceptable to QML, whatever that is doing behind the scenes?

    Yes, this question pertains quite closely to Qt and Qml as opposed to ECMAScript. JS Date objects are automatically converted to QDateTime when passed to Qt properties in C++. Qt properties have a reset function, and so an arbitrary reset state. Assigning undefined to a Qt property via Qml triggers a special condition where it calls the reset function on the property. So my question pertains to the fact that assigning undefined to properties defined in qml with the date type seems to act weird.



  • @patrickkidd
    And trying assigning null instead of the rejected undefined does not hack it?



  • @JonB said in Not possible to reset a `date` property?:

    @patrickkidd
    And trying assigning null instead of the rejected undefined does not hack it?

    Doesn't work. You get the same error but for nullptr.


  • Qt Champions 2018

    A workaround could be to set an invalid QDateTime as a contextProperty and assign your date to that.

    engine.rootContext()->setContextProperty("invalidDate", QDateTime());
    You can then do qmlDate = invalidDate

    property date qmlDate
    
    Component.onCompleted: {
        print(qmlDate);
        qmlDate = new Date();
        print(qmlDate);
        qmlDate = invalidDate;
        print(qmlDate);
    }
    

    This outputs:

    qml: Invalid Date
    qml: mer. juil. 17 11:57:49 2019 GMT+0200
    qml: Invalid Date
    


  • @GrecKo said in Not possible to reset a `date` property?:

    A workaround could be to set an invalid QDateTime as a contextProperty and assign your date to that.

    engine.rootContext()->setContextProperty("invalidDate", QDateTime());
    You can then do qmlDate = invalidDate

    property date qmlDate
    
    Component.onCompleted: {
        print(qmlDate);
        qmlDate = new Date();
        print(qmlDate);
        qmlDate = invalidDate;
        print(qmlDate);
    }
    

    This outputs:

    qml: Invalid Date
    qml: mer. juil. 17 11:57:49 2019 GMT+0200
    qml: Invalid Date
    

    That is a pretty cool idea. The only thing it leaves out is the final goal of my question, which is to find a way to call the reset function on my C++ QDateTime property from qml.


  • Qt Champions 2018

    If you have a property with a RESET function, it will be called if you assign undefined to it.

    I tested it with a C++ class exposed to QML.



  • @GrecKo said in Not possible to reset a `date` property?:

    If you have a property with a RESET function, it will be called if you assign undefined to it.

    I tested it with a C++ class exposed to QML.

    I figured out the right way to do this. I used a var property instead of a date property. , which doesn't perform the Qml-side type checking and properly passes the undefined value back to the model in my onDateChanged handler:

    Something like this:

    ColumnLayout {
        property var date
        property var model: null // set in C++
        onDateChanged: {
            if(model)
                model.date = date // calls C++ `date` custom reset function designated with Q_PROPERTY when `date` is undefined
        }
        Button {
            text: 'Set to today'
            onClicked: {
                date = new Date
            }
        }
        Button {
            text: 'Reset property'
            onClicked: {
                date = undefined // no type checking now
            }
        }
    }
    

Log in to reply