Search code examples
qtqt-quickqtquick2qtquickcontrols

Extending TabViewStyle styleData


I am currently trying to find a nicer way to do this, add an icon to a tab. Right now I am piggy backing off the styleData.title to include the icon source, but it would be nice to be able to extend the styleData so I can include other custom properties.

Here is my current hack:

Tab {
    ...
    title: "Home|images/home-75.png"
    ...
}

style: TabViewStyle {
    ...
    tab: Rectangle {
        ...
        Text {
            ...
            text: styleData.title.split("|")[0]
            ...
        }
        Image {
            ...
            source: styleData.title.split("|")[1]
        }
    }
}

However it would be much nicer to just do this:

Tab {
    ...
    title: "Home"
    source: "images/home-75.png"
    ...
}

style: TabViewStyle {
    ...
    tab: Rectangle {
        ...
        Text {
            ...
            text: styleData.title
            ...
        }
        Image {
            ...
            source: styleData.source
        }
    }
}

Here is the application markup as is:

import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1

ApplicationWindow {
    visible: true
    width: 320
    height: 480

    TabView {
        id: tabwidget
        x: 0
        y: 0
        tabPosition: Qt.BottomEdge
        width: parent.width
        height: parent.height

        Tab {
            id: homeTab
            title: "Home|images/home-75.png"
            source: "images/home-75.png"
            component: Qt.createComponent("Page2.qml")
        }

        Tab {
            id: inboxTab
            title: "Inbox|images/home-75.png"
            component: Qt.createComponent("Page3.qml")
        }

        Tab {
            id: outboxTab
            title: "Outbox"
            source: "images/home-75.png"
            component: Qt.createComponent("Page3.qml")
        }

        Tab {
            id: settingTab
            title: "Settings"
            source: "images/home-75.png"
            component: Qt.createComponent("Page3.qml")
        }

        style: TabViewStyle {
            frameOverlap: 0
            tab: Rectangle {
                color: "#F6F6F7"
                border.width: 0
                implicitWidth: (parent.control.width + 3) / 4
                implicitHeight: 88
                radius: 0
                CustomBorder
                {
                    commonBorder: false
                    lBorderwidth: 0
                    rBorderwidth: 0
                    tBorderwidth: 1
                    bBorderwidth: 0
                    borderColor: "#bababc"
                }
                Text {
                    id: text
                    anchors.bottom: parent.bottom
                    anchors.horizontalCenter: parent.horizontalCenter
                    text: styleData.title.split("|")[0]
                    color: styleData.selected ? "#ff3b30" : "#8e8e8f"
                }
                Image {
                    id: img
                    width: 75
                    height: 75
                    source: styleData.title.split("|")[1]
                }
            }
        }
    }
}

Solution

  • Create component IconTab.qml

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    
    Tab {
        property url iconSource
    }
    

    Then replace all your Tabs width IconTabs, e.g.

    IconTab {
        id: outboxTab
        title: "Outbox"
        iconSource: "images/home-75.png"
    }
    

    And get the icon's source in the TabViewStyle via:

    Component.onCompleted: {
        console.log("title: " + styleData.title)
        console.log("title: " + tabwidget.getTab(styleData.index).title)
        console.log("icon: " + tabwidget.getTab(styleData.index).iconSource)
    }
    

    Btw. check out the documentation for Tab.source and Tab.sourceComponent. Tab.component should not work. At least, it is not documented.