I have tried with
widget->setProperty("text1Text", QVariant("After..."));
in my C++,
and
Button
{
property alias text1Text: text1.text
Text
{
id: text1
text: "Initial"
}
}
in qml.
widget is a QQuickWidget object. What am I doing wrong?
See Interacting with QML Objects from C++.
If you are using QQmlEngine:
// Using QQmlComponent
QQmlApplicationEngine engine;
...
QObject * root = engine.rootObjects().first();
If you are using QQuickView:
QQuickView view;
...
QObject * root = view.rootObject();
Getting text1:
// Update Qml file
Text
{
id: text1
text: "Initial"
objectName: id
}
// Find text1 in c++
QObject * o1 = root->findChild<QObject *>(QStringLiteral("text1"));
QQuickItem *text1 = qobject_cast<QQuickItem*>(o1);
// Set property
text1->setProperty("text", QVariant());
Related
I have a QML ListView and I want to access to the delegate children in c++
main.qml
ApplicationWindow {
objectName: "wnd1"
ListView {
objectName: "mediaPlayerListView"
model: provider.mediaPlayerItems
delegate: MediaPlayerDelegate
}
}
MediaPlayerDelegate.qml
Row {
objectName: "mainRow"
VideoOutput {
objectName: "videoOutput" + modelData.id
}
Here is the c++ code I've tried
QString currentId = "1";
QQuickWindow *mainWindow = _qmlAppEngine->rootObjects()[0]->findChild<QQuickWindow *>("wnd1");
QObject *mediaPlayerListView = mainWindow->findChild<QObject *>("mediaPlayerListView");
QObject *mediaPlayerListViewDelegate = mediaPlayerListView->property("delegate").value<QObject *>();
I want to be able to get in cpp the videoOutput, doing something like this
QObject *videoOutput = mediaPlayerListViewDelegate->findChild<QObject *>("videoOutput" + currentId)
But I can't access further than the delegate, it has no children.
In my Qt5.9 widget application project (Windows), I added a QQuickWidget in the ui and set the source file to a QML file.
My itention is to display open street maps in the QQuickWidget. By clicking a button, the center location of the map should change to specific lat/long coordinates.
The map gets displayed in the QQuickWidget as expected, however, I can't get the location change by button click to work.
I am using this QML file content to display the map:
//================================
// map.qml
//================================
import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6
Item {
id: qmlMap
Plugin {
id: osmPlugin
name: "osm"
}
Map {
id: map
anchors.fill: parent
plugin: osmPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 10
objectName: "mainMap"
MapQuickItem {
id: marker
coordinate {latitude: 59.91
longitude: 10.75}
anchorPoint.x: image.width * 0.5
anchorPoint.y: image.height
sourceItem: Image {
id: image
height: 35
width: 35
source: "geotag.png"
}
function recenter(lat,lng) {
map.clearMapItems();
marker.coordinate.latitude = lat;
marker.coordinate.longitude = lng;
map.addMapItem(marker);
map.center.latitude = lat;
map.center.longitude = lng;
map.update();
}
}
}
}
On application start up, I can see the OSM centered on my specified location and I also can see the marker at the right location.
Loaded map on start up
However, when I click my button to call the function recenter(lat,lng) from C++, nothing seems to happen (no location change on map visible).
My C++ button code for location change is:
void mapproject::on_btnUpdatePos_clicked()
{
QQmlEngine engine;
QQmlComponent component(&engine, "qrc:/map.qml");
QObject *object = component.create();
QVariant returnedValue;
QVariant pos = QVariant(0);
if(object != NULL){
QMetaObject::invokeMethod(object, "recenter",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, pos),
Q_ARG(QVariant, pos));
}
}
Why does the location change not work? Is there a mistake in my QML file or in my C++ code?
Assuming that the QQuickWidget has been added through Qt Designer and it is called quickWidget, so you can access it using ui->quickWidget.
To do a simple search you can set an objectName in the MapQuickItem:
MapQuickItem {
id: marker
objectName: "mapItem"
coordinate {latitude: 59.91
[...]
You should not create a new component, you should use the QQuickWidget, the first thing is to get the item that shows the QQuickWidget through the rootObject() method, then look for the child named mapItem and invoke the recenter method:
void MainWindow::on_btnUpdatePos_clicked()
{
QQuickItem *item = ui->quickWidget->rootObject();
QObject *object = item->findChild<QObject*>("mapItem");
QVariant posx = QVariant(-12.0464);
QVariant posy = QVariant(-77.0428);
if(object != NULL){
QMetaObject::invokeMethod(object, "recenter",
Q_ARG(QVariant, posx),
Q_ARG(QVariant, posy));
}
}
The complete example can be found in the following link
Hi Guys, i need take the text of TextField QML then pass to QString in C++.
Firstpage.qml:
Component {
id: mainView
Row {
Image {
id: logo
anchors.fill: parent
source: "Imagens/jscalcadosLogo.png"
}
ColumnLayout {
id: layoutLogin
anchors.centerIn: parent
anchors.margins: 3
spacing: 3
TextField {
id: login
objectName: "login"
Layout.fillWidth: true
placeholderText: "Username"
}
Main.cpp:
int main(int argc, char *argv[]){
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickView *view = new QQuickView;
view->setSource(QUrl::fromLocalFile("FirstPage.qml"));
QObject *object = view->rootObject();
QObject *textin = object->findChild<QObject*>("login");
//QString input = textin->Property("text").toString(); // crash the program
return app.exec();
}
When i try convert Textin to QString the program crash
any idea ? i'm sorry for my bad english.
The general rule is: Don't read or write something in QML from C++
Instead, you shall create a QObject-derived instance in C++ that has a property for that text. You expose that QObject to QML, either by setting it as a context property or registering it as a singleton.
Then in QML you set afore-mentioned property - et voila - you have pushed the text from the QML world to the C++.
There are various questions on StackOverflow regarding the interaction of C++ and QML (I might search for them later, and probably flag your question as duplicate, for I am sure your question is not the first).
Also the documentation has more information on this.
So I could change the property of a certain QML object via C++ code, but I couldn't see the result on screen.
I have an item repeated 64 times, and I want a certain image to be displayed only for the 32nd item (from C++) so I used invokeMethod to access the object via C++ then I used setProperty to change the visibility, if I view it with qDebug the property "visible" did change, but I notice no difference on the screen I still cannot see the image, but if I change the visibility from qml, I can see it.
This is the C++ code:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl("qrc:///main.qml"));
view.show();
QQuickItem* child;
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///Board.qml")));
QObject *rootObject = engine.rootObjects().first();
QQuickItem *qmlObject = rootObject->findChild<QQuickItem*>("grid")->findChild<QQuickItem*>("repeter");
QMetaObject::invokeMethod(qmlObject,"itemAt",Qt::DirectConnection, Q_RETURN_ARG (QQuickItem*,child), Q_ARG(int,32));
child=child->findChild<QQuickItem*>("pleaseWork");
qDebug() << child->property("visible");
child->setProperty("visible","true");
qDebug() << child->property("visible");
return app.exec();
}
I used qDebug to verify the property changed
This is the QML code :
Item
{
id: root
width: 8*45
height: 8*45
Grid
{
id: grid
objectName: "grid"
rows: 8
Repeater
{
objectName: "repeter"
model: 64
Image
{
objectName: "test"
width: 45; height: 45
source: "images/dark_square.png"
Image
{
id: isit
objectName: "pleaseWork"
visible: false
source: "images/avail_dark.png"
}
}
}
}
}
QQuickView and QQmlApplicationEngine are alternative ways to load and show QML views. What you are loading into QQmlApplicationEngine has nothing to do with the visible output of QQuickView.
In order to get things running, you need to change the top element of the QML file from Item to Window and show it on screen:
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///Board.qml")));
// end of your code
QObject *rootObject = engine.rootObjects().first();
QQuickWindow *window = qobject_cast<QQuickWindow *>(rootObject);
if (!window) {
qDebug() << "Error: Your root item has to be a window.";
return -1;
}
window->show();
// continue with your code
QQuickItem *qmlObject = rootObject->findChild<QQuickItem*>("grid")->findChild<QQuickItem*>("repeter");
I try to add some QML object to my QGraphcisScene but they don't display in the scene. Here is the code.
QList<QObject*> dataList;
dataList.append(new DataObject("Item 1", "red"));
dataList.append(new DataObject("Item 2", "green"));
QDeclarativeEngine engine ;
QDeclarativeContext *context = engine.rootContext();
context->setContextProperty("myModel", QVariant::fromValue(dataList));
QUrl url("qrc:view.qml") ;
QDeclarativeComponent component(&engine,url ) ;
QDeclarativeItem *item = qobject_cast <QDeclarativeItem *>(component.create());
item->setFlag(QGraphicsItem::ItemHasNoContents, false);
myScene->addItem(item);
And here is my qml file:
ListView {
width: 100; height: 100
model: myModel
delegate: Rectangle {
height: 25
width: 100
color: model.modelData.color
Text { text: name }
}
}
You can add a QML in a QDeclarativeView to your scene using addWidget:
QDeclarativeView view;
view.setSource( QUrl("qrc:view.qml"));
view.setStyleSheet("background-color:transparent");
QGraphicsProxyWidget * item = myScene->addWidget((QWidget *)view);
For QtQuick 2.0 you can embed QQuickView in a widget using createWindowContainer :
QQuickView *view = new QQuickView();
...
QWidget *container = QWidget::createWindowContainer(view);
container->setMinimumSize(...);
container->setMaximumSize(...);
container->setFocusPolicy(Qt::TabFocus);
QGraphicsProxyWidget * item = myScene->addWidget((QWidget *)container);