PDA

View Full Version : Label specific mousePressEvent



davethomaspilot
13th June 2012, 00:41
I have a dialog with two labels, side by side. Each has an image associated with it.

There is a RubberBand for each label. I want the rectangles associated with the rubber bands to be the same height, but the starting point to be independent in the two labels.

I created the dialog in Designer, and defined a class that inherits from it.

So, in this class, I can provide implementations of mousePressEvent, mouseMoveEvent, and mouseReleaseEvent for the dialog. This works, but I can't figure out how to provide a unique version for each of the two labels in the dialog.

I can "get there" (I think), by figuring out where each label is in the widget and associate the event with the appropriate label. But, it would probably be simpler to have a separate implementation of the event handlers for each label in the dialog. (And I see me needing to do this as I get better at Qt).

Can this be done?

Thanks,

Dave Thomas

ChrisW67
13th June 2012, 02:09
How do you intend to obtain two separate origins for the rubber bands? You would normally create a QRubberBand on mouse down, resize it on mouse move, and process/delete it on mouse up. With this arrangement clicking in one label to set the origin will not permit clicking in the label other to set the other origin without destroying the first rubber band.

davethomaspilot
13th June 2012, 12:15
The click will be over just one of the labels. So, the origin is redefined for that rubber band only. Whenever you click on a label, you set the origin for that label and it's used for subsequent clicks, if the mouse is not over it.

As the mouse moves, both rubber bands grow from their independent origins. So, the rubber bands will always have the same size, but different origins.

So, I'm writing code to associate a mouse click with one of the two labels/rubber bands. The one associated with the mouse click uses it's pos() as the origin, while the other uses the saved origin. Both rubber band as the mouse moves, and the geometry of both rubber bands is saved at mouseRelease.

This is for setting the AOI of two separate cameras. Each camera's AOI must have the same number of rows and columns, for reasons I won't go into here. But, the size of the AOI can be defined, and moved over the raw images, basically cropping them to a small size--the same size for both cameras.

The origin for the Rubber band will change in only one of the labels--the one that had the mouse click.

Probably many other ways to do the same thing--I'm open for suggestions. This is just the way I did it using mouseCallbacks and drawLines in OpenCV. It works, so I figured I do the same using Qt.

The click will be over just one of the labels. So, the origin is redefined for that rubber band only. Whenever you click on a label, you set the origin for that label and it's used for subsequent clicks, if the mouse is not over it.

As the mouse moves, both rubber bands grow from their independent origins. So, the rubber bands will always have the same size, but different origins.

So, I'm writing code to associate a mouse click with one of the two labels/rubber bands. The one associated with the mouse click uses it's pos() as the origin, while the other uses the saved origin. Both rubber band as the mouse moves, and the geometry of both rubber bands is saved at mouseRelease.

This is for setting the AOI of two separate cameras. Each camera's AOI must have the same number of rows and columns, for reasons I won't go into here. But, the size of the AOI can be defined, and moved over the raw images, basically cropping them to a small size--the same size for both cameras.

The origin for the Rubber band will change in only one of the labels--the one that had the mouse click.

Probably many other ways to do the same thing--I'm open for suggestions. This is just the way I did it using mouseCallbacks and drawLines in OpenCV. It works, so I figured I do the same using Qt.

The click will be over just one of the labels. So, the origin is redefined for that rubber band only. Whenever you click on a label, you set the origin for that label and it's used for subsequent clicks, if the mouse is not over it.

As the mouse moves, both rubber bands grow from their independent origins. So, the rubber bands will always have the same size, but different origins.

So, I'm writing code to associate a mouse click with one of the two labels/rubber bands. The one associated with the mouse click uses it's pos() as the origin, while the other uses the saved origin. Both rubber band as the mouse moves, and the geometry of both rubber bands is saved at mouseRelease.

This is for setting the AOI of two separate cameras. Each camera's AOI must have the same number of rows and columns, for reasons I won't go into here. But, the size of the AOI can be defined, and moved over the raw images, basically cropping them to a small size--the same size for both cameras.

The origin for the Rubber band will change in only one of the labels--the one that had the mouse click.

Probably many other ways to do the same thing--I'm open for suggestions. This is just the way I did it using mouseCallbacks and drawLines in OpenCV. It works, so I figured I do the same using Qt.

Added after 1 12 minutes:

I have it working, by associating the mouse event based on it's x position relative to the right-most label. Remember, the two labels are side by side horizontally.

If the pos().x() is greater than the label on the right side's origin, define the associated RubberBand's origin with that pos(). Else, associate with the RubberBand for the left side.

Note that the left label is named "right", and the right label is named "left". While confusing when reading this bit of code, it's intentional, since the camera images are of a "Left Lane" and "Right Lane". But, the view is such that the screen images will be reversed.

So, the test is for event->pos().x() relative to the left->pos().x(), not relative right->pos().x() as you might expect.

Here's the code.


AOIWindow::AOIWindow(QWidget *parent) : QDialog(parent)
{

rb_left = NULL;
rb_right = NULL;

setupUi(this);
left_origin = left->pos();
right_origin = right->pos();

}

void AOIWindow::mousePressEvent(QMouseEvent *event)
{
click_origin = event->pos();

// Determine which label the click was over and change the origin for the associated rubber band (only)
if (click_origin.x() > left->pos().x())
{
left_origin.setX(click_origin.x() - left->pos().x());
left_origin.setY(click_origin.y());
}
else
{
right_origin.setX( click_origin.x() - right->pos().x());
right_origin.setY(click_origin.y());
}

if (!rb_left)
rb_left = new QRubberBand(QRubberBand::Rectangle, left);
if (!rb_right)
rb_right = new QRubberBand(QRubberBand::Rectangle, right);

rb_left->setGeometry(QRect(left_origin, QSize()));
rb_left->show();
rb_right->setGeometry(QRect(right_origin, QSize()));
rb_right->show();
}
void AOIWindow::mouseMoveEvent(QMouseEvent *event)
{
QPoint mousePosition = event->pos();

// Use the y directly for the associated RubberBand.
// Use a rectangle with same size at saved origin for other one
if (mousePosition.x() > left->pos().x())
{
rb_left->setGeometry(QRect(left_origin, event->pos()).normalized());
rb_right->setGeometry(QRect(right_origin,rb_left->size()));
}
else
{
rb_right->setGeometry(QRect(right_origin, event->pos()).normalized());
rb_left->setGeometry(QRect(left_origin, rb_right->size()));
}
}

The header file:



class AOIWindow : public QDialog , public Ui::AOIWindow
{
Q_OBJECT

public:
AOIWindow(QWidget *parent=0);
QPoint click_origin;
QPoint left_origin;
QPoint right_origin;
QRubberBand *rb_left;
QRubberBand *rb_right;

void AOIWindow::mousePressEvent(QMouseEvent *event);
void AOIWindow::mouseReleaseEvent(QMouseEvent *event);
void AOIWindow::mouseMoveEvent(QMouseEvent *event);

private slots:


};

So, while this works, it might not be as robust as getting mouse events from each label object instead of the widget that contains them. And, I'm really trying to learn Qt as I go along, so I still want to know if it's possible to get mouse events for objects inside the widget instead of just the widget's mouse events-- and without changing files that will get clobbered by Designer.

Not a big deal if it's not possible--I'm just trying to follow "best practices" where appropriate. I'm a "three day old" newbie, so suggestions are welcome!

Thanks,

Dave Thomas

Added after 19 minutes:

Well, mostly working.

I still need to add offsets to adjust for where the origins of the label are vertically with respect to the widget's origin and the fact that the labels' x origns aren't exactly at 0 and widget_width/2.

Still, the code should illustrate what I'm trying to do and why it would be nice to get the mouse events associated with, and relative to, each label object instead of the containing widget.

Dave Thomas

davethomaspilot
13th June 2012, 18:22
Wow, Qt and QtDesigner Rock!

I was thinking I'd have to scale images to fit a window size, rescale when window size changed, etc. But NO! The images scale with the window! And, once I figured out how to do spacers in the layout, everything looks nice regardless of window size. NICE!

Glad I decided to start getting on board.

Dave Thomas