Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: kkk777kkk от Сентябрь 09, 2010, 16:46



Название: Падает QGLWidget при рисовании графика
Отправлено: kkk777kkk от Сентябрь 09, 2010, 16:46
Доброго времени суток.
Рисую в paintGL() через QPainter банальными функциями, а при накоплении определенного числа точек приложение падает, такое впечатление, что где-то что-то переполняется, но что не могу понять. Падает именно в методе paintGL(), при 6 экземплярах графика на форме держит по 400-600 для каждого, при 3 - по 900. Заранее спасибо.



Код:
void GraphDraw::paintGL()
{
    QPainter painter(this);
    if (points.count()>2 || pointsx.count()>2) {
        float maxXp;
        float minXp;
        float maxYp;
        float minYp;
        float maxXt;
        float minXt;
        float maxYt;
        float minYt;
        float stepX;
        float stepY;

        painter.translate(0, float(height())/2); //сместить по вертикали ось в центр

        if (!zoom) {
            maxXt = maxX;
            minXt = minX;
            maxYt = maxY;
            minYt = minY;
        }
        else { //пересчет при включенном увеличении
            maxXt = zoomListMax[zoom-1].first;
            minXt = zoomListMin[zoom-1].first;
            maxYt = zoomListMax[zoom-1].second;
            minYt = zoomListMin[zoom-1].second;
        }

        stepX = qAbs(maxXt - minXt)/10; //поделить сеткой по вертикали поле на 10 ячеек
        stepY = qAbs(maxYt - minYt)/10; //поделить сеткой по горизонтали поле на 10 ячеек
        maxXp = maxXt + 0.4*stepX; //отступ от максимального
        minXp = minXt - 0.4*stepX; //значения по оси для красоты
        maxYp = maxYt + 0.4*stepY;
        minYp = minYt - 0.4*stepY; //
        wsx = float(width()) / qAbs(maxXp - minXp); //масштабный коэф
        wsy = float(height()) / qAbs(maxYp - minYp); //масштабный коэф
        wdx = float(width())/2 - (maxXp*wsx + minXp*wsx)/2; //смещения из-за масштаба
        wdy = - (maxYp*wsy + minYp*wsy)/2; //смещения из-за масштаба

        //сетка
        for (float i=minXt;i<maxXt+stepX;i+=stepX) {
            painter.setPen(palette().dark().color());
            painter.drawLine(QPointF(i*wsx + wdx, -float(height())/2), QPointF(i*wsx + wdx, float(height())/2));
            painter.setPen(QPen(Qt::darkGreen));
            painter.drawText(QPointF(i*wsx + wdx -float(fm->width(QString::number(i,'f',1))/2), float(25)/2), QString::number(i,'f',1));
        }
        for (float i=minYt;i<=maxYt+stepY;i+=stepY) {
            painter.setPen(palette().dark().color());
            painter.drawLine(QPointF(0, -(i*wsy + wdy)), QPointF(width(), -(i*wsy + wdy)));
            painter.setPen(QPen(Qt::darkGreen));
            painter.drawText(QPointF(5, -(i*wsy + wdy+4)),QString::number(i,'f',4));
        }

//        painter.setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
//        painter.drawLine(QPointF(0, 0), QPointF(width(), 0));//ось х
//        painter.drawLine(QPointF(1, -float(height())/2), QPointF(1, float(height())/2));//ось y

        painter.setRenderHint(QPainter::Antialiasing, antialiasing);//сглаживание
        painter.setPen(QPen(Qt::red, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));

        if (sorting) {
            //через сортировку
            QPointF *mpoints = new QPointF[points.count()];
            QList<float> pointsk(points.keys());
            for (int m = 0; m<points.count(); m++)
                mpoints[m]=QPointF(pointsk[m]*wsx + wdx, -(points.value(pointsk[m])*wsy + wdy)); //пересчет значений точек
            painter.drawPolyline(mpoints, points.count());//вывод точек в полилинию
            delete []mpoints;
        }
        else {
            //без сортировки (вероятно немного быстрее)
            QPointF *mpoints = new QPointF[pointsx.count()];
            for (int m = 0; m<pointsx.count(); m++)
                mpoints[m]=QPointF(pointsx[m]*wsx + wdx, -(pointsy[m]*wsy + wdy)); //пересчет значений точек
            painter.drawPolyline(mpoints, pointsx.count());//вывод точек в полилинию
            delete []mpoints;
        }

        painter.translate(0, -float(height())/2); //перенос оси обратно

        painter.setPen(QPen(Qt::black, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
        painter.drawRect(QRect(0, 0, width(), height()));//рисуем ободок
//        font.setStyleStrategy(QFont::OpenGLCompatible);
//        font.setStyleStrategy(QFont::PreferAntialias);

        painter.drawText(float(width())-fm->width("<---   " + xlegend)-10, 15, "<---   " + xlegend);//легенда x

        painter.rotate(90);

        painter.drawText(30, -width()+20, ylegend + "   --->");//легенда y

        painter.rotate(-90);//возврат

        if (mouseState)
            painter.drawRect(QRectF(clickPoint, currPoint));
    }
}

Код:
GraphDraw::GraphDraw(QWidget *parent) //: QWidget(parent)
        : QGLWidget(QGLFormat(QGL::SampleBuffers/* | QGL::DoubleBuffer | QGL::DirectRendering*/), parent)
{
//    setAttribute(Qt::WA_OpaquePaintEvent);
    setBackgroundRole(QPalette::Base);
    setAutoFillBackground(true);
    setMouseTracking(true);
    setCursor(Qt::CrossCursor);
    maxX = -(numeric_limits<float>::max());
    minX = numeric_limits<float>::max();
    maxY = -(numeric_limits<float>::max());
    minY = numeric_limits<float>::max();
    QFont fonttemp(font()); fonttemp.setPointSize(6); setFont(fonttemp);
    fm = new QFontMetrics(font());
    sorting = false;
    antialiasing = false;

    mouseState = 0;
    zoom = 0;
    wsx = 0;
    wsy = 0;
    wdx = 0;
    wdy = 0;
}  

GraphDraw::~GraphDraw()
{

}

QSize GraphDraw::sizeHint() const
{
    return QSize(width(), height());
}

void GraphDraw::resizeEvent(QResizeEvent * event)
{
    event->accept();
}


Название: Re: Падает QGLWidget при рисовании графика
Отправлено: kkk777kkk от Сентябрь 09, 2010, 22:25
есть один нюанс: если отрисовать на графике сразу хоть 20000 точек или скрыть график до того как в массиве, который выводится наберется много точек, то все нормально, но только начинаешь добавлять в этот массив по одной и график видим и соответственно постоянно перерисовывается, то
Цитировать
при 6 экземплярах графика на форме держит по 400-600 для каждого, при 3 - по 900
и даже если отобразить 20000 точек сразу, а потом запустить плавное добавление по одной точке, то через выше названое количество точек вылетает... что ж за загадка такая


Название: Re: Падает QGLWidget при рисовании графика
Отправлено: kkk777kkk от Сентябрь 10, 2010, 14:40
никогда бы ни подумал, но все дело было в коварном drawText, буду рисовать его на QPixmap