Название: Рисования линии на графике
Отправлено: Sergey от Июль 28, 2010, 11:26
Здравствуйте !
Появилась проблемка ( может она детская , но всё таки) требуется нарисовать на графике линию ....почему-то у меня получается что начало линия прорисовывается ....а потом график ....подскажите пожалуйста как исправить это ))) Линия должна быть горизонтальной ...и я должен иметь возможность перемещать её по оси Х и по оси Y.
Заранее благодарен !
Название: Re: Рисования линии на графике
Отправлено: daimon от Июль 28, 2010, 11:33
Рисуйте линию поверх графика (после отрисовки графика)- в самом пиксмепе. Если вы рисуете график на пиксмепе, а paintEvent потом рисуете этот пиксмеп, то можно и там после отрисовки графика с "потрохами" нарисовать линию
Название: Re: Рисования линии на графике
Отправлено: Sergey от Июль 28, 2010, 12:04
простите за глупый вопрос , но пиксмеп это что !? ) я не использовал пиксмеп . Был бы оченб благодарен за какой-то примерчик )
Название: Re: Рисования линии на графике
Отправлено: daimon от Июль 28, 2010, 16:16
простите за глупый вопрос , но пиксмеп это что !? ) я не использовал пиксмеп . Был бы оченб благодарен за какой-то примерчик )
QPixmap - это класс карты для рисования. Когда Вы создаетё QPainter (this)- this- указатель на окно, где рисовать, а Вам надо указатель на QPixmap. C++ (Qt) #include <QtGui> #include <cmath> #include "plotter.h" Plotter::Plotter(QWidget *parent) : QWidget(parent) { setAutoFillBackground(true); rubberBand = new QRubberBand(QRubberBand::Rectangle, this); rubberBand_is_shown=0; setMinimumSize(4*Margin, 3*Margin); connect(&opt_graph,SIGNAL(modified(bool)),this,SLOT(refreshPixmap())); origin.setX(0); origin.setY(0); } void Plotter::set_plot_settings(Settings2DGraph &opt_graph_) { opt_graph=opt_graph_; refreshPixmap(); } QSize Plotter::minimumSizeHint() const { return QSize(4 * Margin, 3 * Margin); } QSize Plotter::sizeHint() const { return QSize(12 * Margin, 8 * Margin); } void Plotter::paintEvent(QPaintEvent * /* event */) { QStylePainter painter(this); painter.drawPixmap(0, 0,pixmap);// mg); } void Plotter::resizeEvent(QResizeEvent * /* event */) { opt_graph.width_widget = this->size().width(); opt_graph.height_widget = this->size().height(); rect.setRect(Margin, Margin, opt_graph.width_widget - 2 * Margin, opt_graph.height_widget - 2*Margin); refreshPixmap(); } void Plotter::refreshPixmap() { pixmap = QPixmap(size()); QPainter painter(&pixmap); painter.initFrom(this); {drawGrid(&painter); painter.setRenderHint(QPainter::Antialiasing,true); drawCurves(&painter); drawCaptions(&painter);} update(); } void Plotter::drawCaptions(QPainter *painter) { if(rect.height()<50) return; //верхняя нормально if( opt_graph.caption_top!=""&&(QFontMetricsF(opt_graph.font_caption_left).width(opt_graph.caption_left) < rect.height() || QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top) < rect.width() )&& (QFontMetricsF(opt_graph.font_caption_right).width(opt_graph.caption_right) < rect.height() || QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top) < rect.width()) && QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top) +10 < opt_graph.width_widget) { painter->setClipping (false ); painter->setPen(opt_graph.pen_caption_top); painter->setFont(opt_graph.font_caption_top); painter->drawText(rect.left()+rect.width()/2-QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top)/2, rect.top()-10-QFontMetricsF(opt_graph.font_tick_labels).ascent()/2, QString(opt_graph.caption_top) ); } //нижняя надпись норма if( opt_graph.caption_bottom!=""&&(QFontMetricsF(opt_graph.font_caption_left).width(opt_graph.caption_left) < rect.width() || QFontMetricsF(opt_graph.font_caption_bottom).width(opt_graph.caption_bottom) < rect.width()) && (QFontMetricsF(opt_graph.font_caption_right).width(opt_graph.caption_right) < rect.height() || QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top) < rect.width()) && QFontMetricsF(opt_graph.font_caption_bottom).width(opt_graph.caption_bottom) +10 < rect.width()) { painter->setClipping (false ); painter->setPen(opt_graph.pen_caption_bottom); painter->setFont(opt_graph.font_caption_bottom); painter->drawText(rect.left()+rect.width()/2-QFontMetricsF(opt_graph.font_caption_bottom).width(opt_graph.caption_bottom)/2, rect.bottom() + 3+opt_graph.major_tick_length + QFontMetricsF(opt_graph.font_tick_labels).ascent()+3+ QFontMetricsF(opt_graph.font_caption_bottom).ascent() , QString(opt_graph.caption_bottom)); } //левая надпись норм if( opt_graph.caption_left!=""&&(QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top) < rect.width() || QFontMetricsF(opt_graph.font_caption_left).width(opt_graph.caption_left) < rect.height()) && (QFontMetricsF(opt_graph.font_caption_bottom).width(opt_graph.caption_bottom) < rect.width() || QFontMetricsF(opt_graph.font_caption_left).width(opt_graph.caption_left) < rect.height()) && QFontMetricsF(opt_graph.font_caption_left).width(opt_graph.caption_left) +10 < rect.height() && rect.left()-QFontMetricsF(opt_graph.font_tick_labels).width(QString::number(opt_graph.maxY_graph_all,opt_graph.type_label,opt_graph.precision_label))-5-opt_graph.major_tick_length-10-QFontMetrics(opt_graph.font_caption_left).height() >=0) { painter->rotate(-90.0); painter->translate(-opt_graph.height_widget,0); painter->setClipping (false ); painter->setPen(opt_graph.pen_caption_left); painter->setFont(opt_graph.font_caption_left); painter->drawText(opt_graph.height_widget-rect.bottom()+rect.height()/2-QFontMetricsF(opt_graph.font_caption_left).width(opt_graph.caption_left)/2, rect.left()-QFontMetricsF(opt_graph.font_tick_labels).width(QString::number(opt_graph.maxY_graph_all,opt_graph.type_label,opt_graph.precision_label))-5-opt_graph.major_tick_length-10, QString(opt_graph.caption_left)); painter->rotate(90.0); painter->translate(0,-opt_graph.height_widget); } //правая надпись норм if(opt_graph.caption_right!=""&& (QFontMetricsF(opt_graph.font_caption_top).width(opt_graph.caption_top) < rect.width() || QFontMetricsF(opt_graph.font_caption_right).width(opt_graph.caption_right) < rect.height()) && (QFontMetricsF(opt_graph.font_caption_bottom).width(opt_graph.caption_bottom) < rect.width() || QFontMetricsF(opt_graph.font_caption_right).width(opt_graph.caption_right) < rect.height()) && QFontMetricsF(opt_graph.font_caption_right).width(opt_graph.caption_right) +10 < rect.height()) { painter->rotate(+90.0); painter->translate(0,-opt_graph.width_widget); painter->setClipping (false ); painter->setPen(opt_graph.pen_caption_right); painter->setFont(opt_graph.font_caption_right); painter->drawText(rect.top()+rect.height()/2-QFontMetricsF(opt_graph.font_caption_right).width(opt_graph.caption_right)/2, opt_graph.width_widget-rect.right()-5-10-QFontMetricsF(opt_graph.font_caption_right).descent(), QString(opt_graph.caption_right)); painter->rotate(-90.0); painter->translate(-opt_graph.width_widget,0); } } void Plotter::drawGrid(QPainter *painter) { painter->fillRect(0,0,opt_graph.width_widget,opt_graph.height_widget,Qt::color0); if (rect.height()<50) return; painter->setFont(opt_graph.font_tick_labels); QFontMetrics fm(opt_graph.font_tick_labels); bool ok_label_x=(fm.width(QString::number(opt_graph.maxX_graph_all,opt_graph.type_label,opt_graph.precision_label))<(double(rect.width())/double((opt_graph.maxX_graph_all-opt_graph.minX_graph_all)/opt_graph.stepX))); bool ok_label_y=(opt_graph.font_tick_labels.pointSize()+opt_graph.font_tick_labels.pointSize()/2<(double(rect.height())/double((opt_graph.maxY_graph_all-opt_graph.minY_graph_all)/opt_graph.stepY)))&& (rect.left()- fm.width(QString::number(opt_graph.maxY_graph_all,opt_graph.type_label,opt_graph.precision_label))-opt_graph.major_tick_length - 5)>0; //для оси Х грид-линии подписи for (int i = 0; i <= ceil((opt_graph.maxX_graph_all-opt_graph.minX_graph_all)/opt_graph.stepX); ++i) { int x = rect.left() + (i * (rect.width() - 1) / ((opt_graph.maxX_graph_all-opt_graph.minX_graph_all)/opt_graph.stepX)); double label = opt_graph.minX_graph_all + (i * opt_graph.stepX); if(x>rect.right()||x<rect.left()) break; if(opt_graph.grid_on) { painter->setPen(opt_graph.grid_line); painter->drawLine(x, rect.top(), x, rect.bottom()); } painter->setPen(opt_graph.pen_aces); painter->drawLine(x, rect.bottom()-opt_graph.major_tick_length, x, rect.bottom() + opt_graph.major_tick_length); if(ok_label_x) { painter->setPen(opt_graph.pen_font_tick_labels); painter->drawText(x-fm.width(QString::number(label,opt_graph.type_label,opt_graph.precision_label))/2, rect.bottom()+opt_graph.major_tick_length+3, fm.width(QString::number(label,opt_graph.type_label,opt_graph.precision_label)), fm.height(), Qt::AlignHCenter | Qt::AlignTop, QString::number(label,opt_graph.type_label,opt_graph.precision_label)); } } //для оси У грид-линии подписи for (int j = 0; j <= ceil((opt_graph.maxY_graph_all-opt_graph.minY_graph_all)/opt_graph.stepY); ++j) { int y = rect.bottom() - (j * (rect.height() - 1) / ((opt_graph.maxY_graph_all-opt_graph.minY_graph_all)/opt_graph.stepY)); double label = opt_graph.minY_graph_all + (j * opt_graph.stepY);; if(y<rect.top()) break; if(opt_graph.grid_on) { painter->setPen(opt_graph.grid_line); painter->drawLine(rect.left(), y, rect.right(), y); } painter->setPen(opt_graph.pen_aces); painter->drawLine(rect.left() - opt_graph.major_tick_length, y, rect.left() + opt_graph.major_tick_length, y); if(ok_label_y) { painter->setPen(opt_graph.pen_font_tick_labels); painter->drawText(rect.left()- fm.width(QString::number(label,opt_graph.type_label,opt_graph.precision_label))-opt_graph.major_tick_length - 5, y - fm.height()/2, fm.width(QString::number(label,opt_graph.type_label,opt_graph.precision_label)), fm.height(), Qt::AlignRight | Qt::AlignVCenter, QString::number(label,opt_graph.type_label,opt_graph.precision_label));} } painter->setPen(opt_graph.pen_aces); painter->drawLine(QPoint(rect.left(),rect.bottom()),QPoint(rect.right(),rect.bottom())); painter->drawLine(QPoint(rect.left(),rect.bottom()),QPoint(rect.left(),rect.top())); } void Plotter::drawCurves(QPainter *painter) { if (rect.height()<50) return; painter->setClipRect(rect); for(int j=0;j< opt_graph.curves.size();j++) { if(opt_graph.curves[j].show_graph_one) for(int i=0; i<opt_graph.curves[j].table.size();i++) { opt_graph.curves[j].table[i].x_widget = x_widget(opt_graph.curves[j].table[i].x_tabl); opt_graph.curves[j].table[i].y_widget = y_widget(opt_graph.curves[j].table[i].y_tabl); if(i>0) { painter->setPen(opt_graph.curves[j].graph_line); painter->drawLine(opt_graph.curves[j].table[i-1].x_widget ,opt_graph.curves[j].table[i-1].y_widget, opt_graph.curves[j].table[i].x_widget,opt_graph.curves[j].table[i].y_widget); } painter->setPen(opt_graph.curves[j].graph_point); painter->drawPoint(opt_graph.curves[j].table[i].x_widget,opt_graph.curves[j].table[i].y_widget); } } } double Plotter::y_widget(double y_tabl_) { double dy = y_tabl_ - opt_graph.minY_graph_all; return rect.bottom() - (dy * (rect.height() - 1) / (opt_graph.maxY_graph_all - opt_graph.minY_graph_all)); } double Plotter::x_widget(double x_tabl_) { double dx = x_tabl_ - opt_graph.minX_graph_all; return rect.left() + (dx * (rect.width() - 1) / (opt_graph.maxX_graph_all - opt_graph.minX_graph_all)); } double Plotter::x_tabl(int x_widget_) { return ((((x_widget_ - rect.left() )* (opt_graph.maxX_graph_all - opt_graph.minX_graph_all)) )/ (rect.width() - 1)) + opt_graph.minX_graph_all; } double Plotter::y_tabl(int y_widget_) { return ((((rect.bottom()-y_widget_ )* (opt_graph.maxY_graph_all - opt_graph.minY_graph_all)) )/ (rect.height() - 1)) + opt_graph.minY_graph_all; } void Plotter::mousePressEvent(QMouseEvent *event) { if(event->button()==Qt::LeftButton) { if (rect.contains(event->pos())) { origin = event->pos(); rubberBand->setGeometry(QRect(origin, QSize())); rubberBand_is_shown=1; } } else if(event->button()==Qt::RightButton) { opt_graph.rescale(1); } } void Plotter::mouseMoveEvent(QMouseEvent *event) { if(rubberBand_is_shown==1) { rubberBand->setGeometry(QRect(origin, event->pos()).normalized()); rubberBand->show(); } } void Plotter::mouseReleaseEvent(QMouseEvent *event) { rubberBand->hide(); bool changed=false; if (rubberBand->geometry().width() < 4 || rubberBand->geometry().height() < 4) return; if(rubberBand_is_shown==1) { double minX_graph_all_widget=std::min(rubberBand->geometry().left(),rubberBand->geometry().right()); if(minX_graph_all_widget<rect.left()) minX_graph_all_widget = rect.left(); double minX_graph_all_old=x_tabl(minX_graph_all_widget); double maxX_graph_all_widget=std::max(rubberBand->geometry().left(),rubberBand->geometry().right()); if(maxX_graph_all_widget > rect.right()) maxX_graph_all_widget = rect.right(); double maxX_graph_all_old=x_tabl(maxX_graph_all_widget); double stepX=0; opt_graph.calculate_norm_Min_Max_Step(minX_graph_all_old,maxX_graph_all_old,stepX); if( QString::number(fabs(maxX_graph_all_old-minX_graph_all_old),'f',4).toDouble()>0.001) { opt_graph.minX_graph_all=minX_graph_all_old; opt_graph.maxX_graph_all=maxX_graph_all_old; opt_graph.calculate_norm_Min_Max_Step(opt_graph.minX_graph_all,opt_graph.maxX_graph_all,opt_graph.stepX); changed=1; } else changed=0; double minY_graph_all_widget=std::max(rubberBand->geometry().top(),rubberBand->geometry().bottom()); if(minY_graph_all_widget > rect.bottom()) minY_graph_all_widget = rect.bottom(); double minY_graph_all_old=y_tabl(minY_graph_all_widget); double maxY_graph_all_widget=std::min(rubberBand->geometry().top(),rubberBand->geometry().bottom()); if(maxY_graph_all_widget<rect.top()) maxY_graph_all_widget = rect.top(); double maxY_graph_all_old=y_tabl(maxY_graph_all_widget); double stepY=0; opt_graph.calculate_norm_Min_Max_Step(minY_graph_all_old,maxY_graph_all_old,stepY); if( QString::number(fabs(maxY_graph_all_old-minY_graph_all_old),'f',4).toDouble()>0.001) { opt_graph.minY_graph_all=minY_graph_all_old; opt_graph.maxY_graph_all=maxY_graph_all_old; opt_graph.stepY=stepY; changed=1; } else changed=0; if(changed) refreshPixmap(); } rubberBand_is_shown=0; } void Plotter::keyPressEvent(QKeyEvent *event) { switch (event->key()) { case Qt::Key_Left: opt_graph.move_left_right_coordinates_x(1,1); break; case Qt::Key_Right: opt_graph.move_left_right_coordinates_x(0,1); break; case Qt::Key_Down: opt_graph.move_top_bottom_coordinates_y(0,1); break; case Qt::Key_Up: opt_graph.move_top_bottom_coordinates_y(1,1); break; case Qt::Key_Minus: if(event->modifiers()&Qt::ShiftModifier) opt_graph.zoom_x(0,1); else if(event->modifiers()&Qt::ControlModifier) opt_graph.zoom_y(0,1); else opt_graph.zoom_x_y(0,1); break; case Qt::Key_Plus: if(event->modifiers()&Qt::ShiftModifier) opt_graph.zoom_x(1,1); else if(event->modifiers()&Qt::ControlModifier) opt_graph.zoom_y(1,1); else opt_graph.zoom_x_y(1,1); break; default: QWidget::keyPressEvent(event); } }
Название: Re: Рисования линии на графике
Отправлено: Sergey от Июль 28, 2010, 17:29
спасибо большое ) уже разобрался ....сделал немного по-другому .... взял просто кривую и сделал из нею прямую линию ....впринципе так вроде бы легче ....но ваш код понял спасибо ещё раз )
Появилась ещё одна проблемка даже две ! Первая заключается , в том что как в сетку добавить вертикальных линий , то есть сделать шаг сетки другой )
Заранее благодарен )
|