PDA

View Full Version : Question on QPainter setWindow use



impeteperry
27th July 2006, 03:52
I'm running Qt4. I want to use QPainter to display an engineer drawing where dimensions go from the lower left to upper right of the screen. Can I, and if so how do I, set the "windowRect" to accomplish this with "painter.setWindow( windowRect )" function.

In other words, say I have a line(0,0, 10000, 70000) which I want to display from the lower left to the upper right of the screen.

In Qt3, I adjusted my data to accomodate the screen, now I want the screen to accomodate my data.

Thanks

munna
27th July 2006, 04:33
I am not sure but I think scale(-1,-1) should do the job. Try it out.

impeteperry
27th July 2006, 05:05
I will try it out, thanks

Shortly after i posted the tread, I tried
x1 = (int)(-0.04 * factor * pX);
y1 = (int)(factor * pY);
x2 = (int)(factor * pX);
y2 = (int)(factor * pY * -1);
myWindowRect.setRect(x1, y1, x2, y2);and it seemed to work and it seemed logical. but I will have to spend time testing it.

Thanks

impeteperry
31st July 2006, 04:51
Hi, Except for the pen functions, the lines display correctly, but the text won't display
void edpForm::paintEvent(QPaintEvent * /*event*/)
{
double angle;
QPainter p( this );

if(paintLines.count () > 0)
{
QPen pen;
pen.setBrush(Qt::blue);

//pen.setWidth(1);

//QVector<qreal> dashes;
//qreal space = 4;
//dashes << 10 << space << 10 << space << 10 << space << 10;// << space << 10;
//dashes << 1 << space << 3 << space << 9 << space << 27; //<< space << 9;

//pen.setDashPattern(dashes);

p.setPen(pen);

p.setViewport(viewportRect);
p.setWindow(windowRect);
p.setClipRect(clippingRect);

for( n = 0; n < paintLines.count(); ++n )
{
k = paintLines[n];
temp = k.split( "," );
xs = temp[0].toInt( &ok );
ys = temp[1].toInt( &ok );
xe = temp[2].toInt( &ok );
ye = temp[3].toInt( &ok );
p.drawLine( xs, ys, xe, ye );
/// start of labeling.
xc = (xs + xe) / 2;
yc = (ys + ye) / 2;
if( xs == xe ) angle = pi/2;
else if( ys == ye) angle = 0;
else angle = atan((double)(ye-ys)/(xe-xs));
angle = (angle * 180)/pi;
p.save();
p.translate( xs, ys );
p.rotate( angle );
k = "s" + h.setNum(n + 1);
p.drawText(0, 0, k);
p.restore();
}
}
What am I missing?

thanks

impeteperry
31st July 2006, 15:51
In addition the following does not work
if(paintErase == true) { p.eraseRect(viewportRect); return; }I have also tried it with the "windowRect" and "clippingRect". Same thing, NOTHING!!. The paintEvent is triggered OK however

I can draw and clip lines, but that is all that works.

Is there a tutorial or example for displaying a "Drawing" where "0,0" is the lower left corner of the screen?

p.drawText(25,30,"This displays"). works before any of the "transforms" are implemented.

thanks

wysota
31st July 2006, 16:36
I am not sure but I think scale(-1,-1) should do the job. Try it out.

I'd say (1,-1) as you don't want to negate the horizontal axis. But this won't be enough. You will have all texts upside down.

impeteperry
31st July 2006, 19:07
You gave me that suggestion before, but I wasn't sure on how to use it and as a result got noware with it. If you could give me a clue on how to use it I would appreciate it.

I can't have distorted text. The lines are all in the first or fourth quadrant and the text has to be "above" the line at mid length and oriented to the slope of the line.

In Qt3, I did all the transforms, rotations etc. on the data before I painted.It. I was under the impression that Qt4 did that with the new painter functions. Either I am doing somthing wrong or Qt4 can't handle it.

When I got the lines to display properly, (except for pen functions) I thought I was home free.

Thanks.

impeteperry
31st July 2006, 20:15
I was able to use the (1,-1), but I can't have upside down text, however I will spend some time with it. anyway.

Thanks.

wysota
1st August 2006, 00:04
In Qt3, I did all the transforms, rotations etc. on the data before I painted.It. I was under the impression that Qt4 did that with the new painter functions.
To be honest, Qt3 had the same abilities in this aspect as Qt4. Only the way pens are handled was changed in Qt4.


Either I am doing somthing wrong or Qt4 can't handle it.

When I got the lines to display properly, (except for pen functions) I thought I was home free.

Thanks.

I'd say you should translate the coordinates by the height of the window. This way you'll get (0,0) in the bottom left corner of your screen with the y axis pointing down. Now if you use negative vertical coordinates, you'll get what you want (so draw at (10, -200) instead of (10, 200)). You could also scale the painter by -1 in vertical direction then, but your texts would still be upside down.

impeteperry
1st August 2006, 15:58
Thanks.
The program I am trying to write in Qt is a re-write of a DOS program where I transformed my data to fit the screen perameters, so I continued with that mind set and it worked.

With Qt4, there were enough changes in QPainter to make me dig deeper into painter. Without any simple CAD type tutorials, demos or examples where "0,0" is at the lower left, I thought the "setWindow" function would do in painter what I had done in my code.

You suggested translating the "y" coordinates which I think I had in the following code
pRatio = ((double)pX/pY); /// aspect ratio of drawing frame pixels

x1 = (int)(-0.04 * maxX); /// arbitrary 4% left border
y1 = (int)(1.05 * maxY); /// arbitrary 5% top border

xWidth = 1.08 * maxX; /// arbitrary 4% left and right borders
yHeight = 1.1 * maxY; /// arbitrary 5% top and bottom borders
dRatio = (xWidth/yHeight); /// aspect ratio of drawing dimentions
if( pRatio < dRatio ) /// modify the width or height to suit
yHeight *= pRatio;
else
xWidth *= pRatio;

myViewportRect.setRect(0, 0, pX, pY);
myWindowRect.setRect(x1, y1, (int)xWidth, -(int)yHeight);
myClippingRect.setRect(0, (int)maxY, (int)(maxX+1000.0), -(int)(maxY+1000.0));which draws the lines properly, including "clipping".
Now why don't the "pen" (except the "setBrush") and "text" functions work?
I can "drawText" on the screen ok before the "setWindow", but not after.

Note: All the data are integers. (1000* inches or 1000*millemeters) to avoid floating point comparison errors.

impeteperry
8th August 2006, 05:19
I'm back.
I have solved most of my problems. They were two fold. I needed another p.scale(1, -1) to right my font and had to make my font size a function of my "windowRect".

Right now, I can't find a clue on how to rotate retangles
if(paintColumns.count() > 0)
{
p.setViewport(viewportRect);
p.setWindow(windowRect);
p.setClipRect(windowRect);
for( n = 0; n < paintColumns.count(); ++n )
{
k = paintColumns[n];
temp = k.split( "," );
xs = temp[0].toInt(&ok);
ys = temp[1].toInt(&ok);
xe = temp[2].toInt(&ok);
ye = temp[3].toInt(&ok);
angle = temp[4].toDouble(&ok);
p.save();
p.translate( xs, ys );
//p.rotate( angle );
p.fillRect(-xe/2, -ye/2, xe, ye, Qt::black);
//p.rotate( angle );
p.restore();
}
}
Neither of the p.rotates do anything.
Any suggestions ?
Thanks

jacek
8th August 2006, 10:15
Neither of the p.rotates do anything.
What is the value of angle variable?

impeteperry
8th August 2006, 12:01
What is the value of angle variable?
They vary, but always in 1st or 4th quadrant and are in Radians

jacek
8th August 2006, 12:03
They vary, but always in 1st or 4th quadrant and are in Radians
Did you try degrees?

impeteperry
8th August 2006, 13:26
Did you try degrees?
No, but I did now and it worked
thanks