借用官方的这张图分析。
主要关注QCPLayer 和QCPLayout,几乎所有的元素都是放置同一张布局中的,布局是核心要素,不同的元素可能不在同一张layer ,即不在同一层,不在同一层的元素的区别就是上层的元素会挡住下层的元素,主要是因为不同层的刷新顺序有区别,具体看源码。
emit beforeReplot();
# if QT_VERSION < QT_VERSION_CHECK(4, 8, 0)
QTime replotTimer;
replotTimer.start();
# else
QElapsedTimer replotTimer;
replotTimer.start();
# endif
updateLayout();//更新布局
// draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers:
setupPaintBuffers();//准备绘画缓冲区
foreach (QCPLayer *layer, mLayers)
layer->drawToPaintBuffer();
foreach (QSharedPointer<QCPAbstractPaintBuffer> buffer, mPaintBuffers)
buffer->setInvalidated(false);
if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh)
{
repaint();
}
else
{
update();
}
# if QT_VERSION < QT_VERSION_CHECK(4, 8, 0)
mReplotTime = replotTimer.elapsed();
# else
mReplotTime = replotTimer.nsecsElapsed()*1e-6;
# endif
if (!qFuzzyIsNull(mReplotTimeAverage))
mReplotTimeAverage = mReplotTimeAverage*0.9 + mReplotTime*0.1; // exponential moving average with a time constant of 10 last replots
else
mReplotTimeAverage = mReplotTime; // no previous replots to average with, so initialize with replot time
emit afterReplot();
主要看replot 函数中两个信号中间做的操作。
这里进行一层一层的画图。
这个函数是获取画笔,然后画图。
继续查看draw函数,这个对每一层的cplayerable 进行画图,cplayerabale是一个父类,根据c++ 的多态特性,通过父类指针调用纯虚函数(这里指draw),可以执行子类的draw 函数。
又根据此图可以看出,所有控件都是继承与QCPlayerable,因此都会调用子类的draw函数进行绘画。