Чтение онлайн

ЖАНРЫ

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

В Qt предусмотрено два способа управления формой курсора мышки:

QWidget::setCursor устанавливает форму курсора, которая используется при его нахождении на конкретном виджете. Если для виджета курсор не задан, используется курсор родительского виджета. По умолчанию для виджета верхнего уровня назначается курсор в виде стрелки;

QApplication::setOverrideCursor устанавливает форму курсора для всего приложения, отменяя формы курсоров отдельных виджетов до вызова функции restoreOverrideCursor.

В главе 4 мы вызывали функцию QApplication::setOverrideCursor

с параметром Qt::WaitCursor для установки курсора приложения на стандартный курсор ожидания.

107 void Plotter::mouseMoveEvent(QMouseEvent *event)

108 {

109 if (rubberBandIsShown) {

110 updateRubberBandRegion;

111 rubberBandRect.setBottomRight(event->pos);

112 updateRubberBandRegion;

113 }

114 }

Когда пользователь перемещает курсор мышки с нажатой левой кнопкой, мы сначала вызываем функцию updateRubberBandRegion для постановки в очередь события рисования для перерисовки области, занятой резиновой лентой, затем пересчитываем значение переменной rubberBandRect для учета перемещения курсора и, наконец, второй раз вызываем функцию updateRubberBandRegion для перерисовки области, в которую переместилась резиновая лента. Это фактически приводит к стиранию резиновой ленты и ее вычерчиванию с новыми координатами.

Если пользователь перемещает мышку вверх или влево, может оказаться, что номинальный нижний правый угол резиновой ленты rubberBandRect выше или левее верхнего левого угла. В этом случае QRect будет иметь отрицательную ширину или высоту. В paintEvent нами использована функция QRect::normalized, которая настраивает координаты верхнего левого и нижнего правого углов для получения положительного значения ширины и высоты.

115 void Plotter::mouseReleaseEvent(QMouseEvent *event)

116 {

117 if ((event->button == Qt::LeftButton) &&

118 rubberBandIsShown) {

119 rubberBandIsShown = false;

120 updateRubberBandRegion;

121 unsetCursor;

122 QRect rect = rubberBandRect.normalized;

123 if (rect.width < 4 || rect.height < 4)

124 return;

125 rect.translate(-Margin, -Margin);

126 PlotSettings prevSettings = zoomStack[curZoom];

127 PlotSettings settings;

128 double dx = prevSettings.spanX / (width - 2 * Margin);

130 double dy = prevSettings.spanY / (height - 2 * Margin);

131 settings.minX = prevSettings.minX + dx * rect.left;

132 settings.maxX = prevSettings.minX + dx * rect.right;

133 settings.minY = prevSettings.maxY - dy * rect.bottom;

134 settings.maxY = prevSettings.maxY - dy * rect.top;

135 settings.adjust;

136 zoomStack.resize(curZoom + 1);

137 zoomStack.append(settings);

138 zoomIn;

139 }

140 }

Когда

пользователь отпускает левую кнопку мышки, мы стираем резиновую ленту и восстанавливаем стандартный курсор в виде стрелки. Если резиновая лента ограничивает прямоугольник, по крайней мере размером 4 × 4, мы изменяем масштаб изображения. Если резиновая лента выделяет прямоугольник меньшего размера, то, по-видимому, пользователь сделал щелчок мышкой по ошибке или просто перевел фокус, и поэтому мы ничего не делаем.

Программный код по изменению масштаба изображения немного сложен. Это вызвано тем, что мы работаем сразу с двумя системами координат: виджета и построителя графиков. Большинство выполняемых здесь действий связано с преобразованием координат объекта rubberBandRect (прямоугольник резиновой ленты) из системы координат виджета в систему координат построителя графиков. После выполнения преобразований мы вызываем функцию PlotSettings::adjust для округления чисел и определения разумного количества отметок по обеим осям. Эта ситуация отражена на рис. 5.10 и 5.11.

Рис. 5.10. Преобразование прямоугольника резиновой ленты из системы координат виджета в систему координат построителя графиков.

Рис. 5.11. Настройка прямоугольника резиновой ленты в системе координат построителя графиков и увеличение изображения.

Затем мы изменяем масштаб изображения. Это достигается путем помещения новых, только что рассчитанных настроек PlotSettings в вершину стека масштабов изображения и вызова функции zoomIn, которая выполняет всю остальную работу.

141 void Plotter::keyPressEvent(QKeyEvent *event)

142 {

143 switch (event->key) {

144 case Qt::Key_Plus:

145 zoomIn;

146 break;

147 case Qt::Key_Minus:

148 zoomOut;

149 break;

150 case Qt::Key_Left:

151 zoomStack[curZoom].scroll(-1, 0);

152 refreshPixmap;

153 break;

154 case Qt::Key_Right:

155 zoomStack[сurZoom].scrol1(+1, 0);

156 refreshPixmap;

157 break;

158 case Qt::Key_Down:

159 zoomStack[curZoom].scroll(0, -1);

160 refreshPixmap;

161 break;

162 case Qt::Key_Up:

163 zoomStack[curZoom].scroll(0, +1);

164 refreshPixmap;

Поделиться с друзьями: