将C ++模块连接到QML-ReferenceError:未定义<blank>

时间:2018-12-26 19:05:54

标签: c++ qt qml

我有一个充满专辑的数据库,我想在GridView中显示这些专辑。我创建了一个qml文件,该文件带有个性化模块(albumObject.h),以便从数据库中获取数据。由于我在MainWindow中已经有了main.cpp,因此需要在GridView文件内部构造的QQuickWidget中显示mainwindow.cpp。这是代码:

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

当所有专辑都添加到数据库后,我在MainWindow构造函数中使用此连接来更新UI

  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;
    }
}

启动程序时出现此错误:

ReferenceError: albumModel is not defined

在类似的问题中,大多数用户都有此问题,因为他们在加载qml文件后设置了上下文,但这不是我的情况。

1 个答案:

答案 0 :(得分:1)

您所遇到的问题是,您在创建QQuickView时不必要地认为通过这种方式您将获得QQmlContext,但它是不正确的,QQuikWidget已经具有自己的QQmlContext。另一方面,列表最好是一个属性并导出MainWindow,以便您可以访问该属性。

*。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;
    }
}