В поддержку Qt

статьи в помощь разработчику

   

Главная

Статьи:

Выбор инструментов разработки

Установка MinGW

Установка Qt 4

Установка Qt 5

Сборка Qt 5

Установка Qt Creator

Проблемы Qt 4.8.3

Распараллеливание компиляции

Распараллеливание для Qt 5.0.1

Сборка отладчика GDB

Установка библиотеки Qwt

Плагин Qwt

Установка QwtPolar

Установка QwtPplot3D

Изменение палитры цветов QwtPlot3D

Конфигурация сборки по умолчанию

Сборка Qt Creator из исходников

Пример использования QwtPlot

Масштабирование QwtPlot в стиле TChart

Синхронное масштабирование

Пример использования QwtPolar

Пример использования QwtPlot3D

Редактирование QSplitter

Сборка в Ubuntu для Windows

Установка пакетов без интернета

Установка драйвера NVIDIA

Файлы:

Проект с интерфейсом QwtChartZoom

Проект с двумя шкалами температуры

Проект Delphi с интерфейсом TChart

Проект с интерфейсом ScrollZoomer

Исходники класса QwtChartZoom

 

Главная > Масштабирование QwtPlot в стиле TChart

 

Интерфейс масштабирования и перемещения графика QwtPlot в стиле TChart из библиотеки компонентов Delphi

В статье "Пример использования виджета QwtPlot из библиотеки Qwt" рассматривается интерфейс ScrollZoomer масштабирования и перемещения графика из примера realtime, поставляемого вместе с библиотекой Qwt. Он позволяет нажатием на левую кнопку мыши выделить на канве какую-либо область графика и увидеть ее в увеличенном масштабе. Кроме того, после перерисовки графика на канве появляются полосы прокрутки, с помощью которых можно перемещать просматриваемую область. Вернуться к исходному масштабу графика можно, нажав правую кнопку мыши. Готовый проект с подключенным интерфейсом ScrollZoomer доступен по ссылке.

Полосы прокрутки позволяют двигать график только в горизонтальном и вертикальном направлении, что не всегда удобно – иногда хочется перемещать его по диагонали. На мой взгляд, на много удобнее интерфейс масштабирования и перемещения графика у компонента TChart из библиотеки компонентов Delphi и C++Builder. Выделение области, определяющей новые границы графика, производится так же левой кнопкой мыши движением слева направо и сверху вниз. При отпускании левой кнопкой мыши график изменяет свой масштаб. Если попытаться выделить область в противоположном направлении, то при отпускании кнопки мыши границы графика вернутся к исходному состоянию. Перемещение графика (причем в любом направлении) производится при нажатой правой кнопке мыши. Для сравнения интерфейсов Вы можете посмотреть проект Delphi с аналогичным графиком.

Вашему вниманию предлагается класс QwtChartZoom, который обеспечивает интерфейс масштабирования и перемещения графика QwtPlot в стиле TChart из библиотеки компонентов Delphi и C++Builder. Кроме того, имеется два класса – QWheelZoomSvc и QAxisZoomSvc, которые придают интерфейсу масштабирования некоторую дополнительную функциональность.

Первое дополнение – класс QWheelZoomSvc – поддерживает изменение масштаба вращением колеса мыши при нажатой клавише <Ctrl> или <Shift>. Если нажата клавиша <Ctrl>, то масштабирование производится и по вертикольной оси, и по горизонтальной. Если нажат левый <Shift>, то изменяется масштаб только по вертикальной шкале, если правый <Shift>, – только по горизонтальной.

Второе дополнение – класс QAxisZoomSvc – позволяет изменять одну из границ шкалы, путем ее перетаскивания мышью так, как показано на рисунке

Если потянуть за правую половину горизонтальной шкалы, то будет меняться правая граница графика, если за левую, – соответственно, левая. Аналогично, если потянуть за верхнюю половину вертикальной шкалы, то будет меняться верхняя граница графика, если за нижнюю, – соответственно, нижняя.

Рассмотрим порядок подключения интерфейса QwtChartZoom к своему графику.

Пусть виджет QwtPlot с именем myPlot размещен на форме главного окна приложения. Ниже приведены заголовочный файл и файл реализации класса MainWindow.

файл "mainwindow.h"

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

Место для размещения дополнительных директив #include

namespace Ui {
  class MainWindow;
}

class MainWindow : public QMainWindow {
  Q_OBJECT

public:
  MainWindow(QWidget *parent = 0);
  ~MainWindow();

private:
  Ui::MainWindow *ui;

Место для размещения для указатей на элементы графика, менеджер масштабирования и его дополнения
}

#endif // MAINWINDOW_H

файл "mainwindow.cpp"

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);

Место для размещения инструкций наполнения графика, подключения менеджера масштабирования и его дополнений

}

MainWindow::~MainWindow()
{
Место для размещения инструкций удаления менеджера масштабирования, его дополнений и элементов графика

  delete ui;
}

Если форма разрабатывалась с помощью Qt Designer, то класс MainWindow определен в пространстве имен Ui, и доступ ко всем элементам формы осуществляется через указатель ui: например, ui->myPlot. Пустой график создается при выполнении инструкции ui->setupUi(this) в конструкторе главного окна приложения. Далее следует наполнение графика: создаются кривые с данными, устанавливаются свойства шкал и т.п. (пример оформления графика приведен в упомянутой выше статье). После перестроения графика здесь же в конструкторе к нему подключается менеджер масштабирования и перемещения – экземпляр класса QwtChartZoom вместе с дополнениями QWheelZoomSvc и QAxisZoomSvc. Понятно, что в свой проект надо добавить файлы, реализующие эти классы. В деструкторе перед удалением объектов из пространства имен Ui командой delete ui сначала удаляются менеджер масштабирования и его дополнения, а также все элементы графика, созданные в конструкторе командой new. Для того чтобы иметь доступ к этим элементам в деструкторе, указатели на них должны являться членами класса MainWindow и быть объявленными в заголовочном файле.

Таким образом, последовательность подключения интерфейса QwtChartZoom следующая

1. Копируем в папку со своим проектом файлы "qwtchartzoom.h", "qwtchartzoom.cpp", "qwheelzoomsvc.h", "qwheelzoomsvc.cpp", "qaxiszoomsvc.h" и "qaxiszoomsvc.cpp", которые доступны по ссылке. Если какое-то из дополений – QWheelZoomSvc или QAxisZoomSvc – не планируется использовать в проекте, то понятно, что файлы этого класса копировать не надо.

2. Добавляем скопированные файлы в свой проект

SOURCES += qwtchartzoom.cpp\
  qwheelzoomsvc.cpp\
  qaxiszoomsvc.cpp

HEADERS +=qwtchartzoom.h\
  qwheelzoomsvc.h\
  qaxiszoomsvc.h

Опять же, заголовочные файлы и файлы исходного кода классов QWheelZoomSvc и QAxisZoomSvc необходимо добавлять в проект только в том случае, если запланировано их использовать.

3. В заголовочный файл "mainwindow.h" включаем дополнительные директивы #include

#include "qwtchartzoom.h"
#include "qwheelzoomsvc.h" (если надо)
#include "qaxiszoomsvc.h" (если надо)

4. В секции private объявляем указатели на менеджер масштабирования и перемещения графика

QwtChartZoom *zoom;

и его дополнения

QWheelZoomSvc *whlzmsvc; (если надо)
QAxisZoomSvc *axzmsvc; (если надо)

5. В конструкторе главного окна приложения (файл "mainwindow.cpp") создаем экземпляр класса QwtChartZoom, и, если необходимо, переопределяем цвет каймы выделяемой области, задающей новый масштаб графика

zoom = new QwtChartZoom(ui->myPlot);
zoom->setRubberBandColor(Qt::white);

Здесь же, если запланировано, создаем экземпляр класса QWheelZoomSvc, и прикрепляем его к менеджеру масштабирования

whlzmsvc = new QWheelZoomSvc();
whlzmsvc->attach(zoom);

Далее, если запланировано, создаем экземпляр класса QAxisZoomSvc, и прикрепляем его к менеджеру масштабирования

axzmsvc = new QAxisZoomSvc();
axzmsvc->attach(zoom);

6. В деструктор вставляем команды удаления объектов

delete axzmsvc; (если надо)
delete whlzmsvc; (если надо)
delete zoom;

Готовый проект с подключенным интерфейсом доступен по ссылке.

По умолчанию всякое изменение масштаба или границ графика прорисовывется немедленно. Это создает определенную нагрузку на графическую систему. Поэтому на "слабых" компьютерах менеджер масштабирования во время выполнения некоторых операций, таких как перемещение графика или изменения одной из границ шкалы, может "притормаживать". В большей степени это проявляется при использовании библиотеки Qwt 6.x.x. Для таких случаев предусмотрен "легкий" режим интерфейса. Если он включен, то при перемещении графика, например, вместо него перемещается индикатор, изображающий канву графика, а прорисовка самого графика осуществляется только по завершении операции – отпускания правой кнопки мыши. Функции включения "легкого" режима, назначения стиля и цвета индикатора приведены ниже. Аналогично предусмотрен "легкий" режим для дополнения QAxisZoomSvc. Прорисовка графика после изменения границы шкалы производится только после отпускания левой кнопки мыши, а во время операции отображается индикатор, показывающий размер видимой части шкалы в новом масштабе.

На графике могут присутствовать сразу две вертикальные шкалы (или две горизонтальные). Масштаб на них может не совпадать, но переход от одной шкалы к другой осуществляется с помощью линейного преобразования. Координатная сетка привязана к одной из шкал. Могут отличаться и шрифты, использующиеся на шкалах. Класс QwtChartZoom умеет корректно работать с такими графиками.

Простой пример, пусть на графике изображены суточные колебания температуры, на левой шкале значения температуры по шкале Цельсия, а на правой – по шкале Фаренгейта. Шкалы связаны между собой соотношением

F = 1.8·t + 32,

где F – температура по шкале Фаренгейта, t – по шкале Цельсия. Координатная сетка привязана к левой шкале. Проект, иллюстрирующий приведенный пример, можно взять здесь. Для дополнительной демонстрации в интерфейсе масштабирования включен "легкий" режим.

Перечислим имеющиеся функции управления интерфейсом и его дополнениями

void QwtChartZoom::fixBoundaries()
Фиксирует текущие границы графика в качестве исходных. Отмена масштабирования и перемещения будет возвращать график имеено к этим границам.

void QwtChartZoom::setRubberBandColor(QColor)
Устанавливает цвет каймы выделяемой области, задающей новый размер графика, (по умолчанию черный).

void QwtChartZoom::setLightMode(bool)
Включает/выключает "легкий" режим перемещения графика (по умолчанию выключен).

void QwtChartZoom::indicateDragBand(QwtChartZoom::QDragIndiStyle)
Задает стиль индикатора перемещения графика в "легком" режиме. Аргумент может принимать значения
QwtChartZoom::disNone     – индикация отключена;
QwtChartZoom::disSimple   – упрощенная индикация;
QwtChartZoom::disDetailed – подробная индикация.
(По умолчанию задан стиль QwtChartZoom::disSimple.)

void QwtChartZoom::setDragBandColor(QColor)
Устанавливает цвет индикатора перемещения графика в "легком" режиме (по умолчанию черный).

void QWheelZoomSvc::attach(QwtChartZoom *)
Подключает дополнение QWheelZoomSvc к интерфейсу масштабирования.

void QWheelZoomSvc::setWheelFactor(double)
Задает коэффициент масштабирования графика при вращении колеса мыши (по умолчанию коэффициент равен 1.2).

void QAxisZoomSvc::attach(QwtChartZoom *)
Подключает дополнение QAxisZoomSvc к интерфейсу масштабирования.

void QAxisZoomSvc::setLightMode(bool)
Включает/выключает "легкий" режим изменения границы шкалы (по умолчанию выключен).

void QAxisZoomSvc::indicateDragBand(bool)
Включает/выключает индикацию изменения границы шкалы в "легком" режиме (по умолчанию индикация включена).

void QAxisZoomSvc::setAxisRubberBandColor(QColor)
Устанавливает цвет индикатора изменения границы шкалы в "легком" режиме (по умолчанию черный).

В дополнение к представленному имеется класс QChartSynZoom, который умеет управлять масштабом сразу нескольких графиков, у которых синхронизирована горизонтальная шкала. О нем можно прочитать в статье Синхронное масштабирование графиков.

 

Данная статья освещает ипользование класса QwtChartZoom версии 1.5.2. Доступны также старые редакции статьи о версиях 1.1 и 1.0.