PDA

View Full Version : Passing a QPixmap to other functions?



DrAgonmoray
31st July 2012, 22:27
Hi. I'm very new to C++ and Qt.

In my constructor, I have a QPixmap called "overlay" and I set a label's pixmap to overlay so that it displays on the screen.

I want to allow the user to draw a rectangle on the screen by clicking, dragging, and releasing. I did this exact thing in Java yesterday, so I understand how those mechanics work.

My problem is: I don't know how to pass the overlay QPixmap to my events so that they can update the rectangle. Here's is what is the relevant snippet of what currently have:


QPoint start;
QPoint end;

MyWindow::MyWindow() {
//Up here i define the layout, label, etc. that all works correctly
QPixmap overlay; //I define this correctly, but chose not to include the code because it is irrelevant
myLabel->setPixmap(overlay);
}

void MyWindow::mousePressEvent(QMouseEvent *event) {
start = event->globalPos();
updateRectangle();
}

void MyWindow::mouseMoveEvent(QMouseEvent *event) {
end = event->globalPos();
updateRectangle();
}

void MyWindow::mouseReleaseEvent(QMouseEvent *event) {
end = event->globalPos();
updateRectangle();
}

void updateRectangle() { //This section does not work. I need to get the QPixmap "overlay" to here so I can update it.
QPainter p(&overlay);
p.setPen(Qt::blue);
p.drawRect(start.x(), start.y(), end.x() - start.x(), end.y() - start.y());
p.end();
}

As you can see, I really don't know what I'm doing. Right now I get "overlay: undeclared identifier" and if I put overlay into the global scope, I get an error saying I can't make a painter before an app.

Help would be greatly appreciated.

mvuori
31st July 2012, 22:52
The thing that gives you visibility to "overlay" in the event handlers is to make it a member variable of your MyWindow class. After that all functions of MyWindow will see it. As it is now, it is local of and only visible to the constructor of MyWindow.

That means that you also need to make updateRectangle() a member of MyWindow, that is, MyWindow::updateRectangle().

DrAgonmoray
31st July 2012, 23:07
The thing that gives you visibility to "overlay" in the event handlers is to make it a member variable of your MyWindow class. After that all functions of MyWindow will see it. As it is now, it is local of and only visible to the constructor of MyWindow.

That means that you also need to make updateRectangle() a member of MyWindow, that is, MyWindow::updateRectangle().

Wow, that is very good to know. Thank you. :)

It now runs without erroring, however it doesn't work and I'm not sure why. The overlay appears on screen as expected, but when I click and drag, nothing at all happens. I drew a rectangle on screen earlier, but right here it doesn't work.
Here's my current code (it has a few changes):

void MyWindow::mousePressEvent(QMouseEvent *event) {
start = event->globalPos();
end = event->globalPos();
updateRectangle();
}

void MyWindow::mouseMoveEvent(QMouseEvent *event) {
end = event->globalPos();
updateRectangle();
}

void MyWindow::mouseReleaseEvent(QMouseEvent *event) {
end = event->globalPos();
updateRectangle();
}

void MyWindow::updateRectangle() {
QPainter p(&overlay);
p.setPen(Qt::blue);
p.drawRect(start.x(), start.y(), end.x() - start.x(), end.y() - start.y());
p.end();
//myLabel->setPixmap(overlay);
}
The overlay shows on screen but nothing happens when I click and drag. If I uncomment that line at the bottom, the overlay shows up but when I click the screens turns grey (as if the label is empty)

ChrisW67
31st July 2012, 23:59
Before you go too much further, are you trying to do what QRubberBand can do for you?

DrAgonmoray
1st August 2012, 00:47
Before you go too much further, are you trying to do what QRubberBand can do for you?I think I am.

Thanks, I'll try it out.

Added after 38 minutes:


Before you go too much further, are you trying to do what QRubberBand can do for you?
Hi Chris,

I got the rubber band working successfully, however I would like to change the appearance of it in two ways:

Make the border thicker
Change the background of the selected area


Unfortunately I don't think this is possible, so I have to go back to what I was doing. Could I get some help there, please?

ChrisW67
1st August 2012, 01:15
Is the aim of the exercise for the user to draw a single filled rectangle with a thick border by click and drag? You can use the QRubberBand to give the user an idea what size the box will be as they move the mouse then draw the final rectangle and hide the rubber band when the mouse button is released.

You will need to think about how the rectangle will be drawn (painted). Painting should occur in the widget's paintEvent(). Have a look at the Scribble Example which draws in an off-screen QImage and then paints that.

DrAgonmoray
1st August 2012, 01:23
Is the aim of the exercise for the user to draw a single filled rectangle with a thick border by click and drag? You can use the QRubberBand to give the user an idea what size the box will be as they move the mouse then draw the final rectangle and hide the rubber band when the mouse button is released.

You will need to think about how the rectangle will be drawn (painted). Painting should occur in the widget's paintEvent(). Have a look at the Scribble Example which draws in an off-screen QImage and then paints that.
The aim IS to simply select the area, however there is a specific look I am trying to achieve.
When the program starts, it 'freezes' the screen and blurs it (takes a screenshot, blurs it, displays it in the label that takes up the entire screen). Then the user should select an area of the screen to capture. Inside the captured area, the screen should be crystal clear (i.e. not blurry).

I did this in Java yesterday, but due to Java's limitations (i couldn't get native keyboard input), I set out to do this using C++. Here is the exact effect that i am trying to achieve:
8078