PDA

View Full Version : drawing over QLabel



tommy
16th November 2007, 21:27
Hi.
I'd like to know how to draw a selection rectangle over a label (QLabel) so that the QLabel continues to show. I think I need to somehow call QLabel::PaintEvent, but I don't know how.
Thanks.

jpn
16th November 2007, 22:07
How about QRubberBand?

tommy
16th November 2007, 23:12
Thanks for the idea. I looked up QRubberBand but can't get it to work (getting "origin" and "m_pixmapLabel" not defined errors). I am misunderstanding something. I put my code below. Thanks!



#include <QApplication>
#include <QtGui>
#include "definitions.h"

int origin =0;

MyWidget::MyWidget(QWidget* parent): QWidget(parent)
{
m_pixmapLabel = new QLabel;
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
QVBoxLayout* mainLayout = new QVBoxLayout;
QPixmap pm;
pm.load("image.bmp");
m_pixmapLabel->setPixmap(pm);
mainLayout->addWidget(m_pixmapLabel);
setLayout(mainLayout);

}

void MyWidget::mouseMoveEvent(QMouseEvent *event)
{
rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}

void MyWidget::mousePressEvent(QMouseEvent *event)
{
origin = event->pos();
rubberBand->setGeometry(QRect(origin, QSize()));
rubberBand->show();
}

void MyWidget::mouseReleaseEvent(QMouseEvent *event)
{
rubberBand->hide();
}


int main(int argc, char *argv[])
{
QApplication application(argc, argv);
MyWidget window;
window.show();
return application.exec();
}

jpn
16th November 2007, 23:23
I looked up QRubberBand but can't get it to work (getting "origin" and "m_pixmapLabel" not defined errors). I am misunderstanding something.
Well, the documentation expects you to know basics of C++. ;) You must define them as member variables:


class MyWidget
{
...
private:
QPoint origin;
QRubberBand* rubberBand;
};

PS. I presumed you meant "rubberBand" with "m_pixmapLabel" since QRubberBand docs talk nothing about "m_pixmapLabel".

tommy
16th November 2007, 23:53
Thanks again jpn. I had forgotten QPoint and I made the change. QRubberBand was declared correctly all along. Nevertheless the code won't work (compains about origin and mouseReleaseEvent). I pasted the current code again - in case you have a minute. Thanks a lot.




#include <QApplication>
#include <QtGui>
#include "tom.h"


MyWidget::MyWidget(QWidget* parent): QWidget(parent)
{
m_pixmapLabel = new QLabel;
origin = new QPoint;
origin.setX(0);
origin.setY(0);
rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
QVBoxLayout* mainLayout = new QVBoxLayout;
QPixmap pm;
pm.load("image.bmp");
m_pixmapLabel->setPixmap(pm);
mainLayout->addWidget(m_pixmapLabel);
setLayout(mainLayout);
}

void MyWidget::mouseMoveEvent(QMouseEvent *event)
{
rubberBand->setGeometry(QRect(origin, event->pos()).normalized());
}

void MyWidget::mousePressEvent(QMouseEvent *event)
{
origin = event->pos();
rubberBand->setGeometry(QRect(origin, QSize()));
rubberBand->show();
}

void MyWidget::mouseReleaseEvent(QMouseEvent *event)
{
rubberBand->hide();
}


int main(int argc, char *argv[])
{
QApplication application(argc, argv);
MyWidget window;
window.show();
return application.exec();
}




#ifndef TOM_H
#define TOM_H

#include <QtGui>

class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget (QWidget* parent = 0);
protected:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event)
private:
QLabel* m_pixmapLabel;
QRubberBand* rubberBand;
QPoint origin;
};

#endif

pherthyl
17th November 2007, 00:08
missing a semicolon after mouseReleaseEvent in the header.....

jpn
17th November 2007, 00:09
Nevertheless the code won't work (compains about origin and mouseReleaseEvent). I pasted the current code again - in case you have a minute.
Always paste the error whenever you bump into such situation, please. Seeing the error message helps us a lot to tell where's the problem. We are not walking compilers... :)




origin = new QPoint;

This is clearly wrong, "origin" was not declared as pointer. You can simply drop the line.




origin.setX(0);
origin.setY(0);

You can drop these as well. As you can see from the documentation (http://doc.trolltech.com/4.3/qpoint.html#QPoint), the default constructor of QPoint already initializes the point to (0,0).

wysota
17th November 2007, 00:18
We are not walking compilers... :)

Jacek is...

pherthyl
17th November 2007, 00:30
Hey now, what is this blatant nepotism... Admins handing thanks out to each other like it was candy.. ;)

tommy
17th November 2007, 00:31
Hi jpn,

I think you got it wrong. I think you are a walking compiler - and more. You're better than a compiler because you can trouble-shoot so much better than a compiler :). Anyway, thank you so much for being so helpful and patient with someone who doesn't yet know a whole lot about Qt or C++.
If I may ask one last question here, that would be:
What's the best way to get local coordinates out of the rubberband once the label which I rubberband (this is a verb as in "to rubberband something") becomes a part of my main layout?
I intend to start using the rubberband for cropping.

Thanks

wysota
17th November 2007, 00:37
Hey now, what is this blatant nepotism... Admins handing thanks out to each other like it was candy.. ;)

Well... J-P is not an admin :) And I'm really an AI - ask Kumosan (http://www.qtcentre.org/forum/u-kumosan-2017.html), he'll tell ya...

jpn
17th November 2007, 00:41
Hey now, what is this blatant nepotism... Admins handing thanks out to each other like it was candy.. ;)
Indeed, I'm no admin. And I never thought I was spreading too many "thanks". Also, believe or not, that really cheered me up! :)


What's the best way to get local coordinates out of the rubberband once the label which I rubberband (this is a verb as in "to rubberband something") becomes a part of my main layout?
Child widget's coordinates are always relative to its parent. You can use various QWidget::mapTo*() and QWidget::mapFrom*() methods to map the coordinates if needed.

pherthyl
17th November 2007, 00:43
Once you're done dragging the rubberband (in the mouseReleaseEvent for example) you can use rubberBand->geometry() to get the rectangle defining this rubber band (in the coordinates of the parent).

pherthyl
17th November 2007, 00:45
Indeed, I'm no admin. And I never thought I was spreading too many "thanks". Also, believe or not, that really cheered me up! :)

I was just kidding. Hence the smiley. I thought it was funny too. :)

tommy
17th November 2007, 01:08
That's great, the rubberband works great for me now and I also know how to get the coordinates out, but the problem is that my picture that I display (as part of the label) is a bit smaller than the label; also, the label does not extend all the way to the edges of the main layout. As a result of that the upper left coordinate of my picture is about (10,10) as opposed to the desired (0,0). And worse yet: as I expand and shrink the window, my label swims around in it and the coordinates change all the time. How'm I ever going to use this approach for cropping of my pixmap image.

wysota
17th November 2007, 01:10
Map the coordinates of the rubberband to the label geometry using QWidget::mapTo.

tommy
17th November 2007, 01:30
....so which way does the mapTo() work?

If this is the syntax:

myPoint = mapTo(my_QLabel_name, QPoint(0,0));

is the myPoint then going to hold the absolute coordinates (two positive numbers) of the upper left of the label named my_QLabel_name?
What function then separates myPoint (a QPoint) into two numbers : x and y?

jpn
17th November 2007, 07:42
What function then separates myPoint (a QPoint) into two numbers : x and y?
It's obvious once you take a look at QPoint docs, isn't it? Try to avoid asking every single question that comes to mind on the forums, please. You know, it doesn't make yourself look very good.. Docs are the number #1 resource after all! ;)

tommy
17th November 2007, 19:39
Thanks for your help, I figured it all out now