Читаем QT 4: программирование GUI на С++ полностью

285 adjustAxis(minX, maxX, numXTicks);

286 adjustAxis(minY, maxY, numYTicks);

287 }

Функция adjust вызывается из mouseReleaseEvent для округления значений minX, maxX, minY и maxY, чтобы получить «удобные» значения, и определения количества меток на каждой оси. Закрытая фyнкция adjustAxis выполняет эти действия отдельно для каждой оси.

288 void PlotSettings::adjustAxis(double &min, double &max, int &numTiсks)

289 {

290 const int MinTicks = 4;

291 double grossStep = (max - min) / MinTicks;

292 double step = pow(10.0, floor(log10(grossStep)));

293 if (5 * step < grossStep) {

294 step *= 5;

295 } else if (2* step < grossStep) {

296 step *= 2;

297 }

298 numTicks = int (ceil(max / step) - floor(min / step));

299 if (numTicks < MinTicks)

300 numTicks = MinTicks;

301 min = floor(min / step) * step;

302 max = ceil(max / step) * step;

303 }

Функция adjustAxis преобразует свои параметры min и max в «удобные» числа и устанавливает свой параметр numTicks на количество меток, которое, по ее расчету, подходит для заданного диапазона [min, max]. Поскольку в функции adjustAxis фактически требуется модифицировать переменные (minX, maxX, numXTicks и так далее), а не просто копировать их, для этих параметров не используется модификатор const. Большая часть программного кода в adjustAxis предназначена просто для определения соответствующего значения интервала между двумя метками (переменная step — шаг). Для получения на оси удобных чисел мы должнытщательно выбирать этот шаг. Например, значение шага 3.8 привело бы к появлению на оси чисел, кратных 3.8, что затрудняет восприятие диаграммы человеком. Для осей с десятичной системой обозначения «удобными» значениями шага являются числа вида 10n, 2 • 10n или 5 • 10n.

Мы начинаем расчет с «крупного шага», то есть с определенного максимального значения шага. Затем мы находим число вида 10n, меньшее или равное крупному шагу. Мы его получаем путем взятия десятичного логарифма от крупного шага, затем округляем полученное значение до целого числа, после чего возводим 10 в степень, равную этому округленному значению. Например, если крупный шаг равен 236, мы вычисляем log 236 = 2.37291…; затем мы округляем это значение до 2 и получаем 102 = 100 в качестве кандидата на значениешага в форме числа 10n.

После получения первого кандидата на значение шага мы можем его использовать для расчета двух других кандидатов: 2 • 10n и 5 • 10n. Для нашего примера два других кандидата являются числами 200 и 500. Кандидат 500 имеет значение большее, чем крупный шаг, и поэтому мы не можем использовать его. Но 200 меньше, чем 236, и поэтому мы можем использовать 200 в качестве размера шага в нашем примере.

Достаточно легко получить numTicks, min и max из значения шага. Новое значение min получается путем округления снизу первоначального min до ближайшего числа, кратного этому шагу, а новое значение max получается путем округления сверху до ближайшего числа, кратного этому шагу. Новое значение numTicks представляет собой количество интервалов между округленными значениями min и max. Например, если при входе в функцию min равно 240, а max равно 1184, то новый диапазон будет равен [200, 1200] с пятью отметками.

Этот алгоритм в некоторых случаях дает почти оптимальный результат. Более изощренный алгоритм описан в статье Поля С. Хекберта (Paul S. Heckbert) «Nice Numbers for Graph Labels» (удобные числа для меток графа), опубликованной в Graphics Gems (ISBN 0—12—286166—3).

Данная глава является последней в части I. В ней объяснены способы настройки существующего виджета Qt и способы построения виджета с использованием в качестве основы базового класса виджетов QWidget. В главе 2 мы уже узнали, как можно построить виджет на основе существующих виджетов, и мы еще вернемся к этой теме в главе 6.

К этому моменту у нас достаточно знаний для написания законченных приложений с графическим интерфейсом с помощью средств разработки Qt. В частях II и III мы проведем более глубокое исследование Qt, чтобы можно было в полной мере использовать возможности Qt.

<p>Часть II. Средний уровень Qt—программирования</p>
Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже