У объекта painter есть функция отрисовки текста. Каким образом можно заставить ее затирать прежнее значение? При отрисовке значения пересечения визира с графиков значение выводится несколько(а то и несколько сот) раз, из-за чего в итоге не разобрать значения.
И опять же сдвиг точки, что не радует....
[attachment=724:test1.JPG]
нужно рисовать в риал-тайме и делать апдейт регионов, где рисовал при перерисовке.
покажи код как рисуешь.
AD,
пользуй не просто drawText а
fillRect
затем
drawText() в тотже rect что и затер фоном
/// Отрисовка графика
void GraphicDisplay::paintEvent(QPaintEvent* events)
{
painter.begin(this);
painter.setWindow(paramsDisplay -> rect());
painter.setFont(QFont("Tahoma", 8, Qt::SolidLine));
painter.setPen(Qt::black);
drawGrid(&painter);
drawCurves(&painter);
painter.end();
}
/// Отрисовка графика
void GraphicDisplay::drawCurves(QPainter* painter)
{
// .....
painter -> drawLine(polyline.last(), pnt),
viewCoordViewfinder(painter, data, j, pnt);
// ......
}
/// Отображение координат пересечения с визиром
void GraphicDisplay::viewCoordViewfinder(QPainter* painter, const QVector<SpecPointF>& data, int index,
const QPointF& pnt)
{
if(!v_viewfinderAction -> isChecked() && !h_viewfinderAction -> isChecked())
return;
double graphic_x = data[index].x(), graphic_y = data[index].y();
foreach(VFFrame* pf, viewfinderList)
{
int frame_x = pf -> x(), frame_y = pf -> y();
double graph_x = pnt.x(), graph_y = pnt.y();
if(pf -> frameShape() == QFrame::VLine && v_viewfinderAction -> isChecked())
if(fabs(frame_x - graph_x) <= 3.)
{
QPointF coord(pnt.x() + 40., pnt.y() - 1.);
QPen oldPen(painter -> pen());
painter -> setPen(Qt::black);
painter -> setBrush(oldPen.color());
QRect cycle_rect(QPoint(pnt.x() - 1, pnt.y() - 1),
QPoint(pnt.x() + 1, pnt.y() + 1));
painter -> drawEllipse(cycle_rect);
painter -> drawText(coord, QString::number(graphic_y));
painter -> setPen(oldPen);
}
// ..................
}
}
Пока ничего не помогло. filRect - не помог.
AD,
как так не помогло.
???
m_painter->begin(this);
m_painter->fillRect(CSKMain::cellRects[CSKSession::e_TIME],CSKConf::colorByStation(pointState));
m_painter->setFont(CSKConf::time_font());
m_painter->drawText(CSKMain::cellRects[CSKSession::e_TIME],Qt::AlignCenter,point->Time().toString(CSKConf::timeFormat));
m_painter->end();
Возможно, я и ошибся, возможно, руки кривоваты. А может быть, что при большом масштабе, точки пересечения, находящиеся рядом накладываются друг на друга, или же не точка пересечения, распознать такие ситуации не очень знаю как - чтобы выделять точки начала и конца отрезка. При приближении вырисовывается нормально, но при сильном приближении точка исчезает. Видимо условие
if(fabs(frame_x - graph_x) <= 3.)
дает ложь. Алгоритм не очень хороший, насколько мне видно. Как его изменить на более предсказуемый, пока не знаю!
Основное непонимание, почему есть сдвиг между положением визира и отрисовываемой точкой. Как определить, что имеется пересечение отрезком.
Никак не могу понять, почему есть смещение рисуемой точки от визира? Подскажите, пожалуйста, где возможна ошибка?
kwisp, посмотрел более внимательно, fillRect() действительно помог, я ошибся. Спасибо. Задача разнести текст при большом масштабе, когда точки находятся рядом. Сделать отметку точек ровно в точке пересечения, а не со смещением. Пока что у меня это не получается.
AD,
как бы всё для этого есть.
всякие там
QRect QRect::intersected ( const QRect & rectangle ) const
и проч.
Тему разделил: http://www.forum.crossplatform.ru/index.php?showtopic=3198
Получилось сделать корректное отображение пересечение графика с визиром.
Вот что получилось.
График кривой без сглаживания:
[attachment=725:graphic_...moothing.JPG]
График кривой со сглаживанием:
[attachment=726:graphic_...moothing.JPG]
Выложу код, вдруг, все-таки пригодится кому-нибудь. Если что, смогу и объяснить, где что в коде делается!
/// Получение размерностей заданной по id кривой
QPointF GraphicDisplay::dimensions(int id)
{
QString x_dimension(fact_prm[id].dimension[language_flag].toLower());
double x_dim = (metric_map[x_dimension]) ? metric_map[x_dimension] : 1.0;
QString y_dimension(fact_prm[id].y_dim[language_flag].toLower());
double y_dim = (metric_map[y_dimension]) ? metric_map[y_dimension] : 1.0;
return QPointF(x_dim, y_dim);
}
/// Поиск точки пересечения визира с графиком (в реальных координатах - следует переводить в экранные)
QPointF GraphicDisplay::findCrossPoint(const QPointF& pnt, const QPointF& prev_pnt, const QPointF& pnt_vf)
{
double curr_x = pnt.x(), curr_y = pnt.y(), prev_x = prev_pnt.x(), prev_y = prev_pnt.y(), y_vf = pnt_vf.y(),
x_vf = pnt_vf.x();
double y = prev_y + (curr_y - prev_y) * (x_vf - prev_x) / (curr_x - prev_x),
x = prev_x + (curr_x - prev_x) * (y_vf - prev_y) / (curr_y - prev_y);
if(curr_y - prev_y == 0.) x = curr_x;
if(curr_x - prev_x == 0.) y = curr_y;
return QPointF(x, y);
}
/// Отображение текста точки пересечения визира с графиком
void GraphicDisplay::drawViewfinderText(QPainter* painter, const QPointF& coord, const QPen& pen,
double coordinate)
{
QBrush oldBrush(pen.color());
QPen oldPen(pen.color());
painter -> setBrush(pen.color());
QColor color((pen.color() == QColor(Qt::blue)) ? Qt::darkGreen : Qt::blue);
painter -> setPen(color);
painter -> drawText(coord, QString::number(coordinate));
painter -> setPen(oldPen);
painter -> setBrush(oldBrush);
}
/// Отображение координат пересечения с визиром
void GraphicDisplay::viewCoordViewfinder(QPainter* painter, int id, const QVector<SpecPointF>& data, int index)
{
if(!v_viewfinderAction -> isChecked() && !h_viewfinderAction -> isChecked()) return;
QPointF dim(dimensions(id));
double real_y = data[index].y(), prev_ry = data[index - 1].y(),
real_x = (settings.win_type != COUNTPARAM) ? data[index].x() * dim.x() : data[index].x(),
prev_rx = (settings.win_type != COUNTPARAM) ? data[index - 1].x() * dim.x() : data[index - 1].x();
QPointF pnt(initXY(real_x, real_y)), prev_pnt(initXY(prev_rx, prev_ry)), rl_pnt(real_x, real_y),
prev_rl_pnt(prev_rx, prev_ry);
foreach(VFFrame* pf, viewfinderList)
{
QPoint screen_pnt_vf(pf -> x(), pf -> y());
QPointF pnt_vf(initXY(&screen_pnt_vf));
double prev_x = prev_rl_pnt.x(), prev_y = prev_rl_pnt.y(), curr_x = rl_pnt.x(), curr_y = rl_pnt.y();
double x_vf = pnt_vf.x(), y_vf = pnt_vf.y();
QPointF res_point(findCrossPoint(rl_pnt, prev_rl_pnt, pnt_vf));
double result_x = res_point.x(), result_y = res_point.y();
QPointF crd_scr(initXY(result_x, result_y));
if(pf -> frameShape() == QFrame::VLine && v_viewfinderAction -> isChecked() &&
prev_x <= x_vf && curr_x > x_vf)
{
QPointF coord(pf -> x() + 15, crd_scr.y() - 1.);
drawViewfinderText(painter, coord, painter -> pen(), res_point.y());
}
else if(pf -> frameShape() == QFrame::HLine && h_viewfinderAction -> isChecked() &&
prev_y <= y_vf && curr_y > y_vf)
{
QPointF coord(crd_scr.x() - 1., pf -> y() - 15.);
drawViewfinderText(painter, coord, painter -> pen(), res_point.x());
}
}
}
/// Отрисовка графика
void GraphicDisplay::drawCurves(QPainter* painter)
{
if(!paramsDisplay -> rect().isValid()) return;
painter -> setClipRect(paramsDisplay -> rect().adjusted(1, 1, -1, -1));
QMapIterator<int, QVector<SpecPointF>> iter(curveMap);
int k = 1;
bool smoothing = valueElement("diagramSmooth", false).toBool();
while(iter.hasNext())
{
iter.next(); int id = iter.key();
if(fact_prm.size() == 0 || id >= fact_prm.size()) break;
if(settings.win_type != fact_prm[id].type) continue;
QPointF dim(dimensions(id));
setColorPen(painter, id);
const QVector<SpecPointF>& data = iter.value();
QPolygonF polyline(0);
for(int j=0; j<data.size(); ++j)
{
if(!isExistPhase(data[j])) continue;
double x = (settings.win_type != COUNTPARAM) ? data[j].x() * dim.x() : data[j].x();
double y = data[j].y() * dim.y();
QPointF pnt(initXY(x, y));
if(!polyline.isEmpty())
{
if(smoothing && pnt.x() <= polyline.last().x()) continue;
setPenForLine(j);
painter -> setPen(myPen);
if(j > 0 && isExistPhase(data[j - 1]))
painter -> drawLine(polyline.last(), pnt),
viewCoordViewfinder(painter, id, data, j);
polyline.append(pnt);
}
else polyline.append(pnt);
}
drawLegend(painter, paramsDisplay -> rect(), k, id);
}
}
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)