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