Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QQuickPaintedItem



  • Hello all !!!

    I have a qml file on which I want to display the spectrum and the input for the player comes from qml.
    I am trying to re-implement spectrum analyzer example (<Qt Dir>/examples/multimedia/spectrum) using
    QQuickPaintedItem. I have re-implemented Paint instead of paintEvent and made following changes :

    But bars are not changing. Can some one help me to fix this.

    @
    void SpectrographQML::paint(QPainter *painter)
    {
    //m_bars.resize(10);
    const int numBars = 10;
    painter->fillRect(contentsBoundingRect(), Qt::black);

    QColor barColor(51, 204, 102);
    QColor clipColor(255, 255, 0);
    
    // Draw the outline
    const QColor gridColor = barColor.darker();
    QPen gridPen(gridColor);
    painter->setPen(gridPen);
     painter->drawLine(contentsBoundingRect().topLeft(), contentsBoundingRect().topRight());
     painter->drawLine(contentsBoundingRect().topRight(), contentsBoundingRect().bottomRight());
     painter->drawLine(contentsBoundingRect().bottomRight(), contentsBoundingRect().bottomLeft());
     painter->drawLine(contentsBoundingRect().bottomLeft(), contentsBoundingRect().topLeft());
    
    QVector<qreal> dashes;
    dashes << 2 << 2;
    gridPen.setDashPattern(dashes);
    painter->setPen(gridPen);
    
    // Draw vertical lines between bars
    if (numBars) {
        const int numHorizontalSections = 10;
        QLine line1(contentsBoundingRect().toAlignedRect().topLeft(), contentsBoundingRect().toAlignedRect().bottomLeft());
        for (int i=1; i<numHorizontalSections; ++i) {
            line1.translate(contentsBoundingRect().width()/numBars, 0);
            painter->drawLine(line1);
        }
    }
    
    // Draw horizontal lines
    const int numVerticalSections = 10;
    QLineF line(contentsBoundingRect().topLeft(), contentsBoundingRect().topRight());
    for (int i=1; i<numVerticalSections; ++i) {
        line.translate(0, contentsBoundingRect().height()/numBars);
        painter->drawLine(line);
    }
        // Calculate width of bars and gaps
        const int widgetWidth = boundingRect().width();
        const int barPlusGapWidth = widgetWidth / numBars;
        const int barWidth = 0.8 * barPlusGapWidth;
        const int gapWidth = barPlusGapWidth - barWidth;
        const int paddingWidth = widgetWidth - numBars * (barWidth + gapWidth);
        const int leftPaddingWidth = (paddingWidth + gapWidth) / 2;
        const int barHeight = boundingRect().height() - 2 * gapWidth;
    
        for (int i=0; i<numBars; ++i) {
            qreal value = m_bars[i].value; // value is always zero, not updating ...
            Q_ASSERT(value >= 0.0 && value <= 1.0);
            QRectF bar = contentsBoundingRect();
            bar.setLeft(boundingRect().left() + leftPaddingWidth + (i * (gapWidth + barWidth)));
            bar.setWidth(barWidth);
            bar.setTop(boundingRect().top() + gapWidth + (1.0 - value) * barHeight);
            bar.setBottom(boundingRect().bottom() - gapWidth);
    
            QColor color = barColor;
            if (m_bars[i].clipped)
                color = clipColor;
           painter->fillRect(bar, color);
        }
    

    }
    @

    Thanks & Regards,
    Narayanan K


  • Moderators

    Hi,

    paint() needs to called when ever your data changes unlike paintevent().
    Use a QTimer to update it and make sure the data is changing or else it will just paint the same thing.


Log in to reply