The problem of using QQuickPaintIem to contionously draw images of different size
-
I used QQuickPaintItem to continously draw many images, which had different size. Howerever,except for the first image displayed normally, the other images were automatically cut and scaled. The problem arises when the following image is larger than the first image.
The cpp code is as follows.
ImagePaintItem.h:class ImagePaintItem : public QQuickPaintedItem { Q_OBJECT public: ImagePaintItem(QQuickItem *parent = nullptr); void setItemSize(); void setDisplayImage(const QImage& img); Q_INVOKABLE void setStartImage(); private: void computeDisplayFreq(); void paint(QPainter *painter) override; signals: void sigSetDisplayFreq(QString freq); void sigReleaseResource(); private: QImage m_PaintImage; QMutex m_PaintMutex; QString m_StartImgUrl = ":/resources/icon/first.png"; uint32_t m_LastPointCount; uint32_t m_CurrentPointCount; QDateTime m_LastPointTime; QDateTime m_CurrrentTime; };ImagePaintItem.cpp
ImagePaintItem::ImagePaintItem(QQuickItem *parent) : QQuickPaintedItem(parent) { this->setRenderTarget( QQuickPaintedItem::Image ); m_LastPointCount = 0; m_CurrentPointCount = -1; m_LastPointTime = QDateTime::currentDateTime(); m_CurrrentTime = QDateTime::currentDateTime(); m_OriginalWidth = 0; m_OriginalHeight = 0; } void ImagePaintItem::setDisplayImage(const QImage &img) { m_PaintMutex.lock(); m_PaintImage = img.copy(); m_PaintMutex.unlock(); QMetaObject::invokeMethod(this, [this](){ //this->setContentsSize(QSize(m_PaintImage.width(), m_PaintImage.height())); this->setWidth(m_PaintImage.width()); this->setHeight(m_PaintImage.height()); //this->setTextureSize(QSize(m_PaintImage.width(),m_PaintImage.height())); }, Qt::BlockingQueuedConnection); //QMetaObject::invokeMethod( this, std::bind( &ImagePaintItem::update, this,QRect()), Qt::QueuedConnection ); QMetaObject::invokeMethod( this, "update" , Qt::QueuedConnection); } void ImagePaintItem::setStartImage() { m_PaintMutex.lock(); m_PaintImage.load(m_StartImgUrl, "png"); m_PaintImage = m_PaintImage.scaled(QSize(800,50)); m_PaintMutex.unlock(); QMetaObject::invokeMethod(this, [this](){ //this->setContentsSize(QSize(m_PaintImage.width(), m_PaintImage.height())); this->setWidth(m_PaintImage.width()); this->setHeight(m_PaintImage.height()); }, Qt::QueuedConnection); QMetaObject::invokeMethod( this, "update" , Qt::QueuedConnection); } void ImagePaintItem::computeDisplayFreq() { if(m_CurrentPointCount - m_LastPointCount > 20){ m_CurrrentTime = QDateTime::currentDateTime(); uint32_t msecs = m_LastPointTime.msecsTo(m_CurrrentTime); float freq = 20. * 1000. / float(msecs); m_LastPointCount = m_CurrentPointCount; m_LastPointTime = m_CurrrentTime; emit sigSetDisplayFreq(QString::number(freq, 'f', 2)); } } void ImagePaintItem::paint(QPainter *painter) { m_PaintMutex.lock(); //QQuickPaintedItem::paint(painter); if ( m_PaintImage.isNull() ) { painter->setBrush( QColor( 0, 0, 0 ) ); painter->drawRect( QRect( 0, 0, this->width(), this->height() ) ); } else { painter->drawImage( QRect(0,0,m_PaintImage.width(), m_PaintImage.height()) , m_PaintImage ); } m_CurrentPointCount++; if(m_CurrentPointCount == 1) m_LastPointTime = QDateTime::currentDateTime(); computeDisplayFreq(); emit sigReleaseResource(); m_PaintMutex.unlock(); }The qml code is as follow.
Item{ id: root_item Rectangle{ id: image_item anchors.centerIn: parent //anchors.fill: parent Drag.active: image_mouse_area.drag.active Drag.source: image_paint Drag.supportedActions: Qt.MoveAction height: image_paint.height width: image_paint.width ImagePaintItem { id: image_paint visible: true contentsSize.width: width contentsSize.height: height MouseArea{ id: image_mouse_area anchors.fill: parent drag.target: image_paint cursorShape: Qt.ArrowCursor //z: -10000 onPressed: { if(image_item.state === "no_drag") image_item.state = "has_drag" cursorShape = Qt.ClosedHandCursor } onReleased: { cursorShape = Qt.ArrowCursor } onWheel:function(wheel){ if(wheel.angleDelta.y > 0){ image_paint.scale *= 1.1 } else{ image_paint.scale *= 0.9 } } } Component.onCompleted: { paintManagerPtr.setActiveItem(image_paint) image_paint.setStartImage(); } } state: "no_drag" states:[ State{ name:"has_drag" PropertyChanges { target: image_paint anchors.centerIn: undefined } } ] } }