I'm very new to Qt, and right now struggling to figure out how to change the index of the SwipeView through a different C++ class. I'd like to make some kind of a signal that emits from the C++ class saying "Swipe Right" or something like that, and having the SwipeView respond. I'm also new to signals and slots, so I might be misunderstanding how they work.
1 Answer
When you want to control a QML
element from C ++ the best strategy is to create a QObject
that has Q_PROPERTY
, slot and signals and export it to QML
through setContextProperty()
, and perform the direct binding or use Connections to connect the signals, in this case it is only necessary to emit a signal and connect it in QML
.
In the following example I show how to change to the right or left using QPushButton:
main.cpp
#include <QApplication>
#include <QPushButton>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QHBoxLayout>
class SwipeManager: public QObject{
Q_OBJECT
public:
using QObject::QObject;
public slots:
void moveToRight(){
emit toRight();
}
void moveToLeft(){
emit toLeft();
}
signals:
void toRight();
void toLeft();
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
SwipeManager manager;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("manager", &manager);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QWidget w;
QPushButton left("to left");
QPushButton right("to right");
QHBoxLayout *lay = new QHBoxLayout(&w);
lay->addWidget(&left);
lay->addWidget(&right);
QObject::connect(&left, &QPushButton::clicked, &manager, &SwipeManager::moveToLeft);
QObject::connect(&right, &QPushButton::clicked, &manager, &SwipeManager::moveToRight);
w.show();
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
Window {
visible: true
width: 640
height: 480
title: qsTr("SwipeView Test")
SwipeView {
id: view
anchors.fill: parent
currentIndex: 4
Repeater {
model: 10
Loader {
active: SwipeView.isCurrentItem || SwipeView.isNextItem || SwipeView.isPreviousItem
sourceComponent: Item{
Text {
text: "Page: "+index
anchors.centerIn: parent
}
}
}
}
}
Connections{
target: manager
onToRight: if(view.currentIndex + 1 != view.count) view.currentIndex += 1
onToLeft: if(view.currentIndex != 0) view.currentIndex -= 1
}
PageIndicator {
id: indicator
count: view.count
currentIndex: view.currentIndex
anchors.bottom: view.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
The complete example can be found in the following link.