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. How to load a piece of an image to QML-form on timer signal
Forum Updated to NodeBB v4.3 + New Features

How to load a piece of an image to QML-form on timer signal

Scheduled Pinned Locked Moved QML and Qt Quick
11 Posts 4 Posters 4.7k Views 1 Watching
  • 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.
  • p3c0P Offline
    p3c0P Offline
    p3c0
    Moderators
    wrote on last edited by
    #2

    Hi,

    AFAIK, you can't use QImage as QML element using Q_PROPERTY.
    Use "qquickimageprovider":http://qt-project.org/doc/qt-5.0/qtquick/qquickimageprovider.html.
    Or
    You can use QUrl and then expose its setter getter using PROPERTY.
    ie.
    @
    Q_PROPERTY(QUrl imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged)
    @
    and once the path is set from the QML element access it from the cpp and "load":http://qt-project.org/doc/qt-5.0/qtgui/qimage.html#load the image.

    157

    1 Reply Last reply
    0
    • G Offline
      G Offline
      gggfggg
      wrote on last edited by
      #3

      Thanks for your reply.

      I started investigating QQuickImageProvider, and request implementation with .fill() method works fine, but when I try to copy the part of an image (QImage or QPixmap) or just try to show the image on QML-form loading it either in request-method itself or before QQuickImageProvider initialization - I still have no result.

      @
      class MyProvider : public QQuickImageProvider
      {
      public:
      QPixmap SourcePixmap;
      MyProvider::MyProvider() : QQuickImageProvider( QQuickImageProvider::Pixmap )
      {
      SourcePixmap.load( "Source.png" );
      }
      QPixmap requestPixmap( const QString &id, QSize *size, const QSize &requestedSize )
      {
      int width = 80;
      int height = 80;
      if( size ) *size = QSize( width, height );
      QPixmap pixmap( requestedSize.width() > 0 ? requestedSize.width() : width,
      requestedSize.height() > 0 ? requestedSize.height() : height );

        // does not work
        pixmap = SourcePixmap.copy( 0, 0, width, height );
      
        /* does not work too
        pixmap.load( "Source80.png" ); */
        
        /* this works
        pixmap.fill( QColor( id ).rgba()); */
      
        return pixmap;
      

      }
      }
      @

      @
      int main( int argc, char *argv[])
      {
      ...
      QQuickView *viewer = new QQuickView;
      viewer -> engine() -> addImageProvider( QLatin1String( "myprovider" ), new MyProvider );
      ...
      }
      @

      @
      // main.qml
      ...
      Image { source: "image://myprovider" }
      ...
      @

      What am i doing wrong?

      [quote author="p3c0" date="1384962646"]Hi,
      You can use QUrl and then expose its setter getter using PROPERTY.
      ie.
      @
      Q_PROPERTY(QUrl imagePath READ imagePath WRITE setImagePath NOTIFY imagePathChanged)
      @
      and once the path is set from the QML element access it from the cpp and "load":http://qt-project.org/doc/qt-5.0/qtgui/qimage.html#load the image.[/quote]

      I didn't understand how can i use your idea with Qurl, as a part of the big image should be chosen randomly (that's why repeats are not very likely), it is not a set of pre-made images, which I form in a single image. I may have not enough knowlegde and experience in QML to understand your idea.

      I also wanted to ask what is better to use in my case - QImage or QPixmap - taking into account that downloading of a source takes place one time. After that very frequent copying of a random fragment, simple random transformation (horizontal/vertical flipping) and showing on QML-form are made.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        stereomatching
        wrote on last edited by
        #4

        I don't know how to use QQuickImageProvider yet(any benefit(s) compare to QQuickPaintedItem?).But QQuickPaintedItem works well for me, you can't set the QImage as property directly, but you could provide QString as property without any problem.

        The full source codes of my custom image is a little bit complex
        Here is the code snippet
        @
        Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged);

        void customImage::setSource(QString source)
        {
        if(source != source_){
        source_ = source;
        imageOrigin_.load(source_);
        update(); //call paint

                emit sourceChanged();        
        }
        

        }

        void customImage::paint(QPainter *painter)
        {
        //paint your image
        if(!img.isNull()){
        painter->drawImage((width() - imageScaled().width()) / 2,
        (height() - imageScaled().height()) / 2, img);
        }else{
        painter->drawImage((width() - imageScaled().width()) / 2,
        (height() - imageScaled().height()) / 2, imageScaled());
        }
        }
        @

        Therefore, you can use your qml component like this

        @
        customImage
        {
        source : "wwww.jpg"
        //other property
        }
        @

        1 Reply Last reply
        0
        • G Offline
          G Offline
          gggfggg
          wrote on last edited by
          #5

          Ok, i got the first result. It appeared that copying a part of a big image on timer signal should be done in request-method. I see the result of the first copying, but update() doesnt't repaint item. I call update in a slot of an item on timer from C++.

          Do you have an idea, what's wrong with this?

          @
          void MyItem::paint( QPainter *painter )
          {
          img = sourceImage.copy( x, y, 100, 100 );
          painter -> drawImage( QPoint(0,0), img );
          }

          void MyItem::myItem_update_Slot()
          {
          update();
          }
          @

          So, I don't use Q_PROPERTY, is it correct?

          1 Reply Last reply
          0
          • S Offline
            S Offline
            stereomatching
            wrote on last edited by
            #6

            Could you reproduce your problems with minimum lines of codes?

            1 Reply Last reply
            0
            • G Offline
              G Offline
              gggfggg
              wrote on last edited by
              #7

              [quote author="stereomatching" date="1385586192"]Could you reproduce your problems with minimum lines of codes?[/quote]

              There are ten lines of code.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                stereomatching
                wrote on last edited by
                #8

                [quote author="gggfggg" date="1385666236"][quote author="stereomatching" date="1385586192"]Could you reproduce your problems with minimum lines of codes?[/quote]

                There are ten lines of code.[/quote]
                What I mean is "please give me a full example which could reproduce your problem with minimum lines of codes" but not asking you "how many lines of codes you write".

                if you want to call the c++ functions from qml site, you need to add Q_PROPERTY before the function or make them become public slots.

                1 Reply Last reply
                0
                • E Offline
                  E Offline
                  eliseev
                  wrote on last edited by
                  #9

                  @gggfggg

                  1. What thread calls MyItem::myItem_update_Slot()? I had similarly sounding problem with update() when it was called from non-UI thread.
                  2. For test's sake put an animated object (e.g. flying rect) into your scene to force redrawing and see if scene updates (update content with timer at the same time).

                  @stereomatching
                  bq. if you want to call the c++ functions from qml site, you need to add Q_PROPERTY before the function or make them become public slots.
                  Correction, it's Q_INVOKABLE
                  But he doesn't need it.

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    stereomatching
                    wrote on last edited by
                    #10

                    [quote author="Sergei Eliseev" date="1385743150"]@gggfggg

                    1. What thread calls MyItem::myItem_update_Slot()? I had similarly sounding problem with update() when it was called from non-UI thread.
                    2. For test's sake put an animated object (e.g. flying rect) into your scene to force redrawing and see if scene updates (update content with timer at the same time).

                    @stereomatching
                    bq. if you want to call the c++ functions from qml site, you need to add Q_PROPERTY before the function or make them become public slots.
                    Correction, it's Q_INVOKABLE
                    But he doesn't need it.[/quote]

                    Thanks for your correction, I didn't notice it

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      gggfggg
                      wrote on last edited by
                      #11

                      [quote author="stereomatching" date="1385677858"]
                      What I mean is "please give me a full example which could reproduce your problem with minimum lines of codes"[/quote]
                      I thought you need less.

                      [quote author="Sergei Eliseev" date="1385743150"]
                      What thread calls MyItem::myItem_update_Slot()?[/quote]
                      MyItem::myItem_update_Slot() calls on timer signal. I don't use multi-threading in my code. Here I connect timer with update():
                      @
                      MyModel::MyModel( QObject *parent ) : QObject( parent )
                      {
                      myitem = new MyItem();
                      mytimer = new QTimer;
                      mytimer -> setInterval( 100 );
                      connect(mytimer, SIGNAL(timeout()), myitem, SLOT(myItem_update_Slot()));
                      mytimer -> start();
                      }
                      @
                      And the less of the code once again:
                      @
                      void MyItem::myItem_update_Slot()
                      {
                      x = rand() % 1400;
                      y = rand() % 1400;
                      j = rand() % 100;
                      k = rand() % 100;
                      update();
                      }

                      void MyItem::paint( QPainter *painter )
                      {
                      img = sourceImage.copy( x, y, 100, 100 );
                      painter -> drawImage( QPoint( j, k ), img );
                      // flying rect
                      // painter -> fillRect( j, k, 50, 50, Qt::black );
                      }

                      // main.qml
                      import QtQuick 2.0
                      import MyItem 1.0

                      Rectangle {
                      width: 360
                      height: 360
                      MyItem{
                      width: 300
                      height: 300
                      }
                      }
                      @
                      [quote author="Sergei Eliseev" date="1385743150"]
                      For test's sake put an animated object[/quote]
                      Thanks for the idea, I've checked it as demonstrated above (if I got it right). update() is being called, but repaint isn't done. I suspect that it can be related to the visibility scope of vars inside paint() during update() calling.

                      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