1
votes

I have a database full of albums and i want to display these albums in a GridView. I created a qml file that takes a personalized module (albumObject.h) in order to get the data from the database. Since I already have a MainWindow in main.cpp i need to display the GridView in a QQuickWidget that is constructed inside the mainwindow.cpp file. Here's is the code:

albumObject.h

class AlbumObject : public QObject {
  Q_OBJECT

  Q_PROPERTY(QString artist READ getArtist)
  Q_PROPERTY(QString album READ getAlbum)
  Q_PROPERTY(QString date READ getDate)
  Q_PROPERTY(QString img READ getImg)

public:
  AlbumObject(QObject* parent = nullptr);

  const QString getArtist() const;
  const QString getAlbum() const;
  const QString getDate() const;
  const QString getImg() const;

  void setArtist(const QString& artist);
  void setAlbum(const QString& album);
  void setDate(const QString& date);
  void setImg(const QString& img);


private:
  QString m_artist;
  QString m_album;
  QString m_date;
  QString m_img;
};

mainwindow.cpp

I use this connect inside the MainWindow constructor to update the UI when all the albums are added to the database

  connect(&databaseManager, &DatabaseManager::albumAddedToDB,
          &databaseManager, [&]() {
    QList<QObject*> albums = databaseManager.getAlbumsFromDB();

    QQuickView view;
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    QQmlContext *ctxt = view.rootContext();
    ctxt->setContextProperty("albumModel", QVariant::fromValue(albums));
    ui->albumGrid->setSource(QUrl{"../Hallownest/Model/something.qml"});
    ui->albumGrid->createWindowContainer(&view, this);
  });

something.qml

import QtQuick 2.4

Rectangle {
    width: 800; height: 600

    Component {
        id: albumDelegate
        Item {
            width: grid.cellWidth; height: grid.cellHeight
            Column {
                anchors.fill: parent
                Text { text: artist; anchors.horizontalCenter:  parent.horizontalCenter }
                Text { text: album; anchors.horizontalCenter:  parent.horizontalCenter }
                Text { text: date; anchors.horizontalCenter:  parent.horizontalCenter }
            }
        }
    }

    GridView {
        id: grid
        anchors.fill: parent
        cellWidth: 150; cellHeight: 150

        model: albumModel
        delegate: albumDelegate
        highlight: Rectangle {color: "lightsteelblue"; radius: 5 }
        focus: true;
    }
}

When i launch the program i get this error:

ReferenceError: albumModel is not defined

In similar questions most of the users have this problem because they set the context after loading the qml file but this is not my case.

1
change QQuickView view; to QQuickView *view = new QQuickView; and provide a minimal reproducible exampleeyllanesc
@eyllanesc already tried that without success. As for the post you mean that there is too much stuff or too few?Gerico0889
I already found where the error is, in a moment publish an answer.eyllanesc
@eyllanesc ok thank youGerico0889

1 Answers

1
votes

The problem in your case is that you are creating a QQuickView unnecessarily thinking that this way you will get the QQmlContext but it is not correct, the QQuikWidget already has its own QQmlContext. On the other hand it is better that the list is a property and export the MainWindow so you can access that property.

*.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
    Q_PROPERTY(QList<QObject *> albums READ getAlbums NOTIFY albumsChanged)

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    QList<QObject *> getAlbums() const;
    void updateAlbums();
signals:
    void albumsChanged();
private:
    Ui::MainWindow *ui;
    QList<QObject *> m_albums;
    DatabaseManager databaseManager;
};

*.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->albumGrid->rootContext()->setContextProperty("mainwindow", this);
    ui->albumGrid->setSource(QUrl{"../Hallownest/Model/something.qml"});
    connect(&databaseManager, &DatabaseManager::albumAddedToDB, this, &MainWindow::updateAlbums);
}

MainWindow::~MainWindow()
{
    delete ui;
}

QList<QObject *> MainWindow::getAlbums() const
{
    return m_albums;
}

void MainWindow::updateAlbums()
{
    qDeleteAll(m_albums);
    m_albums.clear();
    m_albums = databaseManager.getAlbumsFromDB();
    emit albumsChanged();
}

*.qml

import QtQuick 2.4

Rectangle {
    width: 800; height: 600

    Component {
        id: albumDelegate
        Item {
            width: grid.cellWidth; height: grid.cellHeight
            Column {
                anchors.fill: parent
                Text { text: modelData.artist; anchors.horizontalCenter:  parent.horizontalCenter }
                Text { text: modelData.album; anchors.horizontalCenter:  parent.horizontalCenter }
                Text { text: modelData.date; anchors.horizontalCenter:  parent.horizontalCenter }
            }
        }
    }

    GridView {
        id: grid
        anchors.fill: parent
        cellWidth: 150; cellHeight: 150
        model: mainwindow.albums
        delegate: albumDelegate
        highlight: Rectangle {color: "lightsteelblue"; radius: 5 }
        focus: true;
    }
}