Russian Qt Forum
Май 05, 2024, 12:00 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qwt два графика  (Прочитано 8285 раз)
juvf
Программист
*****
Offline Offline

Сообщений: 564


Просмотр профиля
« : Июнь 08, 2017, 10:56 »

сделал два графика на одно плоте. один изменяется по Y от -1 до +1 (легенда слева), другой от 0 до 360 (легенда справа). Всё работает. Теперь до курсором вывожу текст, в виде значения (x,y);
координата х общая для обойх графиков. а вот y будет разный. Написал свой PlotPicker.

Цитировать
PlotPicker::PlotPicker(int xAxis, int yAxis, RubberBand rubberBand, DisplayMode trackerMode,
                       QWidget *canvas )
            : QwtPlotPicker(xAxis, yAxis, rubberBand, trackerMode, canvas)
{
}

QwtText PlotPicker::trackerTextF( const QPointF& pos ) const
{
    QTime time(0,0);
   time = time.addSecs(pos.x() * 0.001);
   QString timeStr = QString("%1\n%2 ms").arg(QString::number(pos.y(), 'f', 2))
                              .arg(pos.x());
    QwtText text;
    text.setText(timeStr);
    return text;
}

прикрутил его к QwtPlot. в методе QwtText PlotPicker::trackerTextF( const QPointF& pos ) const получаю координату pos с коодинатами по левой шкале, т.е. значение pos.y() изменяется от -1 до +1. А как вывести текст в QwtPlotPicker сразу с двух графиков? Как в QwtPlotPicker получить координату pos, у которой y изменяется от 0 до 360?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Июнь 08, 2017, 12:10 »

Цитировать
легенда слева
Цитировать
легенда справа
Скорее всего имелось в виду шкала, а не легенда.
Цитировать
If both or no x-axis are enabled, the picker is set to QwtPlot::xBottom. If both or no y-axis are enabled, it is set to QwtPlot::yLeft.
Возможно получится реализовать через QwtPlotPicker::transform и дополнительный пикер.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 564


Просмотр профиля
« Ответ #2 : Июнь 08, 2017, 12:16 »

Цитировать
Скорее всего имелось в виду шкала
да
Спасибо за ответ. QwtPlotPicker::transform - дает координату в пикселях.... ещё нужно масштаб прикрутить....
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Июнь 08, 2017, 12:44 »

Код
C++ (Qt)
#ifndef CURVETRACKER_H
#define CURVETRACKER_H
 
#include "plotsupportglobal.h"
 
#include <qwt/qwt_plot_picker.h>
 
class QwtPlotCurve;
 
namespace PlotSupport {
 
// CurveTracker
 
class CurveTracker : public QwtPlotPicker
{
   Q_OBJECT
 
public:
   explicit CurveTracker(QWidget *canvas);
 
protected:
   QwtText trackerTextF(const QPointF &pos) const final;
   QRect trackerRect(const QFont &font) const final;
 
private:
   QString curveInfoAt(const QwtPlotCurve *qwtcurve, const QPointF &pos) const;
   QLineF curveLineAt(const QwtPlotCurve *qwtcurve, double x) const;
 
private:
   QWidget *m_canvas; // not owned
};
 
} // namespace PlotSupport
 
#endif // CURVETRACKER_H
 

Код
C++ (Qt)
#include "curvetracker.h"
 
#include <qwt/qwt_plot.h>
#include <qwt/qwt_plot_curve.h>
#include <qwt/qwt_picker_machine.h>
 
namespace PlotSupport {
 
// CurveTracker
 
/*!
   \class PlotSupport::CurveTracker
   \inmodule PlotSupport
   \brief Класс отслеживания значений кривых.
 
   Это вспомогательный класс, который позволяет отслеживать
   значения кривых и отображать их в прямоугольнике.
 
   Также предоставляет перекрестие, которое двигается
   с курсором мыши.
*/

 
CurveTracker::CurveTracker(QWidget *canvas)
   : QwtPlotPicker(canvas)
   , m_canvas(canvas)
{
   setTrackerMode(CurveTracker::ActiveOnly);
   setRubberBand(CurveTracker::CrossRubberBand);
   setStateMachine(new QwtPickerTrackerMachine);
 
   QPen pen;
   pen.setColor(QColor(Qt::gray));
   setRubberBandPen(pen);
}
 
QRect CurveTracker::trackerRect(const QFont &font) const
{
   QRect r = QwtPlotPicker::trackerRect(font);
   // Всегда позиционируем прямоугольник с информацией о значениях
   // кривых в верхнем левом углу графика.
   r.moveTo(0, 0);
   return r;
}
 
QwtText CurveTracker::trackerTextF(const QPointF &pos) const
{
   QString info;
 
   // Тут используем реверсную итерацию для того, чтобы
   // информация последней кривой была сверху, а первой - снизу
   // (в соответствии с очередностью осей кривых).
   const auto curves = plot()->itemList(QwtPlotItem::Rtti_PlotCurve);
   for (auto curveIt = curves.crbegin(); curveIt != curves.crend(); ++curveIt) {
 
       // Не отображаем значения скрытых кривых.
       if (!(*curveIt)->isVisible())
           continue;
 
       const QString curveInfo = curveInfoAt(static_cast<const QwtPlotCurve *>(*curveIt), pos);
       if (!curveInfo.isEmpty()) {
           if (!info.isEmpty())
               info += tr("<br>");
           info += curveInfo;
       }
   }
 
   QwtText trackerText;
   const QPalette palette = m_canvas->palette();
   trackerText.setBorderPen(QPen(palette.text().color(), 2));
   trackerText.setBackgroundBrush(palette.dark());
   trackerText.setText(info);
   return trackerText;
}
 
QString CurveTracker::curveInfoAt(const QwtPlotCurve *qwtcurve, const QPointF &pos) const
{
   const QLineF line = curveLineAt(qwtcurve, pos.x());
   if (line.isNull())
       return QString();
 
   const double y = line.pointAt((pos.x() - line.p1().x()) / line.dx()).y();
   const QString text = QString(tr("<font color=""%1"">&nbsp;<b>%3</b>:&nbsp;%2&nbsp;</font>"))
           .arg(qwtcurve->pen().color().name())
           .arg(y)
           .arg(qwtcurve->title().text());;
   return text;
}
 
QLineF CurveTracker::curveLineAt(const QwtPlotCurve *qwtcurve, double x) const
{
   QLineF line;
   const auto samplesCount = qwtcurve->dataSize();
   if (samplesCount >= 2) {
       const QRectF boundingRect = qwtcurve->boundingRect();
       if ((boundingRect.width() > 0)
               && (x >= boundingRect.left())
               && (x <= boundingRect.right())) {
 
           auto lessfunc = [](const double x, const QPointF &pos) { return (x < pos.x()); };
           int sampleIndex = qwtUpperSampleIndex<QPointF>(*qwtcurve->data(), x, lessfunc);
 
           if (sampleIndex == -1) {
               const auto lastSample = qwtcurve->sample(int(samplesCount) - 1);
               if (qFuzzyCompare(x, lastSample.x()))
                   sampleIndex = int(samplesCount) - 1;
           }
           if (sampleIndex > 0) {
               line.setP1(qwtcurve->sample(sampleIndex - 1));
               line.setP2(qwtcurve->sample(sampleIndex));
           }
       }
   }
   return line;
}
 
} // namespace PlotSupport
 

Как то так.

ЗЫ: Тут значения не привязаны к курсору, а отображаются всегда в левом верхнем углу графика.
« Последнее редактирование: Июнь 08, 2017, 12:46 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
juvf
Программист
*****
Offline Offline

Сообщений: 564


Просмотр профиля
« Ответ #4 : Июнь 08, 2017, 13:18 »


Как то так.

ЗЫ: Тут значения не привязаны к курсору, а отображаются всегда в левом верхнем углу графика.
Да, у вас немного по другому работает отображение.... но главное с двух графиков получить. я под себя подретушировал класс CurveTracker.
Спасибо большое!!!!

ps А зачем вы сделали Q_OBJECT в CurveTracker? там нет сигналов/слотов. Лишний напряг компьютеру.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Июнь 08, 2017, 13:25 »

Цитировать
А зачем вы сделали Q_OBJECT в CurveTracker?

Не отрефакторил наверно (вероятно раньше были какие-то сигналы).
Записан

ArchLinux x86_64 / Win10 64 bit
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #6 : Июнь 08, 2017, 14:01 »

там нет сигналов/слотов. Лишний напряг компьютеру.
Мне кажется, что это не лучшая идея опускать макрос Q_OBJECT у наследников QObject
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 564


Просмотр профиля
« Ответ #7 : Июнь 08, 2017, 14:45 »

там нет сигналов/слотов. Лишний напряг компьютеру.
Мне кажется, что это не лучшая идея опускать макрос Q_OBJECT у наследников QObject

Макрос Q_OBJECT "добавляет" мето-объектную информацию, некий аналог RTTI.
Если какая-то функция захочет получить такую инфу от вашего класса, в котором нет Q_OBJECT, то обругается компилятор.
Я бы советовал добавлять макрос по мере надобности.
Недостаток у него один - усложняет компиляцию.

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.156 секунд. Запросов: 23.