簡體   English   中英

如何將 QPixmap 從 C++ 模型傳遞到 QML?

[英]How to pass QPixmap from a C++ model to QML?

我使用 QAbstractItemModel 在鍵盤啟動器的上下文中為各種事物提供圖標。

這些是要求:

  • 前端是抽象的,因此該模型應該適用於 Widgets 以及 QML 視圖。 這伴隨着裝飾角色不能返回 QIcons (afaik) 的限制。
  • 后端應該與平台無關。 在 linux 上,我使用QMimeDatabase::mimeTypeForFile > QMimeType::iconName > QIcon::fromTheme 在 macOS Qt 上不提供這樣的設施,因此我計划使用icon(for:)返回NSImage ,我必須將其繪制到 QPixmap 中。

沒有圖標,沒有路徑。 只剩下 QPixmap 了吧? 這是要走的路嗎? 我可以在 QML 中顯示來自 C++ 模型的 QPixmap 嗎? 或者我應該在磁盤上緩存圖標並在模型中傳遞路徑?

另一個要求是這應該相當快,因為​​它是一個鍵盤啟動器,結果應該立即顯示出來。

解決方案

我必須承認,它並不像我希望的那么簡單,但無論如何都是這樣:

從 C++ 后端提供模型,例如:

class Backend : public QObject
{
    ...
    QStandardItemModel *model() const { return m_model; }
    ...

private:
    QStandardItemModel *m_model;
};

使用QQuickImageProvider子類獲取給定模型索引的裝飾角色的像素圖,如下所示:

QPixmap requestPixmap(const QString &id, QSize *, const QSize &) override {
    const QModelIndex &index(m_model->index(id.toInt(), 0));
    const QIcon &icon(m_model->data(index, Qt::DecorationRole).value<QIcon>());

    return icon.pixmap(QSize(16, 16));
}

main.cpp您需要以下代碼:

Backend backend;

engine.rootContext()->setContextProperty("backend", &backend);
engine.addImageProvider(QLatin1String("icons"), new PixmapBuilder(backend.model()));

qmlRegisterUncreatableType<QStandardItemModel>("QStandardItemModel", 1, 0, "QStandardItemModel", "The model should be created in C++");

最后像這樣在 QML 中設置Image組件的源:

Image {
    id: name
    source: "image://icons/" + index
}

例子

在 GitHub 上,您可以找到我為您編寫的示例來演示建議的解決方案。

結果

該示例產生以下結果:

帶有裝飾列表的程序窗口

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM