天天看點

Qt繪圖效率的測試(QGraphicsItem QGraphicsPointItem)

Qt在繪制point的時候,一般都直接調用addPoint()函數,但是在point數量達到一定程度的時候,會發生很嚴重的卡頓現象,比如,繪制10w個point,繪制100w個point(point的無序的)

以10w個point為測試,

QTime time;
    time.start();
    for(int i=;i<;i++){
        QGraphicsLineItem* item = new QGraphicsLineItem(+i*0.,+i*0.,+i*0.,+i*0.);
        mScene->addItem(item);
//        QGraphicsLineItem* item = mScene->addLine(+i*0.,+i*0.,+i*0.,+i*0.);
    }
    qDebug()<<"time elapsed: "<<time.elapsed();
           

上面的代碼運作後,顯示耗時達到15s,這是直接使用Qt本身的addPoint()方法,之是以需要如此長的時間,主要是因為,每一個點在繪制的時候,都會new一個painter去繪制,繪制結束後再去吧painter釋放掉,導緻的。

下面是自己封裝的point控件中的paint()和boundingRect()函數的重寫

QRectF PointItem::boundingRect() const
{
    if(pointNumber == single){
        return QRectF(m_x,m_y,,);
    }else if(pointNumber == multiple){
        //測試rect
        QList<qreal> lstX,lstY;
        lstX = m_lstX;lstY = m_lstY;
        qSort(lstX.begin(), lstX.end());
        qSort(lstY.begin(), lstY.end());

        return QRectF(lstX[],lstY[],lstX[lstX.count()-],lstY[lstY.count()-]);
    }
}

void PointItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(widget)
    Q_UNUSED(option)

    int cnt = this->scene()->views().count();
    for (int i =;i<cnt;i++)
    {
        QGraphicsView *view = this->scene()->views().at(i);
        QMatrix matrix = view->matrix();
        qreal scale = matrix.m11();
        qreal width = penWidth/scale;

        painter->setPen(QPen(QBrush(penColor),width));

        if(pointNumber == single){
            painter->drawPoint(m_x,m_y);
        }else if(pointNumber == multiple){
            for(int j=;j<m_lstX.count();j++){
                painter->drawPoint(m_lstX[j],m_lstY[j]);
            }
        }
    }
}
           

當需要繪制多個點的時候,直接在paint()函數中使用同一個painter進行繪制,經過測試這種方法繪制耗時大概在150ms左右。這裡要說明的一點是,在boundingRect()函數中,我對點的坐标進行排序,當我不排序的時候,整個繪制耗時大概在20ms左右,必須要對點進行排序,因為點是無序的,我們需要對控件的有效繪制區域進行設定,排序所占用的時間,是不可以避免的。但是就算如此,也比官方的繪制優化了100倍左右的時間,(為了更好地效率,可以在繪制之前,對點的坐标進行先排序,但是這一部分的資源占用還是存在,隻是被移到其他部分去了)

測試結果截圖放在下面。

如有問題,勿噴。隻是工作上遇到的問題,進行優化後的總結和分享。

Qt繪圖效率的測試(QGraphicsItem QGraphicsPointItem)

上述方法還有一個優化的地方,就是,qSort()函數,其實我隻需要獲得最大值最小值即可,不需要進行排序。測試後,确實可以節省很多時間

繼續閱讀