PDA

View Full Version : Get QRect of a widget using mouseevent



arpspatel
7th March 2010, 15:45
Hi,

I have a grid layout with two widgets displaying input and output image, i want to be able to draw a rectangle, like the one used in paint, only for output image with mouse button clicked and get the x,y,height,width (QRect) of the part selected when mouse button released.

I read the document for mousereleaseevent and from that i can get the position of the mouse, but what i want is the rectangle selection, how do i draw this rectangle and return the Qrect value??

I have no idea how to start with mouseevents or graphics items or such, please could be give me a example or a approach i can use to program this.

Thanks

toutarrive
7th March 2010, 16:22
If I understand your thinking, you want to draw a selection rectangle when the mouse is over your output image.

First you have to get the position of the mouse using QMouseEvent::pos () or QMouseEvent::globalPos () ( read the doc).

Once you have the position of the mouse cursor, relative to the widget that received the even ( using those functions), you can easily retrieve the rect geometry and draw whatever you want (throught the paintEvent of the concerned widget).

toutarrive
7th March 2010, 16:31
Have a look at QWidget::mousePressEvent(), QWidget::mouseMoveEvent() or QWidget::mouseReleaseEvent.
Depending on when you want your custom drawing triggered.

arpspatel
7th March 2010, 17:00
Ok, I understand pos and globalPos from the doc..

imageView->pos() //Gives me the widget position
event->globalPos() // gives me the mouse position

if mouse is within widget, then enable selection rectangle... on mouse release return get the mouse pos() and calculate Qrect.

this is very straight forward. I still dont know how to enable selection rectangle.. I am using QLabel right now, but can switch to QGraphicsView if required..

toutarrive
7th March 2010, 17:29
QGraphicsView is a bit too heavy just to draw a rectangle.
Create a flag (bool isOverImage) to indicate that the cursor is within the right widget (in QWidget::mousePressEvent(), QWidget::mouseMoveEvent() or QWidget::mouseReleaseEvent depending on the expected behaviour) and call update().
In the paint method of that widget draw your selected rectangle, using this flag .


if (isOverImage) drawRect(selectionrect.x(), selectionrect.y(), selectionrect.width(), selectionrect.height() );

arpspatel
7th March 2010, 20:19
void theGui::mousePressEvent(QMouseEvent *event){
if (event->button() == Qt::LeftButton) {
if((event->pos().x() < bx && event->pos().x() > tx) &&
(event->pos().y() < by && event->pos().y() > ty)){
startPoint = event->pos();
drawing = true;
}
}
}

void theGui::mouseReleaseEvent(QMouseEvent *event){
if (event->button() == Qt::LeftButton && drawing) {
if((event->pos().x() < bx && event->pos().x() > tx) &&
(event->pos().y() < by && event->pos().y() > ty)){
endPoint = event->pos();
drawing = false;
}
}
saveSelection(QRect(startPoint,endPoint));
}

void theGui::mouseMoveEvent(QMouseEvent *event){
if ((event->buttons() & Qt::LeftButton) && drawing){
drawRect(startPoint,event->pos());
}
}

void theGui::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QRect dirtyRect = event->rect();
painter.drawImage(dirtyRect, image, dirtyRect);
}

void theGui::drawRect(QPoint _s, QPoint, _e){
QPainter painter(&image);
painter.setPen(QPen(myPenColor, myPenWidth, Qt::SolidLine, Qt::RoundCap,
Qt::RoundJoin));
painter.drawRect(QRect(_s,_e));
modified = true;

int rad = (myPenWidth / 2) + 2;
update(QRect(_s,_e).normalized()
.adjusted(-rad, -rad, +rad, +rad));
}



Here is my code, how i wrote it..
but i am getting a lot of squares and I dont want to paint a rectangle, i just want a selection rectangle which will disappear after selection is done..

Thanks

aamer4yu
8th March 2010, 06:10
Wont QRubberBand be of some use to you :rolleyes:

toutarrive
8th March 2010, 07:23
You got the idea,

Call update() in void theGui::mouseMoveEvent(QMouseEvent *event), not in theGui::drawRect(QPoint _s, QPoint, _e) (rename it drawRectSelection(QPoint _s, QPoint, _e) to avoid confusion QPainter::DrawRect(etc...)) .
No need to calll drawRect(startPoint,event->pos()) in void theGui::mouseMoveEvent(QMouseEvent *event);
Use your flag in theGui::paintEvent(QPaintEvent *event) and do the painting of the selection rectangle in this function only.


Or you can use QRubberBand as suggested...

arpspatel
8th March 2010, 21:57
void theGui::mousePressEvent(QMouseEvent* event) {
if (!rubberband)
rubberband = new QRubberBand(QRubberBand::Rectangle, this);
startPoint = event->pos();
rubberband->setGeometry(QRect(startPoint,QSize()));
rubberband->show();
rubberBandActive = true;
}


void theGui::mouseMoveEvent(QMouseEvent* event) {
if(rubberBandActive){
rubberband->setGeometry(QRect(startPoint,event->pos()).normalized());
}
}

void theGui::mouseReleaseEvent(QMouseEvent* event) {
if(rubberBandActive){
endPoint = event->pos();
rubberBandActive = false;
rubberband->hide();
}
}


Thanks Guys... I tried the QRubberBand and it worked very well and on first try.. there is also an example in qt doc. I didnt even know there was a class like QRubberBand, so I have posted the code here just in case some one needs it.....

aamer4yu
9th March 2010, 04:19
I tried the QRubberBand and it worked very well and on first try.. there is also an example in qt doc. I didnt even know there was a class like QRubberBand
Thats cuteness of Cute(Qt) ! You think, and its probable its there ! :)