Results 1 to 3 of 3

Thread: select QPixmap area with mouse

  1. #1
    Join Date
    Nov 2007
    Posts
    103
    Thanks
    71
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default select QPixmap area with mouse

    Hi. I have a code (please see below) that displays a user-provided bitmap image (image_ori.bmp) when a pushbutton is clicked. I want the user to be able to select two coordinates on the image using mouse (one left click and one right click) and by doing it, crop the picture. Then I want the cropped picture to be displayed instead of the original picture. When the pushbutton is clicked, the original picture (uncropped) is displayed again.
    I can get this to sort of work. But the coordinates are off and selection is offset. I think this is because I use global coordinates but I need local to that QLabel widget. How do you get local coordinates with mouse? Do you need to subclass mouse event for that (in the same subclass with the QLabel that displays the picture?)?
    Also, what's the best way of avoiding having to save an load files every time you crop the picture like I rather unprofessionally do it?
    I know you say that the QLabel approach is not the best for cropping and displaying but I kind of need to stick to this weird appraoch because a program that I write this code for requires this approach. Thanks a lot guys!

    Qt Code:
    1. ////////////////////////main.cpp//////////////////////////////
    2. #include <QApplication>
    3. #include <QtGui>
    4. #include "tom.h"
    5.  
    6. int right_x, right_y, left_x, left_y;
    7.  
    8. MyWidget::MyWidget(QWidget* parent): QWidget(parent)
    9. {
    10. m_pixmapLabel = new QLabel;
    11. m_drawButton = new QPushButton("&Load Original Image");
    12. connect(m_drawButton, SIGNAL(clicked()), this, SLOT(refresh()));
    13. QVBoxLayout* mainLayout = new QVBoxLayout;
    14. mainLayout->addWidget(m_pixmapLabel);
    15. mainLayout->addWidget(m_drawButton);
    16. setLayout(mainLayout);
    17. }
    18.  
    19. void MyWidget::refresh()
    20. {
    21. QPixmap pm3;
    22. pm3.load("image_ori.bmp");
    23. pm3.save("image.bmp", 0, -1);
    24. testDraw();
    25. }
    26.  
    27. void MyWidget::testDraw()
    28. {
    29. right_x=-1;
    30. right_y=-1;
    31. left_x=9999;
    32. left_y=9999;
    33. QPixmap pm;
    34. pm.load("image.bmp");
    35. m_pixmapLabel->setPixmap(pm);
    36. }
    37.  
    38. void MyWidget::mousePressEvent(QMouseEvent *event)
    39. {
    40. if (event->button() == Qt::RightButton)
    41. {
    42. right_x=event->x();
    43. right_y=event->y();
    44. }
    45. if
    46. (event->button() == Qt::LeftButton)
    47. {
    48. left_x=event->x();
    49. left_y=event->y();
    50. }
    51.  
    52. if ( (right_x - left_x) >=0 && (right_y - left_y >=0) && (left_x !=9999) && (right_x !=-1))
    53. {
    54. QPixmap pm2;
    55. pm2.load("image.bmp");
    56. pm2 = pm2.copy(left_x,left_y,right_x,right_y);
    57. pm2.save("image.bmp", 0, -1);
    58. m_pixmapLabel->setPixmap(pm2);
    59. }
    60.  
    61. else QWidget::mousePressEvent(event);
    62. }
    63.  
    64.  
    65. int main(int argc, char *argv[])
    66. {
    67. QApplication application(argc, argv);
    68. MyWidget window;
    69. window.show();
    70. return application.exec();
    71. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. ////////////////////////////////////tom.h///////////////////////////////////////
    2. #ifndef TOM_H
    3. #define TOM_H
    4.  
    5. #include <QtGui>
    6. class MyWidget : public QWidget
    7. {
    8. Q_OBJECT
    9. public:
    10. MyWidget (QWidget* parent = 0);
    11. protected:
    12. void mousePressEvent(QMouseEvent *event);
    13.  
    14. public slots:
    15. void testDraw();
    16. void refresh();
    17. private:
    18. QLabel* m_pixmapLabel;
    19. QPushButton* m_drawButton;
    20. };
    21.  
    22. #endif
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 16th November 2007 at 20:07. Reason: missing [code] tags

  2. #2
    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: select QPixmap area with mouse

    You have to subclass QLabel and reimplement mousePressEvent, mouseMoveEvent and paintEvent.

    In mousePressEvent: store the crop coordinates in a QRect or two QPoint's. The local coordinates are stored in the event.
    When you receive the right click(you should implement some kind of click counting - a boolean flag, etc) you have the two local coordinates. Now you can crop the pixmap and set it in the label.

    In mouseMoveEvent: after you have the coordinate for the left mouse click you can update the second coordinate with the current mouse position stored in the event.

    In paintEvent: draw the crop rectangle specified by the left click position and right click position or current mouse position(if you didn't have a right click yet). Note that you first have to call QLabel:aintEvent and then draw your crop rectangle, because you want the label to be able to draw its initial contents.


    As for storing the pixmaps, you can do that with a 1 QPixmap member, for the original image.

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

    tommy (16th November 2007)

  4. #3
    Join Date
    Nov 2007
    Posts
    103
    Thanks
    71
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default thanks marcel

    Thanks for your useful answer, I now know where to kind of start. My only problem is that I'm not at that level yet. I don't fully understand all the aspects of the general outline you provided.
    May I ask you to be a bit more specific. My general questions are:
    1. OK, I subclass QLabel. I guess I do it exacly like I subclassed MyWidget in the above example. So I guess the QLabel subclass is going to hold (under protected mousePressEvent(), mouseMoveEvent() and paintEvent(). Is it also going to create the m_pixmapLabel instance? If I put this in the QLabel subclass it needs to be in the appropriate constructor, meaning that I cannot add it to my mainLayout (which is subclassed in MyWidget).
    2. Am I still going to have the MyWidget subclass for the pushbutton and everything else that is not the QLabel where the picture is going to appear?
    3. How do I make the objects of the two different subclasses to interact? I mean how do I ensure that the mouse is going to work on the right object?
    4. I guess my questions mostly all boil down to the fact that I am not getting how the mouse events work. Mouse seems to behave very differently from the usual signal/slot.
    5. Maybe the easiest thing for me would be to look at some example code where people have done a similar thing. Do you know of any such postings.
    Thanks a lot!

Similar Threads

  1. Weird behaviour of mouse events and QMenu pop-ups
    By Ishark in forum Qt Programming
    Replies: 1
    Last Post: 7th August 2007, 07:46
  2. select a particular area
    By vishesh in forum Qt Programming
    Replies: 4
    Last Post: 28th February 2007, 21:44

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.