Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. The problem of using QQuickPaintIem to contionously draw images of different size
Forum Updated to NodeBB v4.3 + New Features

The problem of using QQuickPaintIem to contionously draw images of different size

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 137 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lenlend
    wrote on last edited by Lenlend
    #1

    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
                    }
                }
            ]
        }
    }
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved