Subtyping the default type in a theme, Controls 2



  • Let's say I have a custom type, e.g. MyComboBox.qml:

    ComboBox {
        myProperty:...
        function...
        delegate: ItemDelegate {...}
    }
    

    In e.g. Material theme I have to implement it:

    ComboBox {
        myProperty:...
        function...
        delegate: MenuItem {...}
    }
    

    But is it possible to inherit the original default version in the theme like this (e.g. +material/MyComboBox.qml):

    MyComboBox { //inheriting the default MyComboBox
        delegate: MenuItem {...}
    }
    

    so that I don't have to implement the same functionality (properties, functions in the upper level) second time, only those things which are needed to be changed for the theme? I tried it in several ways, importing e.g. "..", "qrc:/myComponents/" or something like that, but got different kinds of errors. Has anyone actually done this or otherwise know how it would work (no wild guessing, please...)?



  • When you implement a Qt Quick Controls 2 style, your ComboBox.qml is literally registered as the ComboBox type in the QtQuick.Controls namespace. The other styles are not registered at all, and not known by the QML type system. Therefore there is no way to inherit other styles when implementing Qt Quick Controls 2 styles.

    On a related note, in Qt 5.7, a partial style implementation (eg. missing Button.qml) always used the Default style as a fallback. Since Qt 5.8, it's possible to call QQuickStyle::setFallbackStyle() to select the Material or Universal style as a fallback. This allows you to customize/extend the built-in styles, but full implementations of the customized controls are still needed.

    The only way to do partial customization for a specific control from the built-in styles is to basically create a new type. That is, you run the app with the one of the built-in styles and then you have a local QML composite type like MyComboBox.qml that inherits the Qt Quick Controls ComboBox type.



  • @jpnurmi
    Thanks for the knowledgeable answer. I'm not sure I understood everything, but here's my version of it: When the engine loads your types it searches in (for example) +material folder. If the type is found, it is registered but the default type with the same name in the upper level directory will not be visible at all in any way. So the type in /+material/X.qml can't see the the type /X.qml at all. But if there's no /+material/ implementation for a type at all it can be seen in types which are in /+material/. I tested a workaround with simple project structure:

    /MyComboBox_base.qml:

    import QtQuick 2.0
    import QtQuick.Controls 2.1
    ComboBox {
        property int someProperty: 0
    }
    

    /MyComboBox.qml:

    import QtQuick 2.0
    import QtQuick.Controls 2.1
    MyComboBox_base {
        id: control
        delegate: ItemDelegate {
            text: control.someProperty
        }
    }
    

    /+material/MyComboBox.qml:

    import QtQuick 2.0
    import QtQuick.Controls 2.1
    import QtQuick.Controls.Material 2.1
    MyComboBox_base {
        id: control
        delegate: MenuItem {
            text: control.someProperty
        }
    }
    

    And it worked! To avoid copypasting later edits this would be enough, but it's a bit cumbersome and leads to more messy project tree.

    Have I invented a new design pattern for Quick Components 2?



  • It seems that we are talking about slightly different things here. You were basically talking about using file selectors in general, whereas I was talking about the Qt Quick Controls 2 styling system that is based on file selectors. Sorry for the confusion.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.