Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ничего не получается с рисованием на виджете
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Система рисования. Печать
Тёма
Как вообще рисовать в Qt?
ViGOur
Для того, чтобы рисовать, тебе понадобится переопределить void QWidget::paintEvent ( QPaintEvent * event ) [virtual protected]
Есть статья в которой описывается как рисовать и как избавиться от мерцания при рисовании: Быстро и без мерцаний

Думаю, там достаточно хорошо все описано.
Don
Плиз, выложите кто-нить ПОЛНЫЙ небольшой пример, где на форме будет что-нить рисоваться (линия, круг, квадрат, что угодно). А то я трох разобрался с помощью чего что рисуется, а вот как всё это вывести не догоняю.
AD
Цитата(Don @ 23.4.2008, 22:52) *
Плиз, выложите кто-нить ПОЛНЫЙ небольшой пример, где на форме будет что-нить рисоваться (линия, круг, квадрат, что угодно). А то я трох разобрался с помощью чего что рисуется, а вот как всё это вывести не догоняю.

Вот пример из книжки Бланшета и Саммерфилда. В примере происходит отрисовка графиков. Используется двойная буферизация, что на данный момент уже необязательно делать!

plotter.h
#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


plotter.cpp

#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;
}



main.h

#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.pro
TEMPLATE      = app
HEADERS       = plotter.h
SOURCES       = main.cpp \
                plotter.cpp
RESOURCES     = plotter.qrc
Andrew Selivanov
Цитата(AD @ 23.4.2008, 23:21) *
Цитата(Don @ 23.4.2008, 22:52) *
Плиз, выложите кто-нить ПОЛНЫЙ небольшой пример, где на форме будет что-нить рисоваться (линия, круг, квадрат, что угодно). А то я трох разобрался с помощью чего что рисуется, а вот как всё это вывести не догоняю.

Вот пример из книжки Бланшета и Саммерфилда. В примере происходит отрисовка графиков. Используется двойная буферизация, что на данный момент уже необязательно делать!
<... skipped ...>

<Andrew stepped in>
Я тут немного вмешаюсь, кажется у нас теперь работает syntax highlight для тега code, я сегодня пробовал :)
иии to Admin -> блин видимо назревает необходимость Wiki...
<Andrew stepped out>
Don
Да уж, маленький примерчик. :)
Какие именно функции отвечают за отображение нарисованных элементов? Как именно переопределяется paintEvent?
И может кто чиркануть простой пример, где на форме просто рисуется линия, на простеньком примере проще разобраться, а потом уже рисовать всякие там графики.

P.S. Наверное это и глупые вопросы, но помогите плиз, очень надо. Я в Qt недавно.
Litkevich Yuriy
Из книжки Макса Шлее:
#include <QtGui>

// ======================================================================
class PainterPathWidget : public QWidget {
protected:
    virtual void paintEvent(QPaintEvent*)
    {
        QPainterPath path;
        QPointF      pt1(width(), height() / 2);
        QPointF      pt2(width() / 2, -height());
        QPointF      pt3(width() / 2, 2 * height());
        QPointF      pt4(0, height() / 2);
        path.moveTo(pt1);
        path.cubicTo(pt2, pt3, pt4);

        QRect rect(width() / 4, height() / 4, width() / 2, height() / 2);
        path.addRect(rect);
        path.addEllipse(rect);

        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(Qt::blue, 6));
        painter.drawPath(path);    
    }

public:
    PainterPathWidget(QWidget* pwgt = 0) : QWidget(pwgt)
    {
    }
};

// ----------------------------------------------------------------------
int main(int argc, char** argv)
{
    QApplication app(argc, argv);

    PainterPathWidget wgt;

    wgt.resize(200, 200);
    wgt.show();

    return app.exec();
}
AD
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::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));
}


painter -> drawLine(100, 200, 200, 400)
- рисование линии
размером (100, 200)!
painter -> drawRect(QRect(10, 10, 40, 40))
- рисование прямоугольника

void Plotter::drawGrid(QPainter *painter)
{
        // тело функции
}
- а вот и переопределение функции paintEvent, которая является виртуальной.

Не понял, чем пример-то плох? :)
Don
Спасибо! Теперь понял.
У меня ещё один вопрос:
Как нарисованные элементы прицепить к созданному виджету? Т.е. я создаю окно (QWidget wndow; .... window.show()), которому задаю нужные свойства и размещаю на нём кнопки, метки и т.д. А как к нему добавить рисунок?
Litkevich Yuriy
ну размести рисунок на одном виджете, и воткни его в тот на котором кнопки.
Вот Layout (компоновщик) может сам как надо отрегулировать:
int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); // Для функций перевода tr()
    
  QWidget            window;
  QPushButton        btn(QObject::tr("Ку-ку"));
  PainterPathWidget wgt;
  QVBoxLayout        *mainLayout = new QVBoxLayout;


    //wgt.resize(200, 200);
    wgt.setMinimumSize(200, 200);
    mainLayout->addWidget(&btn);
    mainLayout->addWidget(&wgt);
    window.setLayout(mainLayout);


    //wgt.show();
    window.show();

    return app.exec();
}
Don
Понял спасибо!
А почеиу текст нужно выводить именно через tr()? Почему нельзя просто
QPushButton btn("Text");?
Litkevich Yuriy
Я пишу в кодировке UTF-8, но строковые переменные использую в виндовозовской кодировке, иниче возникают проблемы с БД, которые я еще не победил, чтобы Qt'я могло использовать разные кодировки в разных местах, я делаю так:
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("Windows-1251"));// 
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); // Для функций перевода tr()

тогда константы строковые помещаю в tr(), она в UTF-8, остальное Windows-1251

Если текст программы в виндовозовской кодировке, то вторую строку можешь не писать, и tr() не использовать, но лучше использовать, чтобы небыло проблем в будущем, в частности с горячими кнопками при разных раскладках клавиатуры.
Don
Как нарисовать дугу? Пытался через drawArc(), не получается - выводится точка.
Litkevich Yuriy
а как ты это делал? приведи код
Don
Цитата(Litkevich Yuriy @ 24.4.2008, 20:28) *
а как ты это делал? приведи код


Ну вот вся прога:

class Life : public QWidget 
{
protected:
    virtual void paintEvent(QPaintEvent*)
    {
        QPainter paint(this);
        paint.drawArc(40,40,50,50,25,25);  <======================
                        
                       //пытался ещё через Безье, но никогда так не делал и не знаю, что обозначают все передаваемые значения
                       QPainterPath path;                          
        path.moveTo( 80,320);        
        path.cubicTo(200,400,320,400,480,320);
        paint.drawPath(path);
                
    }
public:
    Life(QWidget* pwgt = 0) : QWidget(pwgt)
    {
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc,argv);
    QWidget window;
    Life a;
    QHBoxLayout lay;
    lay.addWidget(&a);
    window.setLayout(&lay);
    window.show();
    return app.exec();
}
Litkevich Yuriy
Смотри для начала рабочий пример в каталоге %QTDIR%\examples\painting\basicdrawing, там есть дуги, а тут его описание Basic Drawing Example

руководство по функции:
Цитата
void QPainter::drawArc ( const QRectF & rectangle, int startAngle, int spanAngle )
Draws the arc defined by the given rectangle, startAngle and spanAngle.
The startAngle and spanAngle must be specified in 1/16th of a degree, i.e. a full circle equals 5760 (16 * 360). Positive values for the angles mean counter-clockwise while negative values mean the clockwise direction. Zero degrees is at the 3 o'clock position.

Пример, от туда
 QRectF rectangle(10.0, 20.0, 80.0, 60.0);
int startAngle = 30 * 16;
int spanAngle = 120 * 16;

QPainter painter(this);
painter.drawArc(rectangle, startAngle, spanAngle);

сравни цифры startAngle и spanAngle, со своими
остальное должно работать,
Модификация примера Макса Шлее:
virtual void paintEvent(QPaintEvent*)
{
    int startAngle = 30 * 16;    //    480
    int spanAngle = 120 * 16;    //    
    
    QPainter painter(this);
    painter.drawArc(40, 40, 50, 50, startAngle, spanAngle);
}
Don
Цитата(Litkevich Yuriy @ 24.4.2008, 20:39) *
Смотри для начала рабочий пример в каталоге %QTDIR%\examples\painting\basicdrawing, там есть дуги, а тут его описание Basic Drawing Example


Вот тот код который рисует дугу из примера:
QRect rect(10, 20, 80, 60) // я так понял задаётся прямоугольник в который вписывается эллипс
int startAngle = 30 * 16;
int arcLength = 120 * 16;
painter.drawArc(rect, startAngle, arcLength);

Ввёл в свою прогу, нарисовалась такая же дуга. Но как работать с этими углами? Шаманю со множителями, получаются куски эллипса, причём каждый раз кординально разные. Мне нужно нарисовать просто улыбочку.
Litkevich Yuriy
смотри мой предыдущий пост.

startAngle и spanAngle должны быть определены в ед. 1/16-ой градуса, т.е. полная окружность равна 5760 (16 * 360). Положительное значение углов означает направление против часовой стрелки, а отрицательное - по часовой. Нуль градусов находится в позиции 3 часа.
Don
Смотрите, все что рисуется на форме должно находится в функции paintEvent(). Допустим рисуются какие-то объекты по предворительным рсчётам, которые проводятся в другой функции. И если вызвать в этой фукции функцию repaint(), то происходит перерисовка с учётом расчётов. Получется функция repaint() вызывает функцию paintEvent(). Так?
Litkevich Yuriy
выходит так
guest13
вопрос такой....
имеется такой код
Раскрывающийся текст
#include <QtGui>

class PainterPathWidget : public QWidget {
protected:
    virtual void paintEvent(QPaintEvent*)
    {
        QPainterPath path;
        QPointF      pt1(width(), height() / 2);      
        QPointF      pt2(width() / 2, -height());      
        QPointF      pt3(width() / 2, 2 * height());
        QPointF      pt4(0, height() / 2);
        path.moveTo(pt1);
        path.cubicTo(pt2, pt3, pt4);
        
        QRect rect(width() / 4, height() / 4, width() / 2, height() / 2);        
        path.addRect(rect);        
        path.addEllipse(rect);
        
        QPainter painter(this);        
        painter.setRenderHint(QPainter::Antialiasing, true);        
        painter.setPen(QPen(Qt::blue, 6));        
        painter.drawPath(path);    
    }
public:
    PainterPathWidget(QWidget* pwgt = 0) : QWidget(pwgt)
    {
        
    }
};

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);    

    PainterPathWidget wgt;    
    
    QWidget window;

    QPushButton *q1=new QPushButton("exit");
    
    QVBoxLayout *lay1=new QVBoxLayout;
    wgt.setMinimumSize(200,200);
    lay1->addWidget(q1);
    lay1->addWidget(&wgt);
    window.setLayout(lay1);
        
    QObject::connect(q1,SIGNAL(clicked()),&app,SLOT(quit()));    

    window.show();
    return app.exec();
}

нормально компилится запускается, но при закрытии выдает следующую ошибку
Нажмите для просмотра прикрепленного файла
что можете сказать по этому поводу?
kwisp
#include <QtGui>

class PainterPathWidget : public QWidget {
protected:
    virtual void paintEvent(QPaintEvent* e)
    {
        QPainterPath path;
        QPointF      pt1(width(), height() / 2);      
        QPointF      pt2(width() / 2, -height());      
        QPointF      pt3(width() / 2, 2 * height());
        QPointF      pt4(0, height() / 2);
        path.moveTo(pt1);
        path.cubicTo(pt2, pt3, pt4);
        
        QRect rect(width() / 4, height() / 4, width() / 2, height() / 2);        
        path.addRect(rect);        
        path.addEllipse(rect);
        
        QPainter painter(this);        
        painter.setRenderHint(QPainter::Antialiasing, true);        
        painter.setPen(QPen(Qt::blue, 6));        
        painter.drawPath(path);    
    }
public:
    PainterPathWidget(QWidget* pwgt = 0) : QWidget(pwgt)
    {
        
    }
};
int main(int argc, char* argv[])
{
    QApplication app(argc, argv);    
    QWidget window;
    PainterPathWidget wgt;    
    QPushButton q1("exit");
    QVBoxLayout lay1(&window);
    wgt.setMinimumSize(200,200);
    lay1.addWidget(&q1);
    lay1.addWidget(&wgt);

    QObject::connect(&q1,SIGNAL(clicked()),&app,SLOT(quit()));    

    window.show();
    return app.exec();
}


найди 10 отличий:)
все работает.
почитай если интересно про иерахию классов и осовобождение памяти в Qt.
TiiL
Здравствуйте, обьясните мне не догоняющему, где в приложении описанном в этой теме на первой странице задаютцася координаты графика.

и возможно ли сделать оси координат ЛОгарифмическими?


ЗЫ: было бы хорошо еслиб ткнули носом хотябы в функции которые надо изменить под лагорифмические оси... СПасибо
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.