⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plotter.cpp

📁 关于QT界面字动生成的介绍,包含了各种小例子,以及如何更好更快的学好QT!
💻 CPP
字号:
#include <qpainter.h>#include <qstyle.h>#include <qtoolbutton.h>#include <cmath>using namespace std;#include "plotter.h"Plotter::Plotter(QWidget *parent, const char *name, WFlags flags)    : QWidget(parent, name, flags | WNoAutoErase){    setBackgroundMode(PaletteDark);    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);    setFocusPolicy(StrongFocus);    rubberBandIsShown = false;    zoomInButton = new QToolButton(this);    zoomInButton->setIconSet(QPixmap::fromMimeSource("zoomin.png"));    zoomInButton->adjustSize();    connect(zoomInButton, SIGNAL(clicked()), this, SLOT(zoomIn()));    zoomOutButton = new QToolButton(this);    zoomOutButton->setIconSet(            QPixmap::fromMimeSource("zoomout.png"));    zoomOutButton->adjustSize();    connect(zoomOutButton, SIGNAL(clicked()), this, SLOT(zoomOut()));    setPlotSettings(PlotSettings());}void Plotter::setPlotSettings(const PlotSettings &settings){    zoomStack.resize(1);    zoomStack[0] = settings;    curZoom = 0;    zoomInButton->hide();    zoomOutButton->hide();    refreshPixmap();}void Plotter::zoomOut(){    if (curZoom > 0) {        --curZoom;        zoomOutButton->setEnabled(curZoom > 0);        zoomInButton->setEnabled(true);        zoomInButton->show();        refreshPixmap();    }}void Plotter::zoomIn(){    if (curZoom < (int)zoomStack.size() - 1) {        ++curZoom;        zoomInButton->setEnabled(                curZoom < (int)zoomStack.size() - 1);        zoomOutButton->setEnabled(true);        zoomOutButton->show();        refreshPixmap();    }}void Plotter::setCurveData(int id, const CurveData &data){    curveMap[id] = data;    refreshPixmap();}void Plotter::clearCurve(int id){    curveMap.erase(id);    refreshPixmap();}QSize Plotter::minimumSizeHint() const{    return QSize(4 * Margin, 4 * Margin);}QSize Plotter::sizeHint() const{    return QSize(8 * Margin, 6 * Margin);}void Plotter::paintEvent(QPaintEvent *event){    QMemArray<QRect> rects = event->region().rects();    for (int i = 0; i < (int)rects.size(); ++i)        bitBlt(this, rects[i].topLeft(), &pixmap, rects[i]);    QPainter painter(this);    if (rubberBandIsShown) {        painter.setPen(colorGroup().light());        painter.drawRect(rubberBandRect.normalize());    }    if (hasFocus()) {        style().drawPrimitive(QStyle::PE_FocusRect, &painter,                              rect(), colorGroup(),                              QStyle::Style_FocusAtBorder,                              colorGroup().dark());    }}void Plotter::resizeEvent(QResizeEvent *){    int x = width() - (zoomInButton->width()                       + zoomOutButton->width() + 10);    zoomInButton->move(x, 5);    zoomOutButton->move(x + zoomInButton->width() + 5, 5);    refreshPixmap();}void Plotter::mousePressEvent(QMouseEvent *event){    if (event->button() == LeftButton) {        rubberBandIsShown = true;        rubberBandRect.setTopLeft(event->pos());        rubberBandRect.setBottomRight(event->pos());        updateRubberBandRegion();        setCursor(crossCursor);    }}void Plotter::mouseMoveEvent(QMouseEvent *event){    if (event->state() & LeftButton) {        updateRubberBandRegion();        rubberBandRect.setBottomRight(event->pos());        updateRubberBandRegion();    }}void Plotter::mouseReleaseEvent(QMouseEvent *event){    if (event->button() == LeftButton) {        rubberBandIsShown = false;        updateRubberBandRegion();        unsetCursor();        QRect rect = rubberBandRect.normalize();        if (rect.width() < 4 || rect.height() < 4)            return;        rect.moveBy(-Margin, -Margin);        PlotSettings prevSettings = zoomStack[curZoom];        PlotSettings settings;        double dx = prevSettings.spanX() / (width() - 2 * Margin);        double dy = prevSettings.spanY() / (height() - 2 * Margin);        settings.minX = prevSettings.minX + dx * rect.left();        settings.maxX = prevSettings.minX + dx * rect.right();        settings.minY = prevSettings.maxY - dy * rect.bottom();        settings.maxY = prevSettings.maxY - dy * rect.top();        settings.adjust();        zoomStack.resize(curZoom + 1);        zoomStack.push_back(settings);        zoomIn();    }}void Plotter::keyPressEvent(QKeyEvent *event){    switch (event->key()) {    case Key_Plus:        zoomIn();        break;    case Key_Minus:        zoomOut();        break;    case Key_Left:        zoomStack[curZoom].scroll(-1, 0);        refreshPixmap();        break;    case Key_Right:        zoomStack[curZoom].scroll(+1, 0);        refreshPixmap();        break;    case Key_Down:        zoomStack[curZoom].scroll(0, -1);        refreshPixmap();        break;    case Key_Up:        zoomStack[curZoom].scroll(0, +1);        refreshPixmap();        break;    default:        QWidget::keyPressEvent(event);    }}void Plotter::wheelEvent(QWheelEvent *event){    int numDegrees = event->delta() / 8;    int numTicks = numDegrees / 15;    if (event->orientation() == Horizontal)        zoomStack[curZoom].scroll(numTicks, 0);    else        zoomStack[curZoom].scroll(0, numTicks);    refreshPixmap();}void Plotter::updateRubberBandRegion(){    QRect rect = rubberBandRect.normalize();    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());}void Plotter::refreshPixmap(){    pixmap.resize(size());    pixmap.fill(this, 0, 0);    QPainter painter(&pixmap, this);    drawGrid(&painter);    drawCurves(&painter);    update();}void Plotter::drawGrid(QPainter *painter){    QRect rect(Margin, Margin,               width() - 2 * Margin, height() - 2 * Margin);    PlotSettings settings = zoomStack[curZoom];    QPen quiteDark = colorGroup().dark().light();    QPen light = colorGroup().light();    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,                          AlignHCenter | 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,                          AlignRight | AlignVCenter,                          QString::number(label));    }    painter->drawRect(rect);}void Plotter::drawCurves(QPainter *painter){    static const QColor colorForIds[6] = {        red, green, blue, cyan, magenta, yellow    };    PlotSettings settings = zoomStack[curZoom];    QRect rect(Margin, Margin,               width() - 2 * Margin, height() - 2 * Margin);    painter->setClipRect(rect.x() + 1, rect.y() + 1,                         rect.width() - 2, rect.height() - 2);    map<int, CurveData>::const_iterator it = curveMap.begin();    while (it != curveMap.end()) {        int id = (*it).first;        const CurveData &data = (*it).second;        int numPoints = 0;        int maxPoints = data.size() / 2;        QPointArray points(maxPoints);        for (int i = 0; i < maxPoints; ++i) {            double dx = data[2 * i] - settings.minX;            double dy = data[2 * i + 1] - settings.minY;            double x = rect.left() + (dx * (rect.width() - 1)                                         / settings.spanX());            double y = rect.bottom() - (dy * (rect.height() - 1)                                           / settings.spanY());            if (fabs(x) < 32768 && fabs(y) < 32768) {                points[numPoints] = QPoint((int)x, (int)y);                ++numPoints;            }        }        points.truncate(numPoints);        painter->setPen(colorForIds[(uint)id % 6]);        painter->drawPolyline(points);        ++it;    }}PlotSettings::PlotSettings(){    minX = 0.0;    maxX = 10.0;    numXTicks = 5;    minY = 0.0;    maxY = 10.0;    numYTicks = 5;}void PlotSettings::scroll(int dx, int dy){    double stepX = spanX() / numXTicks;    minX += dx * stepX;    maxX += dx * stepX;    double stepY = spanY() / numYTicks;    minY += dy * stepY;    maxY += dy * stepY;}void PlotSettings::adjust(){    adjustAxis(minX, maxX, numXTicks);    adjustAxis(minY, maxY, numYTicks);}void PlotSettings::adjustAxis(double &min, double &max,                              int &numTicks){    const int MinTicks = 4;    double grossStep = (max - min) / MinTicks;    double step = pow(10, floor(log10(grossStep)));    if (5 * step < grossStep)        step *= 5;    else if (2 * step < grossStep)        step *= 2;    numTicks = (int)(ceil(max / step) - floor(min / step));    min = floor(min / step) * step;    max = ceil(max / step) * step;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -