Page 1 of 2 12 LastLast
Results 1 to 20 of 21

Thread: QGraphicsView scale question.

  1. #1
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default QGraphicsView scale question.

    Hello to everyone,

    Here is what i have:
    - a QDialog, containing a QGraphicsView.
    - The View is "containing" a Scene, in which i only put a QImage.
    - In the QDialog, there is a Zoom out button which scale(.5, .5) on the View, and another Zoom in button which scale(2, 2) the View.

    Now i wish to add another widget on the graphics view, which is on top of all others (The QImage), but which doesnt "scales". What is the best thing to do to achieve this?
    In other words: do i have to only scale the QImage (So the other widget doesnt scales)? If yes, how?

    Thanks a lot!
    Pierre.

  2. #2
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Hello again,

    I just figured that i am able to scale directly on a QGraphicsItem... which is very good for me, because it solves my problem.

    However i have a related question. Let's take for instance a QGraphicsItem, which originaly was containing a QImage. After i retrieve the QGraphicsItem with QGraphicsView::items(), how can i get a pointer to the QImage it contains, so i can change it's contents without putting a new QPicture each time?

    Thanks,
    Pierre.

  3. #3
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Do you use QGraphicsPixmapItem to display the pixmap?
    If you do, you can use the pixmap() and setPixmap() to get/set the pixmap...

    QGraphicsView::items() will return a list of QGraphicsItem. You will have to do a cast to QGrasphicsPixmapItem.

    Regards.

  4. #4
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Hello Marcel, and thanks for answering.

    When adding the item to my scene, i simply do a addItem(myQImage);
    Do you confirm that this QImage is then put in a QGraphicsPixmapItem?

    Pierre.

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Yes, it will add a QGraphicsPixmapItem since it is the only item that can hold a pixmap.

    Why do you use a QImage and why not use addPixmap() ?

  6. #6
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Ok, so it's impossible that if i change the QImage, i see the changes in the scene right?
    Or does the QGraphicsPixmap work with a pointer to my QImage? oO

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    No, it passes a reference to the constructor of QGraphicsPixmapItem and then the operator= of QPixmap will copy your original pixmap into a QGraphicsPixmapItem.

    Just checked it in the sources..

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Hey, have you actually implemented this?

    Because:
    Qt Code:
    1. QImage img;
    2. scene->addItem( img );
    To copy to clipboard, switch view to plain text mode 
    will not even compile.

    Try with QPixmap and addPixmap. Or just construct a QPixmapGraphicsItem from a QPixmap and just use addItem to add it to the scene.

    Regards

  9. #9
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Ouch

    So all this means, if i just constructed a QImage of 1600x1200, then the QGraphicsPixmapItem implicitely created when calling addItem(myQImage) will hold another copy of my image, i'm glad i have 1Gb ram then

    [EDIT:]You're right, what i'm actually doing is grphScToFill->addPixmap(QPixmap::fromImage(cImage, Qt::ColorOnly | Qt::ThresholdDither));

    Now another simple question since you seem to know pretty much about the QGraphics framework:
    Previously, when the user pressed the zoom +/- buttons, i was scaling the scene. It was very nice, since the point where the view were focused was staying on the center after the scale process. Also, when a zoom level like 0.5 was hit, the scene content was centered within the rectangle of my view...

    Now what i am doing, is to scale directly the graphic item instead of the whole scene... But i have a problem doing this: when i scale to a width / height lower than the visible rect, the item is put on the top left corner, and the scene content is still "draggable" to much more top left...

    So i have tried to setPos on my item each time i resize it, it doesnt moves in scene. I also tried to change the sceneRect to fit the item, but i wasnt able to get the item size...

    What am i doing / understanding wrong?

    Thanks ^^

  10. #10
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Now another simple question since you seem to know pretty much about the QGraphics framework:
    Not really that much...

    Use void QGraphicsView::centerOn ( const QPointF & pos ).
    As pos pass the center of your QGraphicsPixmapItem. Pos is scene coords.

    As an alternative, use void QGraphicsView::ensureVisible ( const QRectF & rect, int xmargin = 50, int ymargin = 50 ).
    rect is scene cords.

    Regards.

  11. #11
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Hello again

    Well i'm sorry, but i'm not sure i understand how to do what you recomend
    When i call centerOn(), i have to give some coordinates to the method. Do i have to give the coordinates of the center of my scalled Item as you say: let's take as example my item is scalled down to 0.5 two times, do i have to take my QGraphicsPixmapItem width / height, divide it by 4 (Get item's size in view local coords system after scale), divide the result by 2 (For the center), and then give to centerOn the result added to the position of my item in the scene?

    I tried several methods, for you i have made some screenshots of what i get.
    On the pictures, you can clearly see that after the item is resized, it is "stuck" to top left corned, and is still draggable (But not to the center).

    Anyway thanks, maybe if i try various stuff i'll find why i'm wrong
    Pierre.
    Attached Images Attached Images

  12. #12
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    I just have tried this (Note that iZoomFactor is an int, which is 100 for a scale of 1, 50 for a scale of .5 etc):
    Qt Code:
    1. pPicture = (QGraphicsPixmapItem*)grphVwOriginalPicture->items().first();
    2. pPicture->scale(.5, .5);
    3. QPoint cCenterOn;
    4. // [EDIT:] Here i get the size of the item in the view coords system, divide it by 2 (For the center) and add it's position.
    5. cCenterOn.setX( (100/pPicture->pixmap().width()*iZoomFactor) / 2 + pPicture->pos().x() );
    6. cCenterOn.setY( (100/pPicture->pixmap().height()*iZoomFactor) / 2 + pPicture->pos().y() );
    7. grphVwOriginalPicture->centerOn(cCenterOn);
    To copy to clipboard, switch view to plain text mode 
    But the same problem is here... I'm not sure of what i can try next, but for now i'm stuck.

    [EDIT:]Attached is what i want, it's achieved by scaling the whole scene instead of the item. But i cant keep scaling the whole scene, since i'll have to put another item in it which has to not be scaled.

    Pierre.
    Attached Images Attached Images
    Last edited by hickscorp; 14th April 2007 at 18:52.

  13. #13
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    No, I believe you have to use scene coords instead of view coords. After all, you are trying to center the scene.

    BTW: what app are you working on? some kind of photoshop? looks pretty good... especially the tabs in the upper control bar.

    Regards.

  14. #14
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Please see previous post i edited with some screenshots.

    So as you say, my misstake is probably the referential. I'll try to look at this more further soon, but for now i have lost the faith

    What i'm trying to do is actually a plugin for Photoshop. What you see is actually Photoshop
    We decided to use the QT commercial edition for the gui, since Photoshop exists on Mac and since i worked on QT for some opensource stuff, i was able to make the financials of this company buy QT ^^

    Pierre.

  15. #15
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Yes... I didn't realize it was photoshop... The plugin looks good.

    Use scene coordinates for centerOn and do not take into account the zoom factor. Just use:

    Qt Code:
    1. view->centerOn( itemCenterPosInSceneCoords ).
    To copy to clipboard, switch view to plain text mode 


    Because if you scale only the item, the scale factor of the scene will not change. You will just have a bigger( smaller ) item, depending on the zoom.

  16. #16
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Yeah but to get what you call the "item center in the scene", how am i supposed to do, since i cant get the item's width / height?
    i would do centerOn(QPoint(item->x()+item->Width()/2, item->y()+item->Height()/2)), but there are not such methods width() height()! So how do i get the item's center?
    Pseudo code please, i'm totally lost

    Pierre.

    [EDIT:] Maybe you should just try this: create a graphics view, put a big QImage in it. Then tell the image to scale down, and try to center it. Also when the picture is big, it is draggable off-view.
    Last edited by hickscorp; 14th April 2007 at 19:14.

  17. #17
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Ok. I have played a little bit with QGraphicsView/Scene.

    Here's the code:

    Qt Code:
    1. QGraphicsItem* itm = mDocument->getCurrentPage()->items()[0];
    2. QRectF f= itm->boundingRect();
    3. QPointF mapped1 = itm->mapToScene( f.topLeft() );
    4. QPointF mapped2 = itm->mapToScene( f.bottomRight() );
    5. centerOn( ( mapped2.x() - mapped1.x() )/2, ( mapped2.y() - mapped1.y() )/2 );
    To copy to clipboard, switch view to plain text mode 
    That's it...
    This is done in a QGraphicsView class...
    I guess you can do it wherever you need it.

    NOTE: When you scale an item, the top left position always remains the same.

    Regards.

  18. The following user says thank you to marcel for this useful post:

    hickscorp (15th April 2007)

  19. #18
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    Hello sorry for the delay

    With your code, i have the very same problem. The item is "stuck" to the top left corner, and only can be dragged off-screen when it is little. When it's bigger than the viewable area, it's draggable but can be sragged off-screen in the top left direction too.

    There comes a preview of my code:

    Qt Code:
    1. void CDlgSettingsImpl::on_btnZoomIn_clicked(void) {
    2. if (iZoomFactor>=1600)
    3. return;
    4. iZoomFactor *= 2;
    5. lblZoomLevel->setText(QString::number(iZoomFactor)+"%");
    6.  
    7. QGraphicsItem* pPicture;
    8. QPointF mapped1, mapped2;
    9. QRectF f;
    10.  
    11. pPicture = grphVwOriginalPicture->items().first();
    12. pPicture->scale(2, 2);
    13. f = pPicture->boundingRect();
    14. mapped1 = pPicture->mapToScene(f.topLeft());
    15. mapped2 = pPicture->mapToScene(f.bottomRight());
    16. grphVwOriginalPicture->centerOn((mapped2.x()-mapped1.x())/2, (mapped2.y()-mapped1.y())/2);
    17. }
    18. void CDlgSettingsImpl::on_btnZoomOut_clicked(void) {
    19. if (iZoomFactor<=25)
    20. return;
    21. iZoomFactor /= 2;
    22. lblZoomLevel->setText(QString::number(iZoomFactor)+"%");
    23.  
    24. QGraphicsItem* pPicture;
    25. QPointF mapped1, mapped2;
    26. QRectF f;
    27.  
    28. pPicture = grphVwOriginalPicture->items().first();
    29. pPicture->scale(.5, .5);
    30. f = pPicture->boundingRect();
    31. mapped1 = pPicture->mapToScene(f.topLeft());
    32. mapped2 = pPicture->mapToScene(f.bottomRight());
    33. grphVwOriginalPicture->centerOn((mapped2.x()-mapped1.x())/2, (mapped2.y()-mapped1.y())/2);
    34. }
    To copy to clipboard, switch view to plain text mode 

    Can it be a bug with my QT installation? i havnt tested any of the QGraphics framework on linux, so i'm not sure if it's windows only ...

    Pierre.

    [EDIT:] Maybe the error is here, so here comes how i create the QGraphicsScene & View stuff (In the dialog's constructor):
    Qt Code:
    1. // Create the original preview objects.
    2. grphScOriginal = new QGraphicsScene(this);
    3. grphVwOriginalPicture = new QGraphicsView(grphScOriginal, this);
    4. grphVwOriginalPicture->setFrameShape(QFrame::Panel);
    5. grphVwOriginalPicture->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    6. grphVwOriginalPicture->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    7. grphVwOriginalPicture->setDragMode(QGraphicsView::ScrollHandDrag);
    8. grphVwOriginalPicture->setBackgroundBrush(Qt::darkGray);
    9. fillPreviewFromPlane(grphScOriginal, pInPlane);
    10.  
    11. void CDlgSettingsImpl::fillPreviewFromPlane(QGraphicsScene* grphScToFill, CARGBPlane* pPlane) {
    12. QList<QGraphicsItem*> lstItems = grphScToFill->items();
    13. while (!lstItems.isEmpty()) {
    14. QGraphicsItem* pCurrentItem = lstItems.takeFirst();
    15. grphScToFill->removeItem(pCurrentItem);
    16. delete pCurrentItem;
    17. }
    18. QImage cImage = QImage(pPlane->Width(), pPlane->Height(), QImage::Format_RGB32);
    19. byte* fR = pPlane->fR;
    20. byte* fG = pPlane->fG;
    21. byte* fB = pPlane->fB;
    22. for (int iY=0; iY<pPlane->Height(); iY++)
    23. for (int iX=0; iX<pPlane->Width(); iX++)
    24. cImage.setPixel(iX, iY, qRgb(*fR++, *fG++, *fB++));
    25. grphScToFill->addPixmap(QPixmap::fromImage(cImage, Qt::ColorOnly | Qt::ThresholdDither));
    26. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by hickscorp; 15th April 2007 at 00:26.

  20. #19
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    I believe i have found the "why". In the documentation, it is said this:
    sceneRect : QRectF
    This property holds the scene rectangle; the bounding rectangle of the scene.
    The scene rectangle defines the extent of the scene. It is primarily used by QGraphicsView to determine the view's default scrollable area, and by QGraphicsScene to manage item indexing.
    If unset, or if set to a null QRectF, sceneRect() will return the largest bounding rect of all items on the scene since the scene was created (i.e., a rectangle that grows when items are added to or moved in the scene, but never shrinks).


    Which means, if my scene is created containing a QImage of 1600x1200 and if i scale down this image to 800x600, the sceneRect will still be 1600x1200. So i just tried to do a "grphScProcessed->setSceneRect(pPicture->boundingRect());" right after my item is scaled down, but same problem. Any clue please?

    Pierre.

  21. #20
    Join Date
    Dec 2006
    Posts
    160
    Thanks
    33
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsView scale question.

    ok i think i have finally found what i needed. Here is what i do now, right after changing the scale of my item in the scene:

    Qt Code:
    1. pPicture = grphVwOriginalPicture->items().first();
    2. pPicture->scale(.5, .5);
    3. cTopLeft = pPicture->mapToScene(pPicture->boundingRect().topLeft());
    4. cBotRight = pPicture->mapToScene(pPicture->boundingRect().bottomRight());
    5. grphScOriginal->setSceneRect(cTopLeft.x(), cTopLeft.y(), cBotRight.x()-cTopLeft.x(), cBotRight.y()-cTopLeft.y());
    To copy to clipboard, switch view to plain text mode 

    It seems it's sufficient to set up the scene's view rect to the right rect...

    Marcel, thanks for all your help, it's because of you i finally understood what the mappedTo / mappedFrom methods do

    Pierrre.

Similar Threads

  1. Replies: 1
    Last Post: 15th March 2007, 20:45
  2. Using QGraphicsView with model/view programming
    By JLP in forum Qt Programming
    Replies: 3
    Last Post: 29th January 2007, 11:04
  3. Question regarding how to paint after zoom.
    By JonathanForQT4 in forum Qt Programming
    Replies: 2
    Last Post: 26th January 2007, 15:34
  4. Efficient Scaling and Rotating of QGraphicsView
    By forrestfsu in forum Qt Programming
    Replies: 10
    Last Post: 12th December 2006, 16:28
  5. QGraphicsView scale function
    By forrestfsu in forum Qt Programming
    Replies: 2
    Last Post: 12th October 2006, 14:05

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.