(转)5.4 双缓冲技术(Double Buffering)-4

xiaoxiao2021-02-28  131

(转)5.4 双缓冲技术(Double Buffering)-4

标签: qtalignment网格plotjava 2422人阅读 评论(0) 收藏 举报 本文章已收录于: 分类: Qt(31) 作者同类文章 X 以下是私有函数的实现: 

void Plotter::updateRubberBandRegion()

{

    QRect rect = rubberBandRect.normalized();

    update(rect.left(), rect.top(), rect.width(), 1);     update(rect.left(), rect.top(), 1, rect.height());     update(rect.left(), rect.bottom(), rect.width(), 1);     update(rect.right(), rect.top(), 1, rect.height()); } 函数updateRubberBand()在mousePressEvent(),mouseMoveEvent()和mouseReleaseEvent()中被调用,用来删除或者重新绘制橡皮线。函数中调用了四次update(),用四个绘制事件完成由橡皮线(两条垂直和水平的线)组成的四个小矩形的绘制。Qt也提供了一个类 QRubberBand用来绘制橡皮线,但是控件自己提供的绘制函数会更好 void Plotter::refreshPixmap() {     pixmap = QPixmap(size());     pixmap.fill(this, 0, 0);     QPainter painter(&pixmap);     painter.initFrom(this);     drawGrid(&painter);     drawCurves(&painter);     update(); } 函数refreshPixmap()把plot绘制到图片上,并且更新显示。首先我们把图片的大小调整为和当前控件大小相同,然后用控件的背景颜色填充整个图片。这个颜色是当前调色版的“dark”部分,因为在Plotter构造函数中调用 setBackgroundRole() 。如果背景用的刷子是非实心的(solid brush,刷子的样式,只有颜色,没有花纹的那种最简单的), QPixmap::fill()需要知道控件中刷子的偏移量,以便图片对齐刷子模式。这里图片对应整个控件,因此偏移位置为(0,0)。 接下来我们创建了一个QPainter对象来绘制图片, QPainter::initFrom()设置绘制图片所需画笔,背景和字体,参数this表示这些设置和Plotter控件的相应设置是一致的。然后我们调用drawGrid(),drawCurves()绘制网格和曲线。最后,update()函数安排整个控件的绘制事件,在painteEvent()函数中把图片拷贝到控件上。 void Plotter::drawGrid(QPainter *painter) {    QRect rect(Margin, Margin,                width() - 2 * Margin, height() - 2 * Margin);     if (!rect.isValid())         return;     PlotSettings settings = zoomStack[curZoom];     QPen quiteDark = palette().dark().color().light();     QPen light = palette().light().color();     for (int i = 0; i <= settings.numXTicks; ++i) {         int x = rect.left() + (i * (rect.width() - 1)                                  / settings.numXTicks);         double label = settings.minX + (i * settings.spanX()                                           / settings.numXTicks);         painter->setPen(quiteDark);         painter->drawLine(x, rect.top(), x, rect.bottom());         painter->setPen(light);         painter->drawLine(x, rect.bottom(), x, rect.bottom() + 5);         painter->drawText(x - 50, rect.bottom() + 5, 100, 15,                           Qt::AlignHCenter | Qt::AlignTop,                           QString::number(label));     }     for (int j = 0; j <= settings.numYTicks; ++j) {         int y = rect.bottom() - (j * (rect.height() - 1)                                    / settings.numYTicks);         double label = settings.minY + (j * settings.spanY()                                           / settings.numYTicks);         painter->setPen(quiteDark);         painter->drawLine(rect.left(), y, rect.right(), y);         painter->setPen(light);         painter->drawLine(rect.left() - 5, y, rect.left(), y);         painter->drawText(rect.left() - Margin, y - 10, Margin - 5, 20,                           Qt::AlignRight | Qt::AlignVCenter,                           QString::number(label));     }     painter->drawRect(rect.adjusted(0, 0, -1, -1)); } 函数drawGrid()在坐标轴和曲线的下面绘制网格。这个区域由一个矩形确定,如果控件太小,则不绘制立即返回。第一个循环绘制网格的垂直线,及沿x坐标轴的刻度。第二个循环绘制网格的水平线,及沿y坐标轴的刻度。最后,沿边界绘制一个矩形。drawText()绘制数字,对应两个坐标轴上刻度的标记。 函数painter->drawText()语法如下: painter->drawText(x, y, width, height, alignment, text); 其中(x,y,width,height)所确定的矩形,alignment确定文字在矩形中的位置。 void Plotter::drawCurves(QPainter *painter) {     static const QColor colorForIds[6] = {         Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow     };     PlotSettings settings = zoomStack[curZoom];     QRect rect(Margin, Margin,                width() - 2 * Margin, height() - 2 * Margin);     if (!rect.isValid())         return;     painter->setClipRect(rect.adjusted(+1, +1, -1, -1));     QMapIterator<int, QVector<QPointF> > i(curveMap);     while (i.hasNext()) {         i.next();         int id = i.key();         const QVector<QPointF> &data = i.value();         QPolygonF polyline(data.count());         for (int j = 0; j < data.count(); ++j) {             double dx = data[j].x() - settings.minX;             double dy = data[j].y() - settings.minY;             double x = rect.left() + (dx * (rect.width() - 1)                                          / settings.spanX());             double y = rect.bottom() - (dy * (rect.height() - 1)                                            / settings.spanY());             polyline[j] = QPointF(x, y);         }         painter->setPen(colorForIds[uint(id) % 6]);         painter->drawPolyline(polyline);     } } 函数drawCurves()在网格的上层绘制曲线。调用了 QPainter::setClipRect()函数设置QPainter的剪切区域为包含曲线的矩形区域(不包括四周的间隙和图片的外框)。QPainter会忽略这个区域外的象素。 然后我们使用Java风格的迭代器,遍历所有的曲线,对每一条曲线,遍历它所有的 QPointF点。函数key()得到曲线的id,value()函数得到曲线的QVector<QPointF>类型的数据。内层循环把每个QPointF记录的plotter坐标转换为控件坐标,把结果保存在 polyline变量中。 转换坐标后,我们设置画笔的颜色(使用函数前面预定义的颜色),调用drawPolyline()绘制曲线,经过所有的曲线上的点。 顶 1 踩 0     上一篇(转)5.4 双缓冲技术(Double Buffering)-3 下一篇(转)5.4 双缓冲技术(Double Buffering)-5

我的同类文章

Qt(31) http://blog.csdn.net •(转)利用Qt的qmake创建vc工程2009-08-28阅读1936 •(转)QT中画图方法的不同 2009-06-18阅读3727 •(转)5.4 双缓冲技术(Double Buffering)-32008-05-20阅读1901 •(转)双缓冲技术12008-05-20阅读1960 •(转)5.2从QWidget派生(Subclassing QWidget)2008-05-12阅读1249 •(转)QT事件机制2009-06-20阅读1630 •(转)5.4 双缓冲技术(Double Buffering)-52008-05-20阅读931 •(转)5.4 双缓冲技术(Double Buffering)-22008-05-20阅读1212 •(转) 5.3把自定义控件集成到Qt Designer中(Integrating Custom Widgets with Qt Designer)2008-05-12阅读4155 •(转)5.1自定义Qt控件(Customizing Qt Widgets)2008-05-12阅读1795 更多文章
转载请注明原文地址: https://www.6miu.com/read-26160.html

最新回复(0)