QtQuick: create component from C++ - c++

I have a problem with QQuickView instantiating components from C++... Here is my code:
Class definition (vviewerqml.h):
class VViewerQml : public QObject
{
Q_OBJECT
public:
explicit VViewerQml(QSettings &systemSettings, QObject *parent = 0);
~VViewerQml();
protected slots:
void onViewStatusChanged(QQuickView::Status status);
protected:
QString _qmlFolder;
QQuickView _view;
};
Class implementation (vviewerqml.cpp):
#include "vviewerqml.h"
VViewerQml::VViewerQml(QSettings &systemSettings, QObject *parent) :
QObject(parent)
{
// Initialize viewer reading from settings file
_qmlFolder = "/my/path/to/qml/files";
// Initialize the source
connect(&_view, SIGNAL(statusChanged(QQuickView::Status)),
this, SLOT(onViewStatusChanged(QQuickView::Status)));
_view.setSource(QUrl::fromLocalFile(QDir(_qmlFolder).filePath("Main.qml")));
// Show the viewer
_view.show();
}
VViewerQml::~VViewerQml()
{
// Close the viewer
_view.close();
}
void VViewerQml::onViewStatusChanged(QQuickView::Status status)
{
if(status == QQuickView::Ready)
{
QQmlComponent *c =
new QQmlComponent(_view.engine(),
QDir(_qmlFolder).filePath("TextLegacy.qml"));
QQuickItem *i = qobject_cast<QQuickItem*>(c->create());
QQmlEngine::setObjectOwnership(i, QQmlEngine::CppOwnership);
i->setParent(_view.rootObject());
i->setVisible(true);
}
}
Here is my Main.qml:
import QtQuick 2.0
Rectangle {
width: 1024
height: 768
color: "#000000"
Text {
x: 0
y: 0
color: "#ffffff"
text: "Main page"
}
}
And here is my TextLegacy.qml:
import QtQuick 2.0
Item {
Rectangle {
x: 0
y: 0
width: 100
height: 50
color: "#ff0000"
}
}
My code works fine until the load of Main.qml: the QML viewer opens on the screen and I can read the text "Main page" (white on black) on my screen... But unluckily I am not able to load the TextLegacy.qml... if I put a breakpoint in onViewStatusChanged function, the execution reaches that point... no visible errors are shown in the debug console... but I am not able to see on the screen the red rectangle provided by TextLegacy.qml...
What am I missing? Can somebody give some help?

Ok, I found the solution on my own: I have confused setParent with setParentItem... The correct code is:
void VViewerQml::onViewStatusChanged(QQuickView::Status status)
{
if(status == QQuickView::Ready)
{
QQmlComponent *c = new QQmlComponent(_view.engine(),
QUrl::fromLocalFile(QDir(_qmlFolder).filePath("TextLegacy.qml")));
QQuickItem *i = qobject_cast<QQuickItem*>(c->create());
QQmlEngine::setObjectOwnership(i, QQmlEngine::CppOwnership);
i->setParent(this);
i->setVisible(true);
i->setParentItem(_view.rootObject());
}
}
Actually i->setParent(this); defines the parent of i as a QObject (for deleting purposes, for example) while i->setParentItem(_view.rootObject()); actually adds the object to the scene, as a child of the scene root object.

Related

draw with the mouse on QQuickPaintedItem

I have this code
class cCanvas : public QQuickPaintedItem
..
..
void cCanvas::paint(QPainter *ppainter)
{
ppainter->setPen(QPen(colorValue()));
ppainter->drawLine(0, 0, rand() % 255 ,100);
}
QML
MultiPointTouchArea {
onPressed {
canvas.update();
}
}
It works, but when drawing each new line, the canvas is cleared, previous line is deleted. But I want the lines to stay.
QML Canvas have requestPaint();
How to call this method for QQuickPaintedItem?
How to correctly create the ability to draw with the mouse on QQuickPaintedItem?
(Drawing on the QML canvas itself is not suitable because of the speed of work, since drawing occurs using calculations)
Qt does not keep a cache of what was painted, so you only see what was painted last. A possible solution is to save the line instructions in a QPainterPath:
#ifndef CCANVAS_H
#define CCANVAS_H
#include <QPainterPath>
#include <QQuickPaintedItem>
class CCanvas : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
QML_ELEMENT
public:
CCanvas(QQuickItem *parent = nullptr);
Q_INVOKABLE void requestPaint();
void paint(QPainter *painter);
const QColor &color() const;
void setColor(const QColor &newColor);
signals:
void colorChanged();
private:
QPainterPath m_path;
QColor m_color;
};
#endif // CCANVAS_H
#include "ccanvas.h"
#include <QPainter>
CCanvas::CCanvas(QQuickItem *parent):QQuickPaintedItem(parent)
{
}
void CCanvas::requestPaint()
{
QPointF start(0, 0);
QPointF end(rand() % 255, 100);
m_path.moveTo(start);
m_path.lineTo(end);
update();
}
void CCanvas::paint(QPainter *painter)
{
painter->setPen(QPen(m_color));
painter->drawPath(m_path);
}
const QColor &CCanvas::color() const
{
return m_color;
}
void CCanvas::setColor(const QColor &newColor)
{
if (m_color == newColor)
return;
m_color = newColor;
emit colorChanged();
update();
}
import QtQuick 2.12
import QtQuick.Window 2.12
import Canvas 1.0
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
CCanvas{
id: canvas
anchors.fill: parent
color: "red"
}
Timer {
interval: 500; running: true; repeat: true
onTriggered: canvas.requestPaint()
}
}
QT += quick
CONFIG += c++11
SOURCES += \
ccanvas.cpp \
main.cpp
HEADERS += \
ccanvas.h
RESOURCES += qml.qrc
CONFIG += qmltypes
QML_IMPORT_NAME = Canvas
QML_IMPORT_MAJOR_VERSION = 1
A similar solution can be done with a QImage.

Qt5 - QML: How to properly connect a ProgressBar with Button for long-running loop calculation

I am connecting a ProgressBar to two Buttons. The ProgressBar will do a computation of a loop as soon as I push the button. The computation will be erased if I will push the other button. I still haven't implemented the pause button.
The print screen of what I am trying to achieve is below and in case needed the whole code of the minimal verifiable example is available here:
The problem is that as soon as I connect the ProgressBar with my main.cpp file I have a bunch of errors all that look like the following:
class ProgressDialog has no member named...
code is below:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include "progressbardialog.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQuickView view;
ProgressBarDialog progressDialog;
// One way but it does not work
// engine.rootContext()->setContextProperty("control", QVariant::fromValue(progressDialog.refModel()));
// Another way but this also does not work
view.setSource(QUrl::fromLocalFile("main.qml"));
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
progressbardialog.h
#ifndef PROGRESSBARDIALOG_H
#define PROGRESSBARDIALOG_H
#include <QObject>
#include <QFutureWatcher>
class ProgressBarDialog : public QObject
{
Q_OBJECT
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
public:
ProgressBarDialog();
float progress(int &iterator);
// I will use this as a reference to pass to main.cpp using setContextProperty()
QObject &refModel()
{
return m_Model;
}
public Q_SLOTS:
void startComputation();
void cancelComputation();
signals:
void progressChanged();
private:
int m_progressValue;
QObject m_Model;
QFutureWatcher<void> m_futureWatcher;
};
#endif // PROGRESSBARDIALOG_H
progressbardialog.cpp
#include "progressbardialog.h"
#include <QtConcurrent/QtConcurrentMap>
ProgressBarDialog::ProgressBarDialog()
{}
void spin(int &iteration)
{
const int work = 1000 * 1000 * 40;
volatile int v = 0;
for(int j = 0; j < work; ++j)
++v;
}
float ProgressBarDialog::progress(int &iterator)
{
(void) iterator;
const int work = 1000 * 1000 * 40;
volatile int v = 0;
for(int j = 0; j < work; ++j)
++v;
emit progressChanged();
}
void ProgressBarDialog::startComputation()
{
// Prepare the vector
QVector<int> vector;
for(int i = 0; i < 40; ++i)
vector.append(i);
const QFuture<void> future = QtConcurrent::map(vector, spin);
m_futureWatcher.setFuture(future);
}
void ProgressBarDialog::cancelComputation()
{
m_futureWatcher.cancel();
}
and finally the main.qml
import QtQuick 2.12 // for the Item
import QtQuick.Controls 2.12 // for ApplicationWindow
import QtQuick.Layouts 1.12
ApplicationWindow {
visible: true
width: 440
height: 480
title: qsTr("Progress Bar")
ColumnLayout {
spacing: 10
width: parent.width
GroupBox {
id: box1
title: "Start - Stop"
font.pointSize: 20
Layout.alignment: parent.width
spacing: 10
GridLayout {
width: parent.width
columns: 1
RowLayout {
spacing: 200
Layout.fillWidth: true
Layout.fillHeight: false
Button {
id: buttonStart
text: "Start"
font.pointSize: 15
enabled: !progressDialog.active
onClicked: progressDialog.startComputation()
}
Button {
id: buttonFinish
text: "Finish"
font.pointSize: 15
enabled: progressDialog.cancelComputation()
}
}
}
}
GroupBox {
id: boxprogress
title: "Progressbar"
font.pointSize: 20
Layout.alignment: parent.width
spacing: 10
GridLayout {
width: parent.width
columns: 1
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: false
ProgressBar {
id: progressbar_id
Layout.fillWidth: true
Layout.fillHeight: true
width: parent.width
// These are hard-coded values to confirm it is working
from: 0
to: 100
value: 5
onValueChanged: {
console.log("Progressbar value changed: ", progressbar_id.value)
}
onVisibleChanged: {
console.log("Progressbar visibility changed: ", progressbar_id.visible)
}
}
Connections {
target: progressDialog
onProgressChanged: progressbar_id.value = progress;
}
// This is working if clicking on the progressbar
MouseArea {
anchors.fill: parent
onClicked: progressbar_id.value += 5;
}
}
}
}
}
}
What I tried so far :
1) In order to prove myself that the ProgressBarDialog is correctly working I tried it before as a stand alone main.qml using hard-coded values (which I left in the code so you can see what I have done). But as soon as I started implementing it in the .cpp file and setting the Q_PROPERTY I received all the errors I posted on the second screenshot.
2) I am sure about the procedure taken so far because: a) According to the official documentation and from this post because I will need to check the process of a long running operations; b) According to QtConcurrent the process has a better possibility to be checked, and that is exactly what I did using QtConcurrent::map()
3) I am using the following statement in the progressbardialog.h to make sure that the object is correctly connected and listens to the QML file:
QObject &refModel()
{
return m_Model;
}
But this did n't show and substancial improvements. Therefore digging more into the process I was thinking that it should have been the case to use setContextProperty(), whih cled me to the next point.
4) According to the official documentation and according to this post here I thought I would have fix the error, but it still remains.
I am runnign out of ideas and anyone who may have had this problem, please point to the right direction for a possible solution.
Q_PROPERTY is designed to easier read/write/react to variable change (C++ side) on the QML side. To complete your example with variable read/write/notify add correct getter/setter (signal is already ok).
float progress();
void setProgress(float);
If you want to call a function from QML mark it Q_INVOKABLE instead.
Also what is the point of volatile in your code?
So to sum up, mark your iteration function as a Q_INVOKABLE. It will increment some internal progress value and then emit progressChanged(). This should cause QML side to update.

Why does my window not show?

I need to write a GrabWindow, so I derived my class GrabWindow from QQuickWindow:
#include <QtQuickWidgets/QtQuickWidgets>
#include <QString>
class GrabWindow : public QQuickWindow {
Q_OBJECT
public:
explicit GrabWindow(QQuickWindow *parent = nullptr);
public slots:
void capture(QString const &path);
};
// .CPP
#include "grab_window.h"
#include <QImage>
GrabWindow::GrabWindow(QQuickWindow *parent) : QQuickWindow(parent) {
}
void GrabWindow::capture(const QString &path) {
QImage img = this->grabWindow();
img.save(path);
}
After I registered it in QML: qmlRegisterType<GrabWindow>("myapp", 1, 0, "GrabWindow");
And after I defined my window in QML:
import QtQuick 2.4
import QtQuick.Controls 2.2
import QtQuick.Window 2.3
import myapp 1.0
GrabWindow {
id : translationWindow
width : 1024
height : 768
color: "transparent"
visibility: "FullScreen"
visible: true;
signal capture(string path)
MouseArea {
anchors.fill: parent
onClicked: translationWindow.capture("/home/user/saveTest.jpg")
}
}
But it doesn't show on start (I know it's transparent, I mean the grab window doesn't start to show). If instead of GrabWindow I use Window or ApplicationWindow then all works perfectly I am seeing a transparent full-screen window.
What's wrong?
Your GrabWindow is not shown because when you are setting the visible property it's not same as when you use Window's visible property.
Yours is just the visible property of QWindow.
Window does not directly instantiate QQuickWindow, it instantiates a private Qt class QQuickWindowImpl which overrides the visible property with a custom one.
It seems to delay the actual call of the QWindow::setVisible at a later time.
As such, I don't think QQuickWindow is meant to be inherited from. You could try doing visible = true in your Component.onCompleted but I'm not sure it will resolve your problem.
What I would advise you instead is not subclassing QQuickWindow but just creating a new type and pass it the existing Window.
Possible API could be :
Window {
id: myWindow
//...
MouseArea {
anchors.fill: parent
onClicked: WindowGrabber.grab(myWindow, path) //singleton type
}
}
or
Window {
id: myWindow
//...
WindowGrabber { // regular type
id: windowGrabber
window: myWindow
}
MouseArea {
anchors.fill: parent
onClicked: windowGrabber.grab(path) // you could even add a path property in WindowGrabber and not have it as a function parameter if that makes sense for your use case
}
}

How to find out when the QQuickItem-derived class object is initialized?

I've got class that inherits from QQuickItem and inside I'm operating on its width height properties. I'm also exposing my own properties.
class MyQQuickItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QUrl source MEMBER m_source NOTIFY sourceChanged)
public:
explicit MyQQuickItem(QQuickItem *a_parent = Q_NULLPTR);
~PDFPage();
signals:
void sourceChanged(const QUrl a_source);
private:
QUrl m_source;
};
In qml:
...
MyQQuickItem
{
width: parent.width / 2
height: parent.height
source: "someSource"
Component.onCompleted
{
console.log("component onCompleted");
}
}
When sourceChanged is emmited I'm working on width height properties, but with the first emit they are not initialized yet, and Component.onCompleted is called after my NOTIFY signal.
I can check if component is ready before getting width and height by calling isComponentComplete and execute my code when it is, but I can't find out when it happens and the initial value of source is skipped when it is not.
Of course I could create slot 'itemReady' and call it from Component.onCompleted, but I have many QMLs using my class and I will create more in the future, so I don't want to make copy-paste job.
I also do not want to set the source in Component.onCompleted.
Connecting to widthChanged, and heightChanged signals isn't also good idea, because I'm resizing my item very frequently, and I don't want to execute my code then.
Is there any way to get completed signal from C++?
EDIT:
I did as #Mitch said - overriten componentComplete method and inside, called it's base class equavilent. isComponentComplete() returns true, but I'm still getting 0 from width() and height() methods:
void MyQQuickItem::componentComplete()
{
QQuickItem::componentComplete();
if(isComponentComplete())
{
qDebug() << "c++: oncompleted, width,height: " << width() << height(); //gives 0,0
}
}
Actually I figured out that Component.onCompleted in QML prints 0's too:
...
MyQQuickItem
{
width: parent.width / 2
height: parent.height
source: "someSource"
Component.onCompleted
{
console.log("component onCompleted width, height: ", width, height); //it gives 0 too
}
}
#derM Component.onCompleted is not emmited by QQuickItem::componentComplete() directly, because it prints its log after the qDebug in c++ above.
So, although it is ready, properties are not initialized.
EDIT2:
Finally I've solved it. The Window was guilty, because it uses contentItem as the parent of his childrens, and in MyQQuickItem Component.onCompleted width and height of contentItem(his parent) are 0.
When I do so:
Window
{
id: wnd
width: 640
height: 480
Component.onCompleted:
{
console.log("Window completed: ", this, width, height);
console.log("windowContentItem: ", contentItem, width, height);
}
MyQQuickItem
{
width: parent.width
height: parent.height
Component.onCompleted:
{
console.log("MyQQuickItem completed: ", this, width, height);
console.log("MyQQuickItem parent: ", parent, parent.width, parent.height);
}
}
}
It prints:
qml: Window completed: QQuickWindowQmlImpl(0x345b5eb4d0) 640 480
qml: windowContentItem: QQuickRootItem(0x345e2cdec0) 640 480
qml: MyQQuickItem completed: MyQQuickItem(0x345b5b99e0) 0 0
qml: MyQQuickItem parent: QQuickRootItem(0x345e2cdec0) 0 0
So MyQQuickItem parent is Window's contentItem. When I replace
width: parent.width
height: parent.height
to:
width: wnd.width
height: wnd.height
It works perfectly, and in my void MyQQuickItem::componentComplete() I've got width and height initialized as expected.
One thing that I do not understand is why in Window onCompleted, contentItem size is correct, but in MyQQuickItem onCompleted the size is 0,0. If anyone could explain it to me, I would be grateful :P
Qt code uses componentComplete() like so:
void QQuickControl::componentComplete()
{
Q_D(QQuickControl);
QQuickItem::componentComplete();
d->resizeContent();
// ...
}
You can do something similar, replacing resizeContent() with your function that works on the width and height. Assuming that function is also called whenever source changes, you'd need the isComponentComplete() check. With this approach, you shouldn't have any issues.
You can inherit QQmlParserStatus and implement componentComplete().
class MyQQuickItem : public QQuickItem, public QQmlParserStatus
{
Q_OBJECT
Q_PROPERTY(QUrl source MEMBER m_source NOTIFY sourceChanged)
public:
explicit MyQQuickItem(QQuickItem *a_parent = Q_NULLPTR);
~PDFPage();
void classBegin();
void componentComplete();
signals:
void sourceChanged(const QUrl a_source);
private:
QUrl m_source;
};
componentComplete() will be called automatically by the QML-engine.

How can I display a QStringList in C++ to a QML ListView

So I'm new to Qt and I'm trying to improve my C++ skills, so I decided to start a project where I can search items in a QStringList using a textfield. I got the search function working and I was able to move the result of the search into another QStringList, where I can use it to display to the user in a function that is declared as a "public slot".
The main Idea is that the list will auto update as soon as the user enters a character into the textfield, which it already does. So I managed to get the resulted list into the Slot function to be able to display a different list every time and character gets typed in the textfield.
In the function where I pass in the list of search results, I am trying to use this
m_context->setContextProperty("resultModel",QVariant::fromValue(m_resultList));
where resultModel is the name of my model in QML and m_resultList is where the results of the search are being stored, to display the list in the ListView. My program compiles but it crashes after I run it.
So, my true question is: Is there any way that I can display a C++ QStringList not in the main.cpp into a QML ListView?
The reason why I'm asking for it to not be in the main is because I tried to use that same line above in the main.cpp with a hard coded QStringList and the list was able to display, so there must be an issue with it not being in the main. Also because I would not be able to use the slot function in SearchClass to auto update.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>
#include "searchclass.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<SearchClass>("b9c.backend", 1, 0, "BackEnd");
QQmlApplicationEngine engine;
SearchClass obj;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQmlContext *context = engine.rootContext();
obj.getContext(context);
//the line below works if provided with a qstringlist
//context->setContextProperty("resultModel", QVariant::fromValue(resultList));
return app.exec();
}
SearchClass.h
#ifndef SEARCHCLASS_H
#define SEARCHCLASS_H
#include <QObject>
#include <QQmlContext>
class SearchClass : public QObject
{
Q_OBJECT
Q_PROPERTY(QString userSearch READ userSearch WRITE setUserSearch NOTIFY userSearchChanged)
public:
SearchClass(QObject *parent = 0);
QStringList resultList;
QString userSearch();
void setUserSearch(QString &userSearch);
void getFilenameAndInput(QString inputString);
QString CompareInputAndFilename(QString inputString, QString filename);
QStringList getFileName();
//get context
void getContext(QQmlContext *context);
signals:
void userSearchChanged();
public slots:
void setUserSearch();
private:
QStringList m_resultList;
QString m_userSearch;
QQmlContext* m_context;
};
#endif // SEARCHCLASS_H
SearchClass.cpp
#include "searchclass.h"
#include <QDebug>
#include <QQmlContext>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
SearchClass::SearchClass(QObject *parent) : QObject(parent)
{
connect(this, SIGNAL(userSearchChanged()), this, SLOT(setUserSearch()));
}
//the result should be displayed in this SLOT when ever the user types in a character into the textfield
void SearchClass::setUserSearch(){
qDebug() << "SLOT: " << m_resultList;
//The line below makes the program crash. It works when implemented in the main.cpp
// m_context->setContextProperty("resultModel", QVariant::fromValue(m_resultList));
}
QString SearchClass::userSearch()
{
return m_userSearch;
}
void SearchClass::setUserSearch(QString &userSearch)
{
if (userSearch == m_userSearch)
return;
m_userSearch = userSearch;
qDebug() << "Input: " <<m_userSearch;
getFilenameAndInput(m_userSearch);
emit userSearchChanged();
}
QStringList SearchClass::getFileName(){
//Returns the items that will be searched for...
}
void SearchClass::getFilenameAndInput(QString inputString){
//Puts the search results into class variable m_resultList...
m_resultList = resultList;
}
QString SearchClass::CompareInputAndFilename(QString inputString, QString filename){
//Search processing...
}
//gets context to use setProperty in the above signal, but it crashes
void SearchClass::getContext(QQmlContext *context){
m_context = context;
}
main.qml
import QtQuick 2.6
import QtQuick.Controls 2.0
import b9c.backend 1.0
import QtQuick.Window 2.2
ApplicationWindow {
id: root
width: 300
height: 480
visible: true
BackEnd { id: backend }
TextField {
id: txtfield
text: backend.userSearch
placeholderText: qsTr("Search...")
width: parent.width
onTextChanged: backend.userSearch = text
}
ListView {
id:view
height: parent.height
width: parent.width
y: 5 + txtfield.height
model: resultModel
delegate: Rectangle {
border.color: "lightblue"
height: 25
width: parent.width
Text {
anchors.centerIn: parent
text: modelData
}
}
}
}
You are doing it wrong. In every possible way. You even name getContext() the function that actually sets the context.
m_resultList is never set to anything in that code you have provided. So there is no way to tell you why your application is crashing, because the actual data is a mystery.
You also have a QObject derived class - your SearchClass. So you should expose that as a context property, and then have the string list interfaced to QML by being implemented as a Q_PROPERTY of SearchClass.
Here is a simple example:
// the equivalent of your SearchClass
class Test : public QObject {
Q_OBJECT
Q_PROPERTY(QStringList model MEMBER m_model NOTIFY modelChanged)
QStringList m_model;
public slots:
void setModel(QString m) {
m_model = m.split(" ");
modelChanged();
}
signals:
void modelChanged();
};
// in main.cpp
Test t;
engine.rootContext()->setContextProperty("Test", &t);
// in main.qml
Column {
TextField {
onTextChanged: Test.setModel(text)
}
ListView {
width: 200; height: 300
spacing: 5
model: Test.model
delegate: Rectangle {
height: 25
width: 200
color: "lightgray"
Text { text: modelData; anchors.centerIn: parent }
}
}
}
As you type the text string is sent to Test::setModel(), which then splits it into space separated tokens and sets the QStringList, which is used as a model source for the list view.