- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
QT 4: программирование GUI на С++ - Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
Среди переменных—членов находится pixmap, которая имеет тип QPixmap. Эта переменная содержит копию всего виджета, идентичную его изображению на экране. График всегда сначала строится вне экрана на пиксельной карте, и затем пиксельная карта помещается на виджет.
45 class PlotSettings
46 {
47 public:
48 PlotSettings();
49 void scroll(int dx, int dy);
50 void adjust();
51 double spanX() const { return maxX - minX; }
52 double spanY() const { return maxY - minY; }
53 double minX;
54 double maxX;
55 int numXTicks;
56 double minY;
57 double maxY;
58 int numYTicks;
59 private:
60 static void adjustAxis(double &min, double &max, int &numTicks);
61 };
62 #endif
Класс PlotSettings задает диапазон значений по осям x и y и количество отметок на этих осях. На рис. 5.8 показано соответствие между объектом PlotSettings и виджетом Plotter.
По условному соглашению значение в numXTicks и numYTicks задается на единицу меньше; если numXTicks равно 5, Plotter будет на самом деле выводить 6 отметок по оси x. Это упростит расчеты в будущем.
Рис. 5.8. Переменные—члены настроек графика PlotSettings.
Теперь давайте рассмотрим файл реализации:
001 #include <QtGui>
002 #include <cmath>
003 #include "plotter.h"
Мы включаем необходимые заголовочные файлы и импортируем все символы пространства имен std в глобальное пространство имен. Это позволяет нам получать доступ к функциям, объявленным в <cmath>, без указания префикса std:: (например, floor() вместо std::floor()).
004 Plotter::Plotter(QWidget *parent)
005 : QWidget(parent)
006 {
007 setBackgroundRole(QPalette::Dark);
008 setAutoFillBackground(true);
009 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
010 setFocusPolicy(Qt::StrongFocus);
011 rubberBandIsShown = false;
012 zoomInButton = new QToolButton(this);
013 zoomInButton->setIcon(QIcon(":/images/zoomin.png"));
014 zoomInButton->adjustSize();
015 connect(zoomInButton, SIGNAL(clicked()), this, SLOT(zoomIn()));
016 zoomOutButton = new QToolButton(this);
017 zoomOutButton->setIcon(QIcon(":/images/zoomout.png"));
018 zoomOutButton->adjustSize();
019 connect(zoomOutButton, SIGNAL(clicked()), this, SLOT(zoomOut()));
020 setPlotSettings(PlotSettings());
021 }
Вызов setBackgroundRole() указывает QWidget на необходимость использования для цвета стирания виджета «темного» компонента палитры вместо компонента «window» (окно). Этим мы определяем цвет, который будет использоваться в Qt по умолчанию для заполнения любых вновь появившихся пикселей при увеличении размеров виджета прежде, чем paintEvent() получит возможность рисования нового пикселя. Для включения этого механизма необходимо также вызвать setAutoFillBackground(true). (По умолчанию дочерние виджеты наследуют фон своего родительского виджета.)
Вызов setSizePolicy() устанавливает политику размера виджета по обоим направлениям на значение QSizePolicy::Expanding. Это подсказывает любому менеджеру компоновки, который ответственен за виджет, что он прежде всего склонен к росту, но может также сжиматься. Такая настройка параметров типична для виджетов, которые занимают много места на экране. По умолчанию в обоих направлениях устанавливается политика QSizePolicy::Preferred, означающая, что для виджета предпочтительно устанавливать размер на основе его идеального размера, но он может сжиматься до своего минимального идеального размера или расширяться в любых пределах при необходимости.
Вызов setFocusPolicy(Qt::StrongFocus) заставляет виджет получать фокус при нажатии клавиши табуляции Tab. Когда Plotter получает фокус, он будет реагировать на события нажития клавиш. Виджет Plotter понимает несколько клавиш: «+» для увеличения изображения, «—» для уменьшения изображения и клавиш стрелок для прокрутки вверх, вниз, влево и вправо.
Рис. 5.9. Скроллинг виджета Plotter.
Также в конструкторе мы создаем две кнопки QToolButtons, каждая из которых имеет пиктограмму. Эти кнопки дают возможность пользователю увеличивать и уменьшать масштаб изображения. Пиктограммы кнопок хранятся в файле ресурсов, поэтому любое приложение, использующее виджет Plotter, должно иметь следующую строку в файле .pro:
RESOURCES = plotter.qrc
Этот файл ресурсов похож на файл, который мы использовали для приложения Электронная таблица:
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>images/zoomin.png</file>
<file>images/zoomout.png</file>
</qresource>
</RCC>
Вызовы функции adjustSize() устанавливают для кнопок их идеальные размеры. Кнопки не размещаются в менеджере компоновки; вместо этого мы задаем их положение вручную при обработке события изменения размеров виджета Plotter. Поскольку мы не пользуемся никакими менеджерами компоновки, необходимо явно задавать родительский виджет кнопок, передавая this конструктору QPushButton.
Вызов в конце функции setPlotSettings() завершает инициализацию.
022 void Plotter::setPlotSettings(const PlotSettings &settings)
023 {
024 zoomStack.clear();
025 zoomStack.append(settings);
026 curZoom = 0;
027 zoomInButton->hide();
028 zoomOutButton->hide();
029 refreshPixmap();
030 }
Функция setPlotSettings() устанавливает настройки PlotSettings для отображения графика. Ее вызывает конструктор Plotter, и она может также вызываться пользователями класса. Построитель кривых начинает работу с принятого по умолчанию масштаба изображения. Каждый раз, когда пользователь увеличивает изображение, создается новый экземпляр PlotSettings, который затем помещается в стек масштабов изображения. Этот стек масштабов изображений представлен двумя переменными—членами:
• zoomStack содержит настройки для различных масштабов изображения в объекте QVector<PlotSettings>;
• curZoom содержит индекс текущего элемента PlotSettings стека zoomStack.
После вызова функции setPlotSettings() в стеке масштабов изображений будет находиться только один элемент, а кнопки Zoom In и Zoom Out будут скрыты. Эти кнопки не будут видны на экране до тех пор, пока мы не вызовем для них функцию show() в слотах zoomIn() и zoomOut(). (Обычно для показа всех дочерних виджетов достаточно вызвать функцию show() для виджета верхнего уровня. Но когда мы явным образом вызываем для дочернего виджета функцию hide(), этот виджет будет скрыт до вызова для него функции show().)
Вызов функции refreshPixmap() необходим для обновления изображения на экране. Обычно мы вызываем функцию update(), но здесь мы поступаем немного по-другому, потому что хотим иметь пиксельную карту QPixmap постоянно в обновленном состоянии. После регенерации пиксельной карты функция refreshPixmap() вызывает update() для помещения пиксельной карты на виджет.
031 void Plotter::zoomOut()
032 {
033 if (curZoom > 0) {
034 --curZoom;
035 zoomOutButton->setEnabled(curZoom > 0);
036 zoomInButton->setEnabled(true);
037 zoomInButton->show();
038 refreshPixmap();
039 }
040 }
Слот zoomOut() уменьшает масштаб диаграммы, если она отображена крупным планом. Он уменьшает на единицу текущий масштаб изображения и включает или выключает кнопку ZoomOut, в зависимости от возможности дальнейшего уменьшения диаграммы. Кнопка Zoom In включается и отображается на экране, а изображение диаграммы обновляется посредством вызова функции refreshPixmap().
041 void Plotter::zoomIn()
042 {
043 zoomInButton->setEnabled(curZoom< zoomStack.count() - 1);
044 if (curZoom < zoomStack.count() - 1) {
045 ++curZoom;
046 zoomOutButton->setEnabled(true);
047 zoomOutButton->show();
048 refreshPixmap();
049 }
050 }
Если пользователь сначала увеличил изображение, а затем вновь его уменьшил, настройки PlotSettings для следующего масштаба изображения уже будут в стеке масштабов изображения, и мы можем увеличить его. (В противном случае можно все же увеличить изображение при помощи резиновой ленты.)
Слот увеличивает на единицу значение curZoom для перехода на один уровень вглубь стека масштабов изображения, включает или выключает кнопку Zoom In взависимости от возможности дальнейшего увеличения изображения и включает и показывает кнопку Zoom Out. И вновь мы вызываем refreshPixmap() для использования построителем графиков настроек самого последнего масштаба изображения.

