我正在尝试将 QImage 从 c++ 更新为 QML,
我正在使用以下方法: https: //www.huber.xyz/?p =477
我实现了 QQuickPaintedItem - 显示了初始 QImage,但如果我在那里收到信号(FileWatcher),我找不到从 c++ 更新 QImage 的方法。
我的实现如下所示:
质量管理语言:
ImageItem {
id: liveImageItem
height: parent.height
width: parent.width
objectName: "liveImageItem"
}
Run Code Online (Sandbox Code Playgroud)
我将图像注册为:
qmlRegisterType<QUIQImageItem>("imageItem", 1, 0, "ImageItem");
Run Code Online (Sandbox Code Playgroud)
图像的实现:
ImageItem::ImageItem(QQuickItem *parent) : QQuickPaintedItem(parent) {
qDebug() << Q_FUNC_INFO << "initializing new item, parent is: " << parent;
this->current_image = QImage(":/resources/images/logo.png");
}
void ImageItem::paint(QPainter *painter) {
qDebug() << Q_FUNC_INFO << "paint requested...";
QRectF bounding_rect = boundingRect();
QImage scaled = this->current_image.scaledToHeight(bounding_rect.height());
QPointF center = bounding_rect.center() - scaled.rect().center();
if (center.x() < 0)
center.setX(0);
if (center.y() < 0)
center.setY(0);
painter->drawImage(center, scaled);
}
QImage ImageItem::image() const {
qDebug() << Q_FUNC_INFO << "image requested...";
return this->current_image;
}
void ImageItem::setImage(const QImage &image) {
qDebug() << Q_FUNC_INFO << "setting new image...";
this->current_image = image;
emit imageChanged();
update();
}
Run Code Online (Sandbox Code Playgroud)
如何在 C++ 端获取 ImageItem 的引用来通过 setImage 管理图像的更新?
这种方法可行还是我应该尝试其他解决方案?
我试图通过以下方式获取该物品
QList<ImageItem*> res = engine->findChildren<ImageItem*>();
Run Code Online (Sandbox Code Playgroud)
并且:
QList<ImageItem*> res = engine->findChildren<ImageItem*>("liveImageItem");
Run Code Online (Sandbox Code Playgroud)
ImageItems (res) 列表始终为空。
一般来说,您应该避免直接从 C++ 修改 QML 中创建的项目,在此之前我将通过将图像添加为 qproperty 来改进您的实现:
*。H
#ifndef IMAGEITEM_H
#define IMAGEITEM_H
#include <QImage>
#include <QQuickPaintedItem>
class ImageItem : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged)
public:
ImageItem(QQuickItem *parent = nullptr);
QImage image() const;
void setImage(const QImage &image);
void paint(QPainter *painter);
signals:
void imageChanged();
private:
QImage m_image;
};
#endif // IMAGEITEM_H
Run Code Online (Sandbox Code Playgroud)
*.cpp
#include "imageitem.h"
#include <QDebug>
#include <QPainter>
ImageItem::ImageItem(QQuickItem *parent):QQuickPaintedItem(parent)
{
qDebug() << Q_FUNC_INFO << "initializing new item, parent is: " << parent;
setImage(QImage(":/resources/images/logo.png"));
}
QImage ImageItem::image() const
{
qDebug() << Q_FUNC_INFO << "image requested...";
return m_image;
}
void ImageItem::setImage(const QImage &image)
{
qDebug() << Q_FUNC_INFO << "setting new image...";
if(image == m_image)
return;
m_image = image;
emit imageChanged();
update();
}
void ImageItem::paint(QPainter *painter)
{
if(m_image.isNull())
return;
qDebug() << Q_FUNC_INFO << "paint requested...";
QRectF bounding_rect = boundingRect();
QImage scaled = m_image.scaledToHeight(bounding_rect.height());
QPointF center = bounding_rect.center() - scaled.rect().center();
if (center.x() < 0)
center.setX(0);
if (center.y() < 0)
center.setY(0);
painter->drawImage(center, scaled);
}
Run Code Online (Sandbox Code Playgroud)
在这一部分中,我将回答您的直接问题,尽管这不是最好的,因为如果您不知道如何处理,您可能会遇到问题,例如,如果您在页面中设置项目,StackView因为每次更改时都会创建和删除它们页。
QObject *obj = engine.rootObjects().first()->findChild<QObject*>("liveImageItem");
if(obj){
QImage image = ...;
QQmlProperty::write(obj, "image", image);
}
Run Code Online (Sandbox Code Playgroud)
示例: main.cpp
#include "imageitem.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlProperty>
#include <QTime>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qsrand(QTime::currentTime().msec());
qmlRegisterType<ImageItem>("com.eyllanesc.org", 1, 0, "ImageItem");
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QObject *obj = engine.rootObjects().first()->findChild<QObject*>("liveImageItem");
QTimer timer;
if(obj){
QObject::connect(&timer, &QTimer::timeout, [obj](){
QImage image(100,100, QImage::Format_ARGB32);
image.fill(QColor(qrand()%255, qrand()%255, qrand()%255));
QQmlProperty::write(obj, "image", image);
});
timer.start(1000);
}
return app.exec();
}
Run Code Online (Sandbox Code Playgroud)
对我来说,更好的想法是实现一个 Helper 并在 QML 中建立连接:
#include "imageitem.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlProperty>
#include <QQmlContext>
#include <QTime>
#include <QTimer>
class Helper: public QObject{
Q_OBJECT
Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged)
public:
QImage image() const{ return m_image; }
void setImage(const QImage &image){
if(m_image == image)
return;
m_image = image;
emit imageChanged();
}
signals:
void imageChanged();
private:
QImage m_image;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qsrand(QTime::currentTime().msec());
qmlRegisterType<ImageItem>("com.eyllanesc.org", 1, 0, "ImageItem");
QGuiApplication app(argc, argv);
Helper helper;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("helper", &helper);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QTimer timer;
QObject::connect(&timer, &QTimer::timeout, [&helper](){
QImage image(100,100, QImage::Format_ARGB32);
image.fill(QColor(qrand()%255, qrand()%255, qrand()%255));
helper.setImage(image);
});
timer.start(1000);
return app.exec();
}
#include "main.moc"
Run Code Online (Sandbox Code Playgroud)
*.qml
...
ImageItem{
id: liveImageItem
height: parent.height
width: parent.width
}
Connections{
target: helper
onImageChanged: liveImageItem.image = helper.image
}
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4251 次 |
| 最近记录: |