QCustomPlot Discussion and Comments

Blurry fonts and graph using QCP on Android/IOSReturn to overview

Hey guys,

First of all really spectacular library with great functions. I'm using QCP in an qml application, where I inherit the QCP-Widget inside a QQuickItem which works really great. Performance of real time plots are really okay. The application has to be multi platform. On Windows and low dpi android tablets, the lines and fonts of QCP are really sharp and look good. On Android and IOS the fonts and the lines are looking blurry. I experimented with different approaches, that were already mentioned in the forum.
Here is a screenshot of the android verion on a 4K display (HTC U11): https://imgur.com/a/rALAeon

Does anyone has a tip regarding this behaviour? I'm not really familiar with coding in Qts painting API

It seems like the system isn't communicating the correct device pixel ratio.
What's the output of

qDebug() << [QCP's parent widget]->devicePixelRatio();
qDebug() << customPlot->bufferDevicePixelRatio();


You can try decativating the label caching:

customPlot->setPlottinhHint(QCP::phCacheLabels, false)

But note that 4K on an embedded android is pretty steep. Make sure your system has the power to render complex graphics at such resolution – most apps render a few boxes as buttons and a few lines of text, which is doable in 4K. But complex plots with a million data points and channel fill, not so much ;).

The output of your 2 debug lines brings following

qApp->devicePixelRatio:  4
customPlot->bufferDevicePixelRatio:  4

and current plot looks like this: https://imgur.com/a/22ZPk3S

i have modified also plottingHints, but seems like the workarounds are not taking effect. Pixel Ratio is correct. My Rendering type is currently opengl. Perhaps Software rendering could do the trick?

I have experimented a little bit and was able to get better looking fonts in my point of view. It is looking better:

https://imgur.com/a/rAXVxAb

My font definition is looking this way:

    QFont font = qApp->font();  // start out with MainWindow's font..
    font.setPointSize(11); // and make a bit smaller for legend
    font.setStyleHint(QFont::AnyStyle, QFont::OpenGLCompatible);
    font.setStyleStrategy(QFont::PreferQuality);

and in the main.cpp i have added following config:

    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);

I think it could be better, cause on windows without High-DPI fonts are clear and sharp. I don't know where i have to dig for this issue.

Regards Michael

Anyone has an idea to this issue? I think this would help many people using QCP on mobile devices or on 4k-monitors with High-DPI.

I'm having this issue with iPhones as well

Ok, I fixed this on iOS for my use case at least, maybe this will help someone else.

I was using the width and height of my QQuickPaintedItem named CureImageItem to determine the resolution of the plot image I was painting inside it.

I figured out that on my iPhone 5S the width I was getting from my CureImageItem was only 320, when the real width of the 5S screen is 640. Some high DPI scaling or something? not sure...

At this point I tried both

QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_DisableHighDpiScaling);

but it had no effect...

Then I figured out if I take the width & height I'm given and multiply it by the device pixel ratio I get the true unscaled resolution.

and this worked for me in QML:

         CureImageItem {
                id: cureImageItem
                height: parent.height*Screen.devicePixelRatio
                width: parent.width*Screen.devicePixelRatio
                anchors.centerIn: parent
                scale: 1/Screen.devicePixelRatio
            }

I also had to multiply the labelSize and PenWidth by the device pixel ratio.

The weird thing is my plot was always sharp and looking good on Android, I only had to do the above for iOS...

When I modify my QML-Item derived from QCP in this way, i get a blank screen, so I assume my width and height are not correct for the QQuickPaintedItem.
I have my QQuickPaintedItem within a Page-Component and I am setting implicitWidth and Height fo the QCP-Item to have a responsive Behaviour of the graph.
So do you think modifying the width and heights could also be done in C++ - part of the QQuickPaintedItem?

So after digging deeper into this, i figured out, that the issue is related to a wrong size of the pixmap used for offscreen drawing the plot in paint-method of QQuickPaintedItem.

The pixmap I have used is created with the size of the boundingRect from the QQuickPaintedItem. This size is already downscaled by QML. So you have to adjust the size of the pixmap by multiplying the size with the devicePixelRatio and then you have to set the devicePixelRatio also in the pixmap.
Finally i have a sharp and good looking plot in my Android 4k Phone.

For further usage here my code:

void CustomPlotItem::paint( QPainter* painter )
{
    if (m_CustomPlot)
    {
        this->setRenderTarget(QQuickPaintedItem::FramebufferObject);

        qreal devicePixelRatio = m_CustomPlot->devicePixelRatioF();
        QPixmap    picture(static_cast<int>(boundingRect().size().width()*devicePixelRatio),
                           static_cast<int>(boundingRect().size().height()*devicePixelRatio));
        picture.setDevicePixelRatio(devicePixelRatio);

        QCPPainter qcpPainter( &picture );

        m_CustomPlot->toPainter( &qcpPainter );
        painter->setRenderHints(QPainter::SmoothPixmapTransform |
            QPainter::Antialiasing);


        painter->drawPixmap( QPoint(), picture );
    }
}