Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Pass onCurrentIndexChanged Event to an object in Page1
QtWS25 Last Chance

Pass onCurrentIndexChanged Event to an object in Page1

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 3 Posters 3.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    davidino
    wrote on last edited by davidino
    #1

    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.

    ODБOïO 1 Reply Last reply
    0
    • D davidino

      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.

      ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #2

      @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)
      
          }
      
      1 Reply Last reply
      0
      • D Offline
        D Offline
        davidino
        wrote on last edited by davidino
        #3

        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.

        D 1 Reply Last reply
        0
        • D davidino

          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.

          D Offline
          D Offline
          davidino
          wrote on last edited by
          #4

          @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.

          1 Reply Last reply
          0
          • jpnurmiJ Offline
            jpnurmiJ Offline
            jpnurmi
            wrote on last edited by
            #5

            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.

            D 1 Reply Last reply
            2
            • jpnurmiJ jpnurmi

              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.

              D Offline
              D Offline
              davidino
              wrote on last edited by davidino
              #6

              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.

              1 Reply Last reply
              0
              • jpnurmiJ Offline
                jpnurmiJ Offline
                jpnurmi
                wrote on last edited by
                #7

                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.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  davidino
                  wrote on last edited by davidino
                  #8

                  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.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved