Qt 4.8 (4.8.6) has a QPainter::drawPixmapFragments() overloaded function with 5 arguments:
void drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount,
const QPixmap &pixmap, PixmapFragmentHints hints = 0);
Qt 5 (5.4.1) has no such function, it has only one (same as in Qt 4.8) with 4 arguments:
void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount,
const QPixmap &pixmap, PixmapFragmentHints hints = 0);
I've searched in wiki.qt.io
, here on stackoverflow and several other places, but there is no answer how to port it from Qt 4.8 to Qt 5.
How to do it?
UPD I've taken realization from Qt 4.8.6 source (qpainter.cpp
) and simply transform it to take pointer to QPainter as first parameter:
namespace oldqt
{
void drawPixmapFragments(QPainter *painter, const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount,
const QPixmap &pixmap, QPainter::PixmapFragmentHints hints)
{
// Q_D(QPainter);
if (/* !d->engine || */ pixmap.isNull())
return;
#ifndef QT_NO_DEBUG
if (sourceRects) {
for (int i = 0; i < fragmentCount; ++i) {
QRectF sourceRect = sourceRects[i];
if (!(QRectF(pixmap.rect()).contains(sourceRect)))
qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle");
}
}
#endif
// if (d->engine->isExtended()) {
// d->extended->drawPixmapFragments(targetRects, sourceRects, fragmentCount, pixmap, hints);
// }
// else {
if (sourceRects) {
for (int i = 0; i < fragmentCount; ++i)
painter->drawPixmap(targetRects[i], pixmap, sourceRects[i]);
}
else {
QRectF sourceRect = pixmap.rect();
for (int i = 0; i < fragmentCount; ++i)
painter->drawPixmap(targetRects[i], pixmap, sourceRect);
}
// }
}
}
But I commented out some lines. Q_D(QPainter)
somehow defines d
from d_func
, how can I take it from *painter
? Or it is not possible?
May be there is another solution?
UPD2 Example of my legacy code:
class ButtonSelector:public QGraphicsObject
// ...
void ButtonSelector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
//painter->drawPixmap(m_backGnd.rect(), m_backGnd);
QRectF rectSrc = QRectF(m_backGnd.rect());
QRectF rectTrg = boundingRect();
painter->drawPixmapFragments(&rectTrg,&rectSrc,1,m_backGnd, QPainter::OpaqueHint);
// I've change it to this call:
// oldqt::drawPixmapFragments(painter, &rectTrg, &rectSrc, 1, m_backGnd, QPainter::OpaqueHint);
// where oldqt::drawPixmapFragments is function from above
// ... some other code unrelated to the question
}
In principle, it works OK. What is incorrect in the code?
Solution Based on the answer by @amartel:
void drawPixmapFragments(QPainter *painter, const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount,
const QPixmap &pixmap, QPainter::PixmapFragmentHints hints)
{
for (int i = 0; i < fragmentCount; ++i) {
QRectF sourceRect = (sourceRects) ? sourceRects[i] : pixmap.rect();
QPainter::PixmapFragment pixmapFragment =
QPainter::PixmapFragment::create(
targetRects[i].center(),
sourceRects[i],
targetRects[i].width() / sourceRect.width(),
targetRects[i].height() / sourceRect.height()
);
painter->drawPixmapFragments(&pixmapFragment, 1, pixmap, hints);
}
}
According to http://qt.apidoc.info/5.1.1/qtgui/qpainter-pixmapfragment.html in Qt5 your code should look like this:
void ButtonSelector::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
//painter->drawPixmap(m_backGnd.rect(), m_backGnd);
QRectF rectSrc = QRectF(m_backGnd.rect());
QRectF rectTrg = boundingRect();
QPainter::PixmapFragment fragment = QPainter::PixmapFragment::create(rectTrg.center(), rectSrc, rectTrg.width() / rectSrc.width(), rectTrg.height() / rectSrc.height());
painter->drawPixmapFragments(&fragment,1,m_backGnd, QPainter::OpaqueHint);
// I've change it to this call:
// oldqt::drawPixmapFragments(painter, &rectTrg, &rectSrc, 1, m_backGnd, QPainter::OpaqueHint);
// where oldqt::drawPixmapFragments is function from above
// ... some other code unrelated to the question
}