PDA

View Full Version : Drawing background while mouseMoving



Caolan O'Domhnaill
1st July 2016, 19:50
Hello,

I have an interesting problem I am trying to solve. I have a derived class of QGraphicsScene that draws a line in a rubber band fashion while the left mous button is depressed. What this means is that while I have the left button down it will show the line and I can draw it's position and length however I wish until I release the mouse button. At that time it will draw the object where it was when I left the button up.

What I want to do WHILE I am in rubberband mode, is let appear a cartesian plane axis whose origin is at the point I clicked the left mouse button to begin with. The cartesian plane axis' will continue to appear until I let the mouse button up. In addition, I wish to draw an arc between the x-axis and the line and display it's angle.

Please see attached picture for a view of what I want to see if I have the mouse button clicked and held down.

The problem I am having is that the cartesian axis seem to appear randomly and do not persist while I have the button clicked. I am defining it in the QGraphicsScene::drawbackground() overloaded function instead of the void QGraphicsScene::mouseMoveEvent(QGraphicsSceneMouse Event *mouseEvent) because of the access to the QPainter object.

Is there a better place to do this?

Cheers!
-Caolan

12020

anda_skoa
2nd July 2016, 10:09
Hmm.

What do you mean with "it appears randomly"?

Do you call update() in the methods that affect if/how the background is drawn?

Cheers,
_

Caolan O'Domhnaill
6th July 2016, 19:06
As I hold the mouse button down and move the vector around it's p1 anchor point, the grey image I am trying to draw sometimes shows up and when it dies, it is a partial draw.

No i am not calling update().



void PhysGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) {
Q_UNUSED(rect);

QMatrix mtx;
int w_2 = width() / 2;
int h_2 = height() / 2;

painter -> setPen(Qt::blue);
painter -> drawLine(0, h_2, width(), h_2); // X-Axis
painter -> drawLine(w_2, 0 , w_2, height()); // Y-Axis

mtx.translate(w_2, h_2);
mtx.scale(1, -1);

painter -> setMatrix(mtx);
painter -> setPen(Qt::NoPen);
painter -> setBrush(QBrush(Qt::blue, Qt::Dense4Pattern));
painter -> drawRect(-10, -10, 20, 20);

QLineF y_axis(-10, -10, -10, 10);
QLineF x_axis(-10, -10, 10, -10);
QPen pen;
QLineF angleLine1, angleLine2;

pen.setWidth(2);
pen.setColor(Qt::red);
painter -> setPen(pen);

setupAngleLine(angleLine1, x_axis.p2(), x_axis.p1(), 135.0);
setupAngleLine(angleLine2, x_axis.p2(), x_axis.p1(), -135.0);
painter -> drawLine(x_axis); // X-Axis
painter -> drawLine(angleLine1);
painter -> drawLine(angleLine2);

pen.setColor(Qt::green);
setupAngleLine(angleLine1, y_axis.p2(), y_axis.p1(), 45.0);
setupAngleLine(angleLine2, y_axis.p2(), y_axis.p1(), 135.0);
painter -> setPen(pen);
painter -> drawLine(y_axis); // Y-Axis
painter -> drawLine(angleLine1);
painter -> drawLine(angleLine2);

if (m_Mode == InsertLine && m_pLine)
drawAngledPlane(painter);
}

void PhysGraphicsScene::drawAngledPlane(QPainter *painter) {
QPointF lineMidPoint = findLineMidPoint(m_pLine ->line());
QRectF lineRect(m_pLine ->line().p1(), m_pLine ->line().p2());

// Draw the temporary cartesian axis' origin'ed at p1 of the line
QPen pen(Qt::lightGray);
pen.setStyle(Qt::DashDotDotLine);
pen.setWidth(2);
painter ->setPen(pen);
QLineF xAxis, yAxis;
xAxis.setAngle(90);
xAxis.setP1(m_pLine ->line().p1()); xAxis.setP2(QPointF(m_pLine ->line().dx(), 0));
xAxis.setLength(m_pLine ->line().dx());

yAxis.setAngle(0);
yAxis.setLength(m_pLine ->line().dy());

painter -> drawLine(xAxis); // x-axis
painter -> drawLine(yAxis); // y-axis


// Draw the arc from the false cartesian axis to the line
double angle = m_pLine ->line().angle();
}

anda_skoa
7th July 2016, 10:02
You need to call update() when the thing you want to draw changes.

As for the partial draw: maybe the coordinates are off? You are not using the rectangle that is passed to drawBackground. It is the part of the background that is currently exposed.

Alternatively you could create a custom graphics item or an combination of items for this and just locate it below the actual item.

Cheers,
_

Caolan O'Domhnaill
7th July 2016, 20:11
I implemented the update and one of the liens I draw do persist but it does not stay in position and moves about while I move the vector. I'll check out the solutions you present. BTW, I am basing this off of one of the samples used to show how to use QGraphicsScenes and it does not utilize a QGraphicsView except in the most offhanded way. Other samples I have seen do the opposite and fully flesh out the use of QGraphicsView but treats the QGraphicsScene as if it was not important. However the documentation i have been reading seems to think they're both equally important. Is there a sample Drawing app that shows how both are used as derived classes, in conjunction with QT Creator, to build out a rich, custom interface?

I ask because the application I have been trying to develop seems to need both and I want to make sure I don't spend more time going down yet another wrong road because I am ignorant of what a good QT drawing application looks like.

Cheers!
-Caolan.

anda_skoa
7th July 2016, 21:25
One usually only needs to derive from the scene for things like rendering a custom background, otherwise it is just populated with items.
Very similar for the view, which usually only needs to be subclassed if one needs custom event handling on the view level.

Cheers,
_

Caolan O'Domhnaill
8th July 2016, 01:04
Okay so should the painting of an object such as a QGraphicsLineItem, happen within the subclass of that item in a custom paint?

I am currently implementing a custom QGraphicsView, have a default QGraphicsScene, and each of the objects implement their own paint() but I am encountering some serious issues with drawing which is why I was looking at having it done in a custom QGraphicsScene instead because the sample I was mocking it up in seems to have made rendering the objects easier.

Should I stick with my initial implementation of having a custom QGraphicsView and where each QGraphicsItem does it's own custom paint()?

anda_skoa
8th July 2016, 12:01
Each item paints itself, even with the standard view.

The view asks the scene to render a specific area, the scene finds the items intersecting this area and asks them to paint themselves.

Cheers,
_

Caolan O'Domhnaill
8th July 2016, 20:12
Ooooooh I see now... Okay that makes sense. SO if I wanted to ensure that the entire screen is always rendered, I need to make sure the scene's rectangle is always set to the current size of the View as well....

Thank you!
-Caolan