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倍左右的時間,(為了更好地效率,可以在繪制之前,對點的坐标進行先排序,但是這一部分的資源占用還是存在,隻是被移到其他部分去了)
測試結果截圖放在下面。
如有問題,勿噴。隻是工作上遇到的問題,進行優化後的總結和分享。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwFe5EDWwh2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zMyMDOykjM2EDMzUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
上述方法還有一個優化的地方,就是,qSort()函數,其實我隻需要獲得最大值最小值即可,不需要進行排序。測試後,确實可以節省很多時間