Search code examples
qtqmlqtquick2qtquickcontrolsqtquickcontrols2

QML - Not able to canvas.requestPaint() from a function


I am a beginer and i am not getting how to call canvas.requestPaint() in My QML ,Code is below:

//myTab.qml

TabView {
    id: tv
    width: parent.width
    height: parent.height
    antialiasing: true

    style: TabViewStyle {
        frameOverlap: -1

        tab: Rectangle {              
            color: "Transparent"
            implicitWidth: text1.width + 50
            implicitHeight: 20
            radius: 2
            smooth: true
            Canvas {
                id: canvas1
                anchors.fill: parent
                width: parent.width
                height: parent.height
                onPaint: {
                    styleData.selected ? drawTab(canvas1,"#0C3142") :
                                         drawTab(canvas1,"Transparent") //Some custom JS function to draw a object
                }                 

                Text {
                    id: text1
                    height: parent.height
                    verticalAlignment: Text.AlignVCenter
                    anchors.left : parent.left
                    anchors.leftMargin: 15
                    text: styleData.title
                    color: "white"
                }
            }
        }

        frame: Rectangle {
            width: parent.width
            height: parent.height
            color: "Transparent"
            border.color:"white"
        }
        tabBar: Rectangle {
            color: "Transparent"
            anchors.fill: parent
        }
    }

    Tab {
        id: tab1
        title: "Tab1"
    }
    Tab{
        id: tab2
        title: "Tab2"
    }

    onCurrentIndexChanged: {
        console.log("index changed "+currentIndex)
        canvas1.repaint() //ERRROR - not defind canvas1
    }
}

When i try to use in onCurrentIndexChanged, I am getting the following error:

ReferenceError: canvas1 is not defined.

Please Suggest.


Solution

  • You have the id canvas1 in another scope, as the tab-style is a Component and the ID therefore not necessarily unique for the TabView. It might be instantiated multiple times.

    I have little experience with the TabView, so there might be another solution. I however would declare a signal: refresh in the TabView which I trigger, whenever I want to repaint.

    Then I'd use a Connections-element within the Canvas to connect to this signal to execute the repaint

    Example:

    TabView {
        id: tv
        width: parent.width
        height: parent.height
        antialiasing: true
    
        signal refresh // *** DEFINE SIGNAL HERE
    
        style: TabViewStyle {
            frameOverlap: -1
    
            tab: Rectangle {
                color: "Transparent"
                implicitWidth: text1.width + 50
                implicitHeight: 20
                radius: 2
                smooth: true
                Canvas {
                    id: canvas1
                    anchors.fill: parent
                    width: parent.width
                    height: parent.height
                    onPaint: {
                        styleData.selected ? drawTab(canvas1,"#0C3142") :
                                             drawTab(canvas1,"Transparent") //Some custom JS function to draw a object
                    }
    
                    function drawTab() { // *** I DONT KNOW WHAT SHOULD BE DONE HERE
                        console.log('do nothing')
                    }
    
                    // *** CONNECT TO SIGNAL HERE ***
                    Connections {
                        target: tv
                        onRefresh: canvas1.requestPaint() // *** repaint is not a function.
                    }
    
                    Text {
                        id: text1
                        height: parent.height
                        verticalAlignment: Text.AlignVCenter
                        anchors.left : parent.left
                        anchors.leftMargin: 15
                        text: styleData.title
                        color: "white"
                    }
                }
            }
    
            frame: Rectangle {
                width: parent.width
                height: parent.height
                color: "Transparent"
                border.color:"white"
            }
            tabBar: Rectangle {
                color: "Transparent"
                anchors.fill: parent
            }
        }
    
        Tab {
            id: tab1
            title: "Tab1"
        }
        Tab{
            id: tab2
            title: "Tab2"
        }
    
        onCurrentIndexChanged: {
            console.log("index changed "+currentIndex)
            refresh() // *** INVOKE SIGNAL HERE
        }
    }