c++ 使用QQuickImageProvider的正确方法是什么?

5kgi1eie  于 2022-11-19  发布在  其他
关注(0)|答案(2)|浏览(279)

我需要动态选择qpixmap来显示在QML图像项目中。qpixmap应该从源qpixmap中裁剪出来,我将从QML文件中进行设置。我希望它们在QML的第一次请求时被C++代码裁剪,并被缓存以供将来使用。对于动态图像操作,它应该从QQuickImageProvider中派生出我自己的类,并将其加载到QML应用程序引擎中。但是我该如何控制源qpixmap呢?通过属性吗?如果是的话,那么我的自定义提供者必须是从QObject中派生出来的,并且它的示例应该在QML中声明,不是吗?但是它该如何被引擎加载呢?我觉得这种实现方式是错误的,但是哪一种是正确的呢?
UPD:好的,我有一个类:

class MyQuickImageProvider : public QQuickImageProvider {
public:
    ...
    // This method should set the source image path
    void setPath ( QUrl path );
    // Overriden method of base class; should return cropped image
    virtual QPixmap requestPixmap ( const QString &id, QSize *size, const QSize &requestedSize );
    ...
}

在main.cpp中,它被加载为:

QQmlApplicationEngine engine;
...
engine.addImageProvider("my_quick_image_provider", new MyQuickImageProvider(QQmlImageProviderBase::Image));

我想通过QML更改源图像路径。如何使setPath方法可访问?最明显的方法是将方法声明为Q_INVOKABLE(并从QObject和qmlRegisterType派生MyQuickImageProvider),但之后我应该在QML源代码中声明我的类的示例:

MyQuickImageProvider {
    id: my_quick_image_provider
    ...
}

从main.cpp访问它会有问题。而且这样的设计对我来说很奇怪。有没有更优雅的解决方案?

rjzwgtxy

rjzwgtxy1#

您不能将MyQuickImageProvider用作QML对象,也不能定义Q_INVOKABLE方法,因为您无法从QML访问图像提供程序对象。
engine.addImageProvider("my_quick_image_provider", [...]
设置访问图像的名称,例如

// qml file
Image {
    source: "image://my_quick_image_provider/name_of_my_image"
}

后面的部分“name_of_my_image”称为id,您可以在

virtual QPixmap requestPixmap ( const QString &id, QSize *size, const QSize &requestedSize );

现在在MyQuickImageProvider中实现requestPixmap,并让它使用id字符串来生成QPixmap。
我认为您可以丢弃void setPath ( QUrl path );方法,因为您只需要一个图像提供程序示例来处理所有此类图像。
由于构造函数不是从基类继承的,我认为new MyQuickImageProvider(QQmlImageProviderBase::Image));没有意义。

class MyQuickImageProvider : public QQuickImageProvider {
public:
    MyQuickImageProvider();
    // ...

并在初始化器列表中包含图像类型:

MyQuickImageProvider::MyQuickImageProvider()
    : QQuickImageProvider(QQuickImageProvider::Pixmap)
{
}
f5emj3cl

f5emj3cl2#

在Qt-6.2.4中创建和测试

main.cpp--除了第行引擎外,都用默认的Qt代码.addImageProvider(“colors”,新测试);

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "test.h"
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    engine.addImageProvider("colors", new test);

    const QUrl url(u"qrc:/qimgprovider/main.qml"_qs);
    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();
}

测试.cpp

#include "test.h"

test::test() : QQuickImageProvider(QQuickImageProvider::Pixmap)
{ 
}
    
QPixmap test::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
{
   int width = 100;
   int height = 50;
   if (size)
      *size = QSize(width, height);
   QPixmap pixmap(requestedSize.width() > 0 ? requestedSize.width() : width,
                  requestedSize.height() > 0 ? requestedSize.height() : height);
   pixmap.fill(QColor(id).rgba());
   return pixmap;
}

测试.h

#ifndef TEST_H
#define TEST_H

#include <QQuickImageProvider>

class test : public QQuickImageProvider
{
public:
    test();
    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) override;
};

#endif // TEST_H

主文件.qml

import QtQuick

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Glory to Ukraine!")
    Column {
        Image { source: "image://colors/blue" }
        Image { source: "image://colors/yellow" }
    }
}

相关问题