使用 QQuickImageProvider 的正确方法是啥?
Posted
技术标签:
【中文标题】使用 QQuickImageProvider 的正确方法是啥?【英文标题】:What is the right way to use QQuickImageProvider?使用 QQuickImageProvider 的正确方法是什么? 【发布时间】:2015-05-15 18:58:39 【问题描述】:我需要动态选择 qpixmaps 以显示在 QML Image 项目中。应该从源 qpixmap 中裁剪 qpixmaps,我将从 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 访问它会有问题。这样的设计对我来说似乎很奇怪。还有更优雅的解决方案吗?
【问题讨论】:
这个问题让我很困惑。您遇到的实际问题是什么?你的代码是什么样的? 【参考方案1】:您没有将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)
【讨论】:
感谢您的回答,西蒙!据我了解,此算法将需要检查源图像是否在每次 requestPixmap 调用时发生变化(而 setPath 将允许避免每次检查)。这不能优化吗? QML 确实为您缓存了给定image://
url 的Image
的像素图,因此它假定底层图像不会经常更改。你从哪里得到图像?如果您已经有一种方法可以在图像更改时通知您,请使用信号/插槽将该信息传递给您的图像提供者。但是,一旦您掌握了基本知识,就应该将其放入后续问题中。
我有从文件加载的源图像(“大”)和小图像的 qhash;当第一次请求它的 id 时,每个小图像都是从大图像“懒惰地”裁剪并放入 qhash 的。所以我需要经常更换小图像,而大图像则要少得多。现在我将通过属性控制大图像文件名。以上是关于使用 QQuickImageProvider 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
通过按钮单击触发带有参数的 QQuickImageProvider::requestImage()