Russian Qt Forum
Октябрь 17, 2017, 14:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Урок: Библиотека QWT. Добавляем QwtSymbol, QwtPlotPicker, Zoomer. (Урок 2)  (Прочитано 21758 раз)
_Vitaliy_
Самовар
**
Offline Offline

Сообщений: 105


Просмотр профиля
« : Декабрь 29, 2009, 11:31 »

На этом уроке мы используем зумм и отобразим рядом с курсором координаты графика.

Пример использования скроллбара можно посмотреть в примере Х:\путь к QWT\examples\realtime_plot.
Читая файл readme можно увидеть такие строки:
Цитировать
ScrollZoomer adds scrollbars for zooming. There are a couple of
reasons why the implementation is a hack and therefore the class
is not part of the Qwt lib, but it should be working with all
types of QwtPlots. Copy the code of scrollbar.[h|cpp] and
scrollzoomer.[h|cpp] to the application code.
таким образом нам необходимо:
1. Скопировать данные файлы в нашу директорию с программой.
2. Подключить их к нашему проекту. Для этого правой кнопкой на проекте выбираем подключить существующие файлы и добавляем в наш проект 4 файла.
Рисунок иллюстрирующий использование кьюткреатора прикреплен в аттаче.
Далее в коде после вывода
Код:
// finally, refresh the plot
    myPlot->resize(800, 600);
    myPlot->replot();
Добавляем такие строки:
Код:
// enable zooming

        Zoomer *zoomer = new Zoomer(myPlot->canvas());
        zoomer->setRubberBandPen(QPen(Qt::red, 2, Qt::DotLine));
        zoomer->setTrackerPen(QPen(Qt::red));
        zoomer->zoom(0);
в заголовочном файле добавляем такие объявления:
Код:
#include <qwt_data.h>
#include <qwt_scale_widget.h>
#include "scrollzoomer.h"
и добавляем переменную
Код:
const unsigned int c_rangeMax = 1000;
которая отвечает за размер шкалы, выводимой на экран по одной из осей
и новый класс, отвечающий за зумм:
Код:
class Zoomer: public ScrollZoomer
{
public:
    Zoomer(QwtPlotCanvas *canvas):
        ScrollZoomer(canvas)
    {
    }

    virtual void rescale()
    {
        QwtScaleWidget *scaleWidget = plot()->axisWidget(yAxis());
        QwtScaleDraw *sd = scaleWidget->scaleDraw();

        int minExtent = 0;
        if ( zoomRectIndex() > 0 )
        {
            // When scrolling in vertical direction
            // the plot is jumping in horizontal direction
            // because of the different widths of the labels
            // So we better use a fixed extent.

            minExtent = sd->spacing() + sd->majTickLength() + 1;
            minExtent += sd->labelSize(
                scaleWidget->font(), c_rangeMax).width();
        }

        sd->setMinimumExtent(minExtent);

        ScrollZoomer::rescale();
    }
};
скомпилировав проект получаем заветный результат.
Теперь если на графике левой кнопкой мыши выделить область и отпустить кнопку мышки получим увеличенное изображение. Для отмены скролирования достаточно нажать правую кнопку. Полезным применением можно назвать тот факт, что при наведении на любое место в плоте и нажав левую кнопку мыши рядом с курсором
появятся координаты: по иксу и по игреку, что позволяют снимать показания с графиков в заданной точке.

Следующим шагом немного "облагородим" наш вывод графиков, для этого
Теперь нам необходимо чтобы плот выводился на все окно, для этого удаляем строку в
Код:
void obrabotka::setModel(QStandardItemModel *model)
{
...
QwtPlot *myPlot = new QwtPlot(this);
...
}
добавляем в obrabotka.h в секции:
Код:
...
private:
    QwtPlot *myPlot;
...
и далее в obrabotka.срр
в конструкторе:
Код:
obrabotka::obrabotka(QWidget *parent)
:QDialog(parent)
{
    myPlot = new QwtPlot();
}
Теперь добавим в конструктор еще такие строки:
Код:
...
QVBoxLayout *l = new QVBoxLayout();
    l->addWidget(myPlot);
    setLayout(l);
...
и подключим соответствующий инклуд:
Код:
#include <QtGui/QVBoxLayout>
Теперь если скомпилировать и запустить проект можно видеть, что при изменении размера окна, наш "плот" вместе с окном также изменяется.

Можно немного еще модифицировать наше приложение используя  QwtPlotPicker для вывода на экране координат точек плота для этого добавим в заголовочный файл следующее:
Код:
class QwtPlotPicker;

в секцию private:
 
Код:
...
 QwtPlotPicker *d_picker;
 ...
в файле obrabotka.срр в конце нашей функции в которой осуществляем рисование добавляем
Код:
...
// enable picker
    d_picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
                                 QwtPicker::PointSelection | QwtPicker::DragSelection,
                                 QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
                                 myPlot->canvas());
    d_picker->setRubberBandPen(QColor(Qt::green));
    d_picker->setRubberBand(QwtPicker::CrossRubberBand);
    d_picker->setTrackerPen(QColor(Qt::white));
...
скомпилировав проект можем наблюдать рядом с курсором с правой стороны координаты Х и Y точки.

Бывает также полезно выделять точки на кривой, по которой она строится. Для этого делаем следующее.
1. Подключаем в заголовочный файл:
Код:
#include <qwt_symbol.h>
2. В файле obrabotka.срр после объявления QwtPlotCurve *curve1 = new QwtPlotCurve("H ot T")  добавляем следующее
Код:
...
 QwtSymbol symbol1;
        symbol1.setStyle(QwtSymbol::Cross);
        curve1->setPen(QPen(Qt::red));
        symbol1.setPen(QColor(Qt::black));
        symbol1.setSize(2);
        curve1->setSymbol(symbol1);
        curve1->setStyle(QwtPlotCurve::Lines);
...
скомпилировав проект можно видеть что первая кривая красного цвета а ключевые точки черного цвета. Комбинируя различнные параметров QwtSymbol можно добиться желаемого (визуального) результата.

Данный пример (как и предыдущий) взяты из примеров, поставляющихся вместе с Qwt.  QwtPicker взят из примера bode,  QwtSymbol  - curvdemo1, Zoomer - realtime.

Можно было бы еще добавить легенду (пример simple) и сетку (bode) делается по аналогии.

Не раскрытым (пока) остается вопрос вывода на экран только части графика (например 100 единиц по оси Х) и чтобы одновременно был скролл, позволяющий пролистать оставшуюся часть графика. Я пок этот вопрос "не победил", да и на форуме по этому поводу упорно молчат... как с этот вопрос прояснится - появиться следующий урок.
Пример, который раскрывает тему этого урока находится во вложении.
« Последнее редактирование: Май 19, 2010, 08:37 от xintrea » Записан
daimon
Гость
« Ответ #1 : Май 26, 2010, 00:39 »

Цитировать
moc_scrollzoomer.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QwtPlotZoomer::staticMetaObject" (?staticMetaObject@QwtPlotZoomer@@2UQMetaObject@@B)

Как исправить?
« Последнее редактирование: Сентябрь 09, 2010, 12:19 от xintrea » Записан
sa_mel
Гость
« Ответ #2 : Август 15, 2010, 10:06 »

Спасибо за статью, она мне очень помогла в освоении QwtPlot. Удивило, что так мало отзывов, ведь больше в сети на эту тему ничего нет!
Все работает. Увеличивать и уменьшать график удобно, привычно. Не понравилось просматривать увеличенный график с помощью ScrollBar'ов. Иногда хочется переместить график по диагонали одним движением, так как это реализовано у TChart'а из библиотеки компонентов Delphi.

Попытался реализовать такой интерфейс самостоятельно. Дополнительно добавил возможность увеличивать и уменьшать график вращением колеса мыши при нажатой клавише Ctrl. То что получилось выложил здесь. Просьба оставить отзывы на этом форуме.

Вопрос к форумчанам.
Почему  приложение, собранное под Linux, при большом количестве точек на графике начинает заметно тормозить после изменения масштаба графика? В том же самом приложении, собранном под Windows, ничего подобного не наблюдается. Это особенности операционной системы или особенности реализации QwtPlot?
« Последнее редактирование: Август 15, 2010, 20:56 от sa_mel » Записан
tiiL
Гость
« Ответ #3 : Июнь 23, 2011, 07:59 »

class Zoomer: public ScrollZoomer
{
public:
    Zoomer(QwtPlotCanvas *canvas):
        ScrollZoomer(canvas)
    {
    }

    virtual void rescale()
    {
        QwtScaleWidget *scaleWidget = plot()->axisWidget(yAxis());
        QwtScaleDraw *sd = scaleWidget->scaleDraw();

        int minExtent = 0;
        if ( zoomRectIndex() > 0 )
        {
            // When scrolling in vertical direction
            // the plot is jumping in horizontal direction
            // because of the different widths of the labels
            // So we better use a fixed extent.

            minExtent = sd->spacing()+ sd->majTickLength()+ 1;
            minExtent += sd->labelSize(
               scaleWidget->font(), c_rangeMax).width();
        }

        sd->setMinimumExtent(minExtent);

        ScrollZoomer::rescale();
    }
};

компилятор выдает вот такое:

In file included from src\mainwindow.cpp:21:

src\/obrabotka.h: In member function 'virtual void Zoomer::rescale()':

src\/obrabotka.h:62: error: 'class QwtScaleDraw' has no member named 'majTickLength'

как лечить данную проблему?

PS: qwt 6.0.0 у меня
« Последнее редактирование: Июнь 23, 2011, 08:28 от tiiL » Записан
sa_mel
Гость
« Ответ #4 : Июнь 25, 2011, 22:36 »

Для tiiL

Похоже, что в qwt-6.0.0 вместо
Код:
minExtent = sd->spacing() + sd->majTickLength() + 1;
следует использовать
Код:
minExtent = floor(sd->spacing() + sd->tickLength(QwtScaleDiv::MajorTick) + 1);

Хочу отметить, что в qwt-6.0.0 по сравнению с qwt-5.2.1 появилось множество подобных мелких отличий, доставляющих неудобства при ее использовании. И у меня сложилось впечатление, что, в целом, qwt-6.0.0 работает хуже, например, динамически изменяющиеся графики тормозят. Сам я пока не стал отказываться от qwt-5.2.1 и жду, пока появится что-либо более достойное.
Записан
sa_mel
Гость
« Ответ #5 : Август 09, 2011, 18:05 »

С 1 августа 2011 вышла библиотека Qwt версии 6.0.1. Увы, притормаживает также, как и предшествующая версия 6.0.0. Вместе с ней появилась версия библиотеки 5.2.2 - как продолжение ветви, представленной версией 5.2.1. Эта ветвь работает по-прежнему быстро.
Записан
daimon
Гость
« Ответ #6 : Апрель 16, 2012, 02:05 »

С 1 августа 2011 вышла библиотека Qwt версии 6.0.1. Увы, притормаживает также, как и предшествующая версия 6.0.0. Вместе с ней появилась версия библиотеки 5.2.2 - как продолжение ветви, представленной версией 5.2.1. Эта ветвь работает по-прежнему быстро.
под версией 6.0.1 ошибок уйма данного проекта
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

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