Pass onCurrentIndexChanged Event to an object in Page1



  • Hello everybody,
    as explain in "Custom Qlabel show Videocamera on different thread", I made a QtQuick Control application where a QThread is used for displaying camera frames, for not overloading the GUI thread. The application has two pages at the moment, and I pass from one to the other with a SwipeView Type, contained in main.qml.
    Basically I need to stop the QThread handled by videocamera object in Page1, when I sift to Page2 and I need to restart it vice versa. Unfortunately in main.qml I cannot see videocamera object, so I don't know how to pass the event onCurrentIndexChanged to videocamera.
    Can you enlight me?

        SwipeView {
            id: swipeView
            anchors.fill: parent
            currentIndex: tabBar.currentIndex
    
            Page1 {
    
            }
    
            Page2 {
    
            }
            
            onCurrentIndexChanged: 
    // I want to pass the event to videocamera QtObject contained in Page1, but I don' know how to do it.
        }
    

    Thank you.



  • @davidino hi,

    Do you mean something like this ?

       SwipeView {
            id: swipeView
            anchors.fill: parent
          
    
            Rectangle {
                color :"green"
               
     QtObject{
                    id:videocamera 
                    signal viewIndexChanged(var newIndex)
                    onViewIndexChanged: console.log("signal recived with arg :" + newIndex)
                }
    
            }
    
            Rectangle {
                color: "blue"
    
            }
    
            onCurrentIndexChanged: videocamera .viewIndexChanged(currentIndex)
    
        }
    


  • Hello LeLev,
    Maybe I've been misunderstood. Below you can find the following files that could help to clarify the situation:

    • main.qml, is the main QML file that handle the page changing and show a footer common to all the pages.
    • Page1Form.ui.qml, is the QML file where only graphics objects of Page1 are placed.
      Page1.qml, is the QML file where only the logic part for Page1 is placed (there is no logic at the moment).

    main.qml

    ApplicationWindow {
        visible: true
        width: 480
        height: 320
    
        SwipeView {
            id: swipeView
            anchors.fill: parent
            currentIndex: tabBar.currentIndex
    
            Page1 {
    
            }
    
            Page2 {
    
            }
        }
    
        footer: TabBar {
            id: tabBar
            width: parent.width
            height: 35
            currentIndex: swipeView.currentIndex
            TabButton {
                text: qsTr("Webcam")
                font.family: "Helvetica"
                font.pointSize: 13
                font.bold: true
            }
            TabButton {
                text: qsTr("Gpio")
                font.family: "Helvetica"
                font.pointSize: 13
                font.bold: true
            }
        }
    }
    
    

    Page1Form.ui.qml

    Item {
        id: item1
        width: 480
        height: 320
    
        Rectangle {
            id: rectangle
            anchors.fill: parent
    
            RowLayout {
                id: rowLayout
                spacing: 2
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
    
                Videocamera {
                    id: videocamera
                    width: 350
                    height: 250
                    x: 0
                    y: 0
                }
            }
        }
    }
    
    

    The custom object videocamera has been created with c++ code and it's has been registered in main.cpp with the following:

    qmlRegisterType<VideoCamera>("VideocameraLib", 1, 0, "Videocamera");
    

    Inside videocamera.cpp there is a QThread. Basically I need to pass in the c++ code, the event that the page has changed. More specifically when the current page is Page1, I need to start the thread, I need to stop it otherwise.
    The problem is that main.qml doesn't see the objects contained in Page1Form.ui.qml, so I cannot pass the event to videocamera.cpp.
    On the other side, I could easiily pass events from Page1Form.ui.qml to videocamera.cpp since it's its direct child.
    Maybe I need to pass the event to Page1 first, and then pass it to videocamera?
    Thank you.



  • @davidino
    Hello everyone,
    after some time of test, I found a solution. I have to give an id to each page, after that I can access Page1 children as follow:

            Page1 {
                id: pager1
            }
    
            Page2 {
                id: pager2
            }
    
            onCurrentIndexChanged: pager1.videocamera.pageChanged(currentIndex)
    

    Hope that can be useful to someone, maybe it's easy but for me, as a newbie, it required some time.



  • You can use SwipeView.isCurrentItem attached property to query whether the page is the current item in view. That way, you can create a nice and clean declarative binding to control whether the camera is active. For example:

    Item {
        id: page1
    
        VideoCamera {
            active: page1.SwipeView.isCurrentItem
        }
    }
    

    Just notice that the SwipeView attached properties are available on the root items of the pages that are added to the view, not on arbitrary grandchildren inside the pages. That is, the root items of Page1 and Page2, not their children.



  • Hello @jpnurmi
    I tried the method that you suggest but it didn't work, the property active doesn't exist (Videocamera is a QQuickPaintedItem, don't know if that the reason) and naming the Item page1, I haven't got SwipeView, see screenshot below.

    0_1517158605492_4608a042-0c09-4193-b481-6b2e01cf7d69-immagine.png

    Let me know if you have any suggestions.
    Thank you.



  • I tried the method that you suggest but it didn't work, the property active doesn't exist (Videocamera is a QQuickPaintedItem, don't know if that the reason)

    It was more like a pseudo snippet. We don't know the API of your custom VideoCamera type.

    The custom object videocamera has been created with c++ code and it's has been registered in main.cpp...

    Based on this, I assumed that the API was in your control. What you do currently to start and stop the video camera is not visible in the above snippets, so I just wrote an imaginary example how it could be controlled in a declarative way, with a simple boolean property in your VideoCamera type.



  • Hello jpurmi, thank you for your post.
    Now I learned the meaning of Q_PROPERTY for creating custom types from C++ code to QML.
    I've added the "active" property for Videocamera but, unfortunately, from Page1Form.ui.qml, I cannot see SwipeView.isCurrentItem property contained in main.qml:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    import VideocameraLib 1.0
    
    Item {
        id: page1
        width: 480
        height: 320
    
        Videocamera {
            id: videocamera
            width: 350
            height: 250
            x: 0
            y: 0
            active: page1.SwipeView.isCurrentItem 
    // it doesn't see SwipeView, nor id:swipeView of the item in main.qml
        }
    

    Am I missing something else?
    Thank you.


Log in to reply
 

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