Qt: Connect list in c++ to listview in QML - c++

I just started learning Qt. To be honest, some of confuses my a lot. I'm trying to load a predefined .csv table into a listview.
I created a qml file with the simple layout of a textfield, a listview and a button to load a file. The file looks like this:
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
ApplicationWindow {
id: applicationWindow
objectName: "App"
visible: true
width: 640
height: 480
title: qsTr("Rosinenpicker")
ColumnLayout {
id: columnLayout
anchors.rightMargin: 40
anchors.leftMargin: 40
anchors.bottomMargin: 40
anchors.topMargin: 40
anchors.fill: parent
TextField {
id: name
text: qsTr("Text Field")
Layout.preferredHeight: 50
Layout.fillWidth: true
}
ListView {
id: list
x: 0
y: 0
width: 110
height: 160
spacing: 0
boundsBehavior: Flickable.DragAndOvershootBounds
Layout.fillHeight: true
Layout.fillWidth: true
objectName: "listView"
model: guestModel
delegate: Item {
x: 5
width: 80
height: 40
Text {
text: model.modeldata.name
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
}
}
Button {
id: button
width: 50
text: qsTr("Open File")
Layout.preferredWidth: 100
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
onClicked: fileDialog.visible = true;
}
FileDialog {
id: fileDialog
title: "Please choose a valid guestlist file"
objectName: "fileDialog"
nameFilters: ["Valid guestlist files (*.csv)"]
selectMultiple: false
signal fileSelected(url path)
onAccepted: fileSelected(fileDialog.fileUrl)
}
}
}
In my main file I create a CsvParser class a connect it to the fileSelected signal of the file dialog.
I can parse the csv-File. But when I try to connect it to the listview, I'm lost.
The main file:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtDebug>
#include <QUrl>
#include <QQuickView>
#include "csvparser.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
auto root = engine.rootObjects().first();
auto fileDialog = root->findChild<QObject*>("fileDialog");
CsvParser parser(engine.rootContext());
QObject::connect(fileDialog, SIGNAL(fileSelected(QUrl)), &parser, SLOT(loadData(QUrl)));
return app.exec();
}
My parser looks like this:
#include "csvparser.h"
#include <QtDebug>
#include <QFile>
#include "guest.h"
CsvParser::CsvParser(QQmlContext *context)
{
this->context = context;
}
void CsvParser::loadData(QUrl path)
{
friendList.clear();
guestList.clear();
QFile file(path.toLocalFile());
file.open(QIODevice::ReadOnly);
// ignore first lines
for(int i=0; i<3; i++)
file.readLine();
while(!file.atEnd()) {
auto rowCells = file.readLine().split(',');
if(rowCells.size() != 6)
continue;
checkedAdd(friendList, rowCells[0], rowCells[1]);
checkedAdd(guestList, rowCells[3], rowCells[4]);
}
qDebug() << guestList.size();
auto qv = QVariant::fromValue(guestList);
context->setContextProperty("guestModel", qv);
}
void CsvParser::checkedAdd(QList<QObject*> &list, QString name, QString familyName)
{
if(name == "" && familyName == "")
return;
list.append(new Guest(name, familyName));
}
And the guest, which has only a name and a familyname looks like this:
#ifndef GUEST_H
#define GUEST_H
#include <QObject>
class Guest : public QObject
{
public:
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString fName READ fName WRITE setfName NOTIFY fNameChanged)
public:
Guest(QString name, QString fName);
QString name();
QString fName();
void setName(QString name);
void setfName(QString fName);
signals:
void nameChanged();
void fNameChanged();
private:
QString m_name, m_fName;
};
#endif // GUEST_H
I get the following output:
qrc:/main.qml:41: ReferenceError: guestModel is not defined
QFileInfo::absolutePath: Constructed with empty filename
2
qrc:/main.qml:49: TypeError: Cannot read property 'name' of undefined
qrc:/main.qml:49: TypeError: Cannot read property 'name' of undefined
What am I doing wrong? Any help is appreciated. Thanks!

There are a few things I think are wrong. QML will not find guestModel, because it tries to render the ListView but it has not been made available to QML since you are setting the context property in loadData(), which is however only invoked when the user interacts with the FileDialog. Also, the Q_OBJECT macro needs to appear in the private section of the class (see http://doc.qt.io/qt-5/qobject.html#Q_OBJECT). Also, I do not think it is nice to make a data container/parser class aware of the UI, i.e. you export the rootContext to the parser. It would be better if you export something from the parser to the rootContext in main. The parser should have no notion of the UI IMHO. Finally, if you want to implement a custom list of data items to be displayed, you really should think about using an AbstractListModel as Yuki has suggested (see, http://doc.qt.io/qt-5/qabstractlistmodel.html) or another suitable List-based model (see, http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html). This way, changes in C++ will automatically result in updates in the UI.

Related

How to use QThread from QML while having QML function async too

I'm looking for the way to use QThread in QML.
I want to pass parameters to the QThread function and return a bool value from it.
Another thing I want from the QML side is to not block the app when it's executing a script that will happen before calling/executing the QThread.
Below is an example code:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "testasync.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<testAsync>("testAsync",1,0,"thread");//not working on main.qml
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
//import testAsync 1.0
ApplicationWindow {
id: window
title: "Stack"
visible: true
width: 1400
Page {
id: page
anchors.fill: parent
property int responsiveWidth: 1000
property int maximumWidth: 900
ScrollView {
id:configScroll
anchors.fill: parent
GridLayout {
columns: 2
width: page.width > page.responsiveWidth ? page.maximumWidth : page.width
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: page.width > page.responsiveWidth ? (page.width - childrenRect.width)/2 : 10
anchors.rightMargin: page.width > page.responsiveWidth ? 0 : 10
//this function needs to be processed and will return the values we need for the testasync. this can't block UI thread too
function teste() {
for(var i=0; i<10000000; i++)
{
console.log(i)
}
return "teste"
}
Button {
property bool test: true
text: "async"
onClicked: {
var val = parent.teste()
// if(test)
// val=thread.start()
// else
// val=thread.quit()
console.log(val)
test=!test
}
}
}
}
}
}
testasync.h
#ifndef TESTASYNC_H
#define TESTASYNC_H
#include <QThread>
#include <QObject>
class testAsync : public QThread
{
Q_OBJECT
public:
testAsync();
void run();
private:
QString name;
};
#endif // TESTASYNC_H
testasync.cpp
#include "testAsync.h"
#include <QDebug>
#include <QtCore>
testAsync::testAsync(){}
void testAsync::run() {
for(int i = 0; i <= 100; i++)
{
qDebug() << this->name << " " << i;
}
//return true
}
How can these be done?
Register the type correctly:
qmlRegisterType<testAsync>("TestAsync", 1, 0, "TestAsync");
Make a instance of your type in the qml file and call the methods of it.
import QtQuick 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import TestAsync 1.0
ApplicationWindow {
id: window
title: "Stack"
visible: true
width: 1400
TestAsync {
id: threadAsync
}
Page {
....
Button {
property bool test : true
text: "async"
onClicked: {
if(test) {
val=threadAsync.start()
} else {
val=threadAsync.quit()
}
console.log(val)
test=!test
}
}
....
}
You've done several errors that drives you away from desired.
As it was already mentioned by #folibis and by #Hubi -- you've used C++ class names which starts from small letter. QML has problems with it.
Regarding multi-threading, there are a lots of ways to do it. It really depends on your particular tasks.
I do really recommend you to read next articles (from official Qt documentation):
Threading Basics
Multithreading Technologies in Qt
Since you have signals in Qt and QML, you may implement all what you want in C++ and then just drop it to QML.
You may refer to this simple project on GitHub I've prepared for you. There is moveToThread approach implemented.

Get user input from qml to c++

I'm trying to get user input from qml TextField to c++, but it only works if text property value is hardcoded (const value).
c++
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *rootObject = engine.rootObjects().first();
QObject *serverField1 = rootObject->findChild<QObject*>("serverField1");
qDebug() << serverField1->property("text"); //Here I expect to get user input
Qml
ApplicationWindow {
id: applicationWindow
visible: true
width: 300
height: 550
TextField {
id: serverField1
objectName: "serverField1"
width: 200
height: 110
// text: "hardcoded value" //If text is const value, qDebug will get data from this property
}
}
You are asking for the text of the TextField when the window is displayed so what you will get is the text you have initially set, what you should do is get it every time it changes. I think that you have some class that will handle some processing with that data, that class will be called Backend, it must inherit from QObject so that it can have a qproperty and embed an object of that class to QML through setContextProperty, so every time it changes the text in QML will also change the text in the Backend class object.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQmlProperty>
#include <QDebug>
class Backend: public QObject{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
public:
QString text() const{
return mText;
}
void setText(const QString &text){
if(text == mText)
return;
mText = text;
emit textChanged(mText);
}
signals:
void textChanged(const QString & text);
private:
QString mText;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
Backend backend;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("backend", &backend);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
// test
QObject::connect(&backend, &Backend::textChanged, [](const QString & text){
qDebug() << text;
});
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("Hello World")
TextField {
id: serverField1
x: 15
y: 46
width: 120
height: 45
topPadding: 8
font.pointSize: 14
bottomPadding: 16
placeholderText: "Server Ip"
renderType: Text.QtRendering
onTextChanged: backend.text = text
}
}
You can find the complete code in the following link.

C++ function is being called before page loads even with Component.onCompleted

Here is the issue, I created a C++ class which loads a local file and for every new line it sends out a signal. What I want to do is in my QML file I want to print out these lines into a listview which I have already done but the issue now is that the C++ function loads even before the application starts, it would read the file and populate the listview and then display the page.
Here is my code.
main.cpp
#include <QtCore/QCoreApplication>
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickView>
#include <QtQml>
#include "boot.h"
int main(int argc, char *argv[])
{
QCoreApplication::setApplicationName("xyz");
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
qmlRegisterType<Boot>("xyx", 1, 0, "Boot");
QGuiApplication app(argc, argv);
QQuickView quickView;
quickView.setSource(QUrl(QStringLiteral("qrc:/Boot.qml")));
quickView.setResizeMode(QQuickView::SizeRootObjectToView);
quickView.showMaximized();
return app.exec();
}
Boot.qml
import QtQuick 2.0
import "."
import QtQuick.XmlListModel 2.0
import xyz 1.0
Item{
Loader{
id: bootPageLoader
anchors.fill:parent
sourceComponent: bootSystem
focus:true
}
Component{
id:bootSystem
Rectangle{
width: 640
height: 480
color:"black"
focus:true
Component.onCompleted: {
booting.load();
}
Boot{
id:booting
onErrorMsgChanged: {
console.log("New Boot Log Message: " + errorMsg);
//This is where I am adding to the listview every time I receive a signal
logModel.append({msg:errorMsg});
log.positionViewAtEnd();
}
}
ListView {
id:log
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
anchors.bottomMargin:10
anchors.top: parent.top
width:(parent.width*40)/100
height:parent.height-20
model: BootLogModel{
id:logModel
}
delegate: Text {
text: msg
color: "green"
font.pixelSize: 15
}
}
Text{
id: loading
anchors{
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
text: "LOADING..."
color: "white"
font.pixelSize: Math.round(parent.height/20)
font.bold: true
}
}
}
}
BootLogModel.qml
import QtQuick 2.0
ListModel {
}
Here is the C++ code snippet
In boot.h
#ifndef BOOT_H
#define BOOT_H
#include <QObject>
#include <QString>
#include <string>
class Boot : public QObject{
Q_OBJECT
Q_PROPERTY(QString errorMsg READ errorMsg NOTIFY errorMsgChanged)
public:
explicit Boot(QObject *parent = 0);
Q_INVOKABLE void load();
QString errorMsg();
void setErrorMsg(const QString &errorMsg);
signals:
void errorMsgChanged();
private:
QString m_errorMsg;
};
#endif // BOOT_H
In boot.cpp
Boot::Boot(QObject *parent) : QObject(parent)
{
}
QString Boot::errorMsg()
{
return m_errorMsg;
}
void Boot::setErrorMsg(const QString &errorMsg)
{
m_errorMsg = errorMsg;
emit errorMsgChanged();
}
void Boot::load()
{
int i = 0;
while(i < 10000)
{
setErrorMsg("test: " + QString::number(i));
i++;
}
}
I first see this before the GUI
Then this is the GUI being displayed and already populated
Loops are always a problem in a GUI, it is always better to look for a friendlier alternative to the GUI, in this case a QTimer:
boot.h
int counter = 0;
bool.cpp
void Boot::load()
{
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [timer, this](){
setErrorMsg("test: " + QString::number(counter));
counter++;
if(counter > 10000){
timer->stop();
timer->deleteLater();
}
});
timer->start(0); //delay
}

Copy QML Item to Clipboard as Image thru C++

I've been trying on with QML Charts API and decided to export the ChartView as image to the Clipboard. I found a working solution surfing on the net, in which one grabs the item as image thru Javascript and sends the QVariant data to C++. This is nice and works but I'm wondering if it wouldn't be possible to send just a QQuickItem* or something as light as that and do the grab and whatever at C++, as everybody says to avoid Javascript as much as possible and grabbing an image seems to be a heavy operation.
Here is the working code I'm using now.
chartexporter.h
#ifndef CHARTEXPORTER_H
#define CHARTEXPORTER_H
#include
#include
class QQuickItem;
class ChartExporter : public QObject
{
Q_OBJECT
public:
explicit ChartExporter(QObject *parent = 0);
Q_INVOKABLE void copyToClipboard(QVariant data);
};
#endif // CHARTEXPORTER_H
chartexporter.cpp
includes....
ChartExporter::ChartExporter(QObject *parent) : QObject(parent)
{
}
void ChartExporter::copyToClipboard(QVariant data){
QImage img = qvariant_cast(data);
QApplication::clipboard()->setImage(img,QClipboard::Clipboard);
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtCharts 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello Chart World")
ColumnLayout{
spacing: 2
anchors.fill: parent
ChartView{
id: chart
title: "Testing Charts"
anchors.fill: parent
legend.alignment: Qt.AlignTop
antialiasing: true
animationOptions: ChartView.AllAnimations
PieSeries {
id: pieSeries
PieSlice { label: "Volkswagen"; value: 13.5; exploded: true}
PieSlice { label: "Toyota"; value: 10.9 }
PieSlice { label: "Ford"; value: 8.6 }
PieSlice { label: "Skoda"; value: 8.2 }
PieSlice { label: "Volvo"; value: 6.8 }
}
}
Button{
Layout.alignment: Qt.AlignBottom
text: qsTr("Copy to Clipboard")
onClicked: {
var stat = chart.grabToImage(function(result) {
Printer.copyToClipboard(result.image);
});
}
}
}
}
main.cpp
includes ....
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
ChartExporter printer;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("Printer", &printer);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
Do you guys have an idea on how it could be done by simply calling a method to send the desired Item to C++ as proposed below and processing all stuff in there?
Button{
Layout.alignment: Qt.AlignBottom
text: qsTr("Copy to Clipboard")
onClicked: {
Printer.copyToClipboard(chart);
}
}
I kind of found a way to do it in C++!
When I do the Printer.copyToClipboard(chart) inside the onClicked handler (Javascript) I'm actually sending a QObject* to the C++ layer. Inside my C++ method I can do a qobject_cast and grab it as image. One must take into account that the grab operation is asyncronous. So, I needed to do the copy to clipboard inside an slot which gets called when the grab is finished.
So, below is the way I got. If anybody has a better approach it would be nice to know.
chartexporter.h
#ifndef CHARTEXPORTER_H
#define CHARTEXPORTER_H
#include &ltQObject>
#include &ltQVariant>
#include &ltQSharedPointer>
class QQuickItem;
class QQuickItemGrabResult;
class ChartExporter : public QObject
{
Q_OBJECT
private:
QSharedPointer p_grabbedImage;
protected slots:
void doCopy();
public:
explicit ChartExporter(QObject *parent = 0);
Q_INVOKABLE void copyToClipboard(QObject *item);
};
#endif // CHARTEXPORTER_H
chartexporter.cpp
#include &ltQDebug>
#include &ltQImage>
#include &ltQQuickItem>
#include &ltQClipboard>
#include &ltQApplication>
#include &ltQSharedPointer>
#include &ltQQuickItemGrabResult>
#include "chartexporter.h"
ChartExporter::ChartExporter(QObject *parent) : QObject(parent), p_grabbedImage(nullptr)
{
}
void ChartExporter::copyToClipboard(QObject* item){
if(item){
auto itm = qobject_cast(item);
p_grabbedImage = itm->grabToImage(QSize(itm->width()*2,itm->height()*2));
connect(p_grabbedImage.data(), &QQuickItemGrabResult::ready, this, &ChartExporter::doCopy);
}
}
void ChartExporter::doCopy(){
if(p_grabbedImage.data()){
auto img = p_grabbedImage->image();
QApplication::clipboard()->setImage(img, QClipboard::Clipboard);
}
disconnect(p_grabbedImage.data(),&QQuickItemGrabResult::ready, this, &ChartExporter::doCopy);
}
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtCharts 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello Chart World")
ColumnLayout{
spacing: 2
anchors.fill: parent
ChartView{
id: chart
title: "Testing Charts"
anchors.fill: parent
legend.alignment: Qt.AlignTop
antialiasing: true
animationOptions: ChartView.AllAnimations
PieSeries {
id: pieSeries
PieSlice { label: "Volkswagen"; value: 13.5; exploded: true}
PieSlice { label: "Toyota"; value: 10.9 }
PieSlice { label: "Ford"; value: 8.6 }
PieSlice { label: "Skoda"; value: 8.2 }
PieSlice { label: "Volvo"; value: 6.8 }
}
}
Button{
Layout.alignment: Qt.AlignBottom
text: qsTr("Copy to Clipboard")
onClicked: {
Printer.copyToClipboard(chart);
}
}
}
}
main.cpp
#include &ltQApplication>
#include &ltQQmlContext>
#include &ltQQmlApplicationEngine>
#include "chartexporter.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
ChartExporter printer;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("Printer", &printer);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}

How to access properties of another file from main.qml after they are modified by C++ code first

I’m having problems with QML and C++. If someone could take a look at this piece of code and tell me what I am doing wrong. I ‘m just trying to print “msg.author” on a window (main window) but everytime I try to access it from main.qml there’s an error saying msg is not defined. Thank you for your time.
main.qml
import QtQuick 2.2
import QtQuick.Window 2.1
Window {
property alias name: value
visible: true
id: main_window
width: 500; height: width
color:"black"
}
MyItem.qml
import QtQuick 2.0
import QtQuick.Window 2.0
Text {
id: text1
visible: true
width: 100; height: 100
text: msg.author // invokes Message::author() to get this value
color: "green"
font.pixelSize: 20
Component.onCompleted: {
msg.author = "Jonah" // invokes Message::setAuthor()
}
message.h
#ifndef MESSAGE
#define MESSAGE
#include <QObject>
#include <QString>
class Message : public QObject
{
Q_OBJECT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
public:
void setAuthor(const QString &a) {
if (a != m_author) {
m_author = a;
emit authorChanged();
}
}
QString author() const {
return m_author;
}
signals:
void authorChanged();
private:
QString m_author;
};
#endif // MESSAGE
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlComponent>
#include <QDebug>
#include "message.h"
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine_e;
engine_e.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQmlEngine engine;
Message msg;
engine.rootContext()->setContextProperty("msg", &msg);
QQmlComponent component(&engine, QUrl::fromLocalFile("main.qml"));
if(component.status()!=component.Ready){
if(component.Error){
qDebug()<<"Error: "<<component.errorString();
}
}
return app.exec();
}
The code is not working, and the main has two engines. The second is not properly set-up and it should also be noted, from QQmlApplicationEngine documentation, that:
This class combines a QQmlEngine and QQmlComponent to provide a convenient way to load a single QML file. It also exposes some central application functionality to QML, which a C++/QML hybrid application would normally control from C++.
Hence, QQmlApplicationEngine can perfectly suit your needs and load the QML file. Now, it should also be noted that context properties should always be set before loading a QML file. The final correct code is the following:
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine_e;
Message msg;
engine_e.rootContext()->setContextProperty("msg", &msg);
engine_e.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
EDIT
For what concerns QML files, they should be placed inside the resources (as I hope you have done). My test setting is the following:
main.qml:
import QtQuick 2.3
import QtQuick.Window 2.1
Window {
// property alias name: value
visible: true
id: main_window
width: 500; height: width
// color:"black"
MyItem {
anchors.centerIn: parent // <--- added to the main window to see the result
}
}
MyItem.qml
import QtQuick 2.0
Text {
id: text1
visible: true
width: 100; height: 100
text: msg.author // invokes Message::author() to get this value
color: "green"
font.pixelSize: 20
Component.onCompleted: {
msg.author = "Jonah" // invokes Message::setAuthor()
}
}