PDA

View Full Version : QPicture does not play right



derick
18th February 2006, 18:45
Hi,

I have the following code:


void xpPageWidget::setPage(QPicture* image)
{
m_Pixmap.fill(Qt::white);

QPainter painter(&m_Pixmap);

qDebug(ds_filepos+QString("MPageDisplay::setPage(): image =%1x%2").arg(image->width()).arg(image->height()));
qDebug(ds_filepos+QString("MPageDisplay::setPage(): m_Pixmap=%1x%2").arg(m_Pixmap.width()).arg(m_Pixmap.height()));
qDebug(ds_filepos+QString("MPageDisplay::setPage(): this =%1x%2").arg(width()).arg(height()));

image->play(&painter);
//painter.drawPicture(0,0,*image);

}


And the output:


.\gui\xpPageWidget.cpp(29): MPageDisplay::setPage(): image =732x327
.\gui\xpPageWidget.cpp(30): MPageDisplay::setPage(): m_Pixmap=794x1123
.\gui\xpPageWidget.cpp(31): MPageDisplay::setPage(): this =796x1125


image get's painted to by code like this:


void ReportBase::drawFrame(QPainter *p,QRectF aRect)
{
if(!p) return;
QPen aPen = m_BorderColor;
...
p->setPen(aPen);
p->drawLine(aRect.topLeft(),aRect.topRight());
...
}
bool ReportBase::draw(QPainter *p)
{
drawFrame(p);
if(m_ReportEngine->m_ShowNames)
{
p->setPen(Qt::lightGray);
p->setFont(getFont());
p->drawText(*m_Rect,Qt::AlignCenter,QString("%1:%2").arg(className()).arg(name()));
}
return true;
}



The painting worked fine in Qt3 (1st Block line 11: image->play(&painter) ) but in Qt4 the QPicture painting is too big and goes off my pageWidget. The only way to get it within the required 796x1125 (A4 Paper) area on pageWidget (see output) is to scale it :( ... I still have to work out the correct ratios for QPainter::scale ( qreal sx, qreal sy ) to make it fit snuggly but that seems like something that should work without scaling.

Thus, is there some scaling/transformations when the paint commands are played back to a QPainter? What's the pixel size of an A4 Paper... would that be a potential issue?

jacek
18th February 2006, 19:02
What's the pixel size of an A4 Paper... would that be a potential issue?
It is an issue. Paper does not have pixels, but every device (like monitors or printers) has different pixel size depending on current resolution (and hardware). You can obtain the all the information you need using QPaintDevice class.

derick
18th February 2006, 19:14
I've calculated that the with it draws 'too wide' on is 200pixels.

Then my output is:
.\gui\MPagedisplay.cpp(29): MPageDisplay::setPage(): image =532x327
.\gui\MPagedisplay.cpp(30): MPageDisplay::setPage(): m_Pixmap=794x1123
.\gui\MPagedisplay.cpp(31): MPageDisplay::setPage(): this =796x1125

And it draws correctly on the page.

I would expect a 794x1123 QPicture to play back properly on a 796x1125 QPixmap using a QPainter

jacek
18th February 2006, 19:34
I would expect a 794x1123 QPicture to play back properly on a 796x1125 QPixmap using a QPainter


int QPaintDevice::width () const
Returns the width of the paint device in default coordinate system units (e.g. pixels for QPixmap and QWidget).
See also widthMM().
This means QPicture::width() and QPixmap::width() might return size in different units (pixels from QPicture and from QPixmap might have different sizes). Try widthMM() method.


QPicture always runs in 72 dpi, and scales the painter to match differences in resolution depending on the window system.

derick
18th February 2006, 22:58
Thanks for the tip. The display dpi was higher.. thus here is the fixed code:


void MPageDisplay::setPage(QPicture* image)
{
//A white page
m_Pixmap.fill(Qt::white);
// Convert from painting/printing resoltion to on screen
qreal sx = (qreal)image->logicalDpiX()/(qreal)m_Pixmap.logicalDpiX();
qreal sy = (qreal)image->logicalDpiY()/(qreal)m_Pixmap.logicalDpiY();

QPainter painter(&m_Pixmap);
painter.scale(sx,sy);
image->play(&painter);
}

derick
19th February 2006, 01:46
Sniff Sniff :( ... because QPicture can only record paint events at 72dpi and printers go from 300 - 600dpi my printouts are not good.

I scaled the image on painting but it comes out a bit fuzzy...

Does anybody have some ideas on how to cache paints ... QPixmap seems like a waste of memory since I would like to view the pages onscreen.

Painting an oversized image to get the quality better perhaps?