Профессионал
    
Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84
Спасибо сказали: 70 раз(а)
Репутация: 17

|
Цитата(Don @ 23.4.2008, 22:52)  Плиз, выложите кто-нить ПОЛНЫЙ небольшой пример, где на форме будет что-нить рисоваться (линия, круг, квадрат, что угодно). А то я трох разобрался с помощью чего что рисуется, а вот как всё это вывести не догоняю. Вот пример из книжки Бланшета и Саммерфилда. В примере происходит отрисовка графиков. Используется двойная буферизация, что на данный момент уже необязательно делать! #ifndef PLOTTER_H #define PLOTTER_H
#include <QMap> #include <QPixmap> #include <QVector> #include <QWidget>
class QToolButton; class PlotSettings;
class Plotter : public QWidget { Q_OBJECT
public: Plotter(QWidget *parent = 0);
void setPlotSettings(const PlotSettings &settings); void setCurveData(int id, const QVector<QPointF> &data); void clearCurve(int id); QSize minimumSizeHint() const; QSize sizeHint() const;
public slots: void zoomIn(); void zoomOut();
protected: void paintEvent(QPaintEvent *event); void resizeEvent(QResizeEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void keyPressEvent(QKeyEvent *event); void wheelEvent(QWheelEvent *event);
private: void updateRubberBandRegion(); void refreshPixmap(); void drawGrid(QPainter *painter); void drawCurves(QPainter *painter);
enum { Margin = 50 };
QToolButton *zoomInButton; QToolButton *zoomOutButton; QMap<int, QVector<QPointF> > curveMap; QVector<PlotSettings> zoomStack; int curZoom; bool rubberBandIsShown; QRect rubberBandRect; QPixmap pixmap; };
class PlotSettings { public: PlotSettings();
void scroll(int dx, int dy); void adjust(); double spanX() const { return maxX - minX; } double spanY() const { return maxY - minY; }
double minX; double maxX; int numXTicks; double minY; double maxY; int numYTicks;
private: static void adjustAxis(double &min, double &max, int &numTicks); };
#endif
#include <QtGui> #include <cmath>
#include "plotter.h"
using namespace std;
Plotter::Plotter(QWidget *parent) : QWidget(parent) { setBackgroundRole(QPalette::Dark); setAutoFillBackground(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setFocusPolicy(Qt::StrongFocus); rubberBandIsShown = false;
zoomInButton = new QToolButton(this); zoomInButton->setIcon(QIcon(":/images/zoomin.png")); zoomInButton->adjustSize(); connect(zoomInButton, SIGNAL(clicked()), this, SLOT(zoomIn()));
zoomOutButton = new QToolButton(this); zoomOutButton->setIcon(QIcon(":/images/zoomout.png")); zoomOutButton->adjustSize(); connect(zoomOutButton, SIGNAL(clicked()), this, SLOT(zoomOut()));
setPlotSettings(PlotSettings()); }
void Plotter::setPlotSettings(const PlotSettings &settings) { zoomStack.clear(); zoomStack.append(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 < zoomStack.count() - 1) { ++curZoom; zoomInButton->setEnabled(curZoom < zoomStack.count() - 1); zoomOutButton->setEnabled(true); zoomOutButton->show(); refreshPixmap(); } }
void Plotter::setCurveData(int id, const QVector<QPointF> &data) { curveMap[id] = data; refreshPixmap(); }
void Plotter::clearCurve(int id) { curveMap.remove(id); refreshPixmap(); }
QSize Plotter::minimumSizeHint() const { return QSize(6 * Margin, 4 * Margin); }
QSize Plotter::sizeHint() const { return QSize(12 * Margin, 8 * Margin); }
void Plotter::paintEvent(QPaintEvent * /* event */) { QStylePainter painter(this); painter.drawPixmap(0, 0, pixmap);
if (rubberBandIsShown) { painter.setPen(palette().light().color()); painter.drawRect(rubberBandRect.normalized() .adjusted(0, 0, -1, -1)); }
if (hasFocus()) { QStyleOptionFocusRect option; option.initFrom(this); option.backgroundColor = palette().dark().color(); painter.drawPrimitive(QStyle::PE_FrameFocusRect, option); } }
void Plotter::resizeEvent(QResizeEvent * /* event */) { 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) { QRect rect(Margin, Margin, width() - 2 * Margin, height() - 2 * Margin);
if (event->button() == Qt::LeftButton) { if (rect.contains(event->pos())) { rubberBandIsShown = true; rubberBandRect.setTopLeft(event->pos()); rubberBandRect.setBottomRight(event->pos()); updateRubberBandRegion(); setCursor(Qt::CrossCursor); } } }
void Plotter::mouseMoveEvent(QMouseEvent *event) { if (rubberBandIsShown) { updateRubberBandRegion(); rubberBandRect.setBottomRight(event->pos()); updateRubberBandRegion(); } }
void Plotter::mouseReleaseEvent(QMouseEvent *event) { if ((event->button() == Qt::LeftButton) && rubberBandIsShown) { rubberBandIsShown = false; updateRubberBandRegion(); unsetCursor();
QRect rect = rubberBandRect.normalized(); if (rect.width() < 4 || rect.height() < 4) return; rect.translate(-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.append(settings); zoomIn(); } }
void Plotter::keyPressEvent(QKeyEvent *event) { switch (event->key()) { case Qt::Key_Plus: zoomIn(); break; case Qt::Key_Minus: zoomOut(); break; case Qt::Key_Left: zoomStack[curZoom].scroll(-1, 0); refreshPixmap(); break; case Qt::Key_Right: zoomStack[curZoom].scroll(+1, 0); refreshPixmap(); break; case Qt::Key_Down: zoomStack[curZoom].scroll(0, -1); refreshPixmap(); break; case Qt::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() == Qt::Horizontal) { zoomStack[curZoom].scroll(numTicks, 0); } else { zoomStack[curZoom].scroll(0, numTicks); } refreshPixmap(); }
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()); }
void Plotter::refreshPixmap() { pixmap = QPixmap(size()); pixmap.fill(this, 0, 0);
QPainter painter(&pixmap); painter.initFrom(this); drawGrid(&painter); drawCurves(&painter); update(); }
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)); }
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); } }
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.0, floor(log10(grossStep)));
if (5 * step < grossStep) { step *= 5; } else if (2 * step < grossStep) { step *= 2; }
numTicks = int(ceil(max / step) - floor(min / step)); if (numTicks < MinTicks) numTicks = MinTicks; min = floor(min / step) * step; max = ceil(max / step) * step; }
#include <QtGui>
#include "plotter.h"
void readFlightCurves(Plotter *plotter, const QString &fileName) { QVector<QPointF> data[6]; double factX = 0.0013; double factY[6] = { 0.0008, 0.1, 0.2, 0.2, 0.1, 0.8 }; double offsY[6] = { +500, -55, +309, +308, 0, 0 }; int pos[6] = { 3, 6, 7, 8, 9, 10 }; QFile file(fileName); double offsX = 0.0;
if (file.open(QIODevice::ReadOnly)) { QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); QStringList coords = line.split(' ', QString::SkipEmptyParts); if (coords.count() >= 6) { double x = factX * coords[0].toDouble(); if (data[0].isEmpty()) offsX = x; for (int i = 0; i < 6; ++i) { double y = coords[pos[i]].toDouble(); data[i].append(QPointF(x - offsX, factY[i] * (y - offsY[i]))); } } } }
plotter->setCurveData(0, data[0]); plotter->setCurveData(1, data[1]); plotter->setCurveData(2, data[2]); plotter->setCurveData(3, data[3]); plotter->setCurveData(4, data[4]); plotter->setCurveData(5, data[5]); }
int main(int argc, char *argv[]) { QApplication app(argc, argv); Plotter plotter; plotter.setWindowTitle(QObject::tr("Plotter")); readFlightCurves(&plotter, "in1.txt"); plotter.show(); return app.exec(); }
plotter.proTEMPLATE = app HEADERS = plotter.h SOURCES = main.cpp \ plotter.cpp RESOURCES = plotter.qrc
Причина редактирования: теперь можно включать подсветку [code=cpp]
|