Я работал над виджетом пользовательского интерфейса в течение нескольких дней и боролся за большую его часть с проблемой, которая на первый взгляд казалась такой тривиальной!
Задача состояла в том, чтобы реализовать временную шкалу, которую можно масштабировать по горизонтали. Просто!
Везде, где мышь расположена горизонтально вдоль временной шкалы, следует удерживать линию, в которой она находится при масштабировании, а временная линия должна отклоняться от этой точки. Тем не менее, относительно просто на поверхности!
Сложная часть, как я обнаружил, заключалась в манипулировании длиной линии и значениями временной шкалы, когда она масштабировалась относительно относительных значений в пикселях в виджете, и обновлением полосы прокрутки относительно любого происходящего увеличения и смещения.
Это изображение иллюстрирует задачу:
Обзор изображения проблемы
Реализация была в Qt AND C ++, однако проблема и мой вопрос больше касаются процесса решения проблемы. (Извините мои неверные теги).
Мой вопрос:
(A) Как бы вы решили эту проблему, чтобы прийти к решению и реализации.
(B) Как бы вы подошли к «изучению» шагов для решения этой и подобных проблем.
Спасибо,
Если я смогу прояснить проблему, дайте мне знать (возможно, проблема в том, чтобы сообщить о проблеме :))
Вам необходимо переопределить «масштабирование события» и рассчитать новые диапазоны и один шаг.
class ZoomSlider : public QSlider
{
Q_OBJECT
public:
explicit ZoomSlider(QWidget *parent = Q_NULLPTR) : QSlider(parent) {}
protected:
void wheelEvent(QWheelEvent *event)
{
// Calculate x, y and z from event
setRange(x, y);
setSingleStep(z);
}
};
Если ваш слайдер имеет ширину W
и текущий диапазон [w1, w2]
, будучи мышкой в положении wm
дано w1 <= wm <= w2
,
Учитывая, что вы хотите увеличить / уменьшить на процент 10%
каждый.
#define ZOOM_RATIO 0.1
Если увеличить, новый диапазон [i1,i2]
меньше, так i1>w1
а также i2<w2
:
i1 = wm - ( wm - w1 ) * ( 1.0 - ZOOM_RATIO );
i2 = wm - ( wm - w2 ) * ( 1.0 - ZOOM_RATIO );
Когда вы уменьшаете:
i1 = wm - ( wm - w1 ) * ( 1.0 + ZOOM_RATIO );
i2 = wm - ( wm - w2 ) * ( 1.0 + ZOOM_RATIO );
После этого вам нужно проверить действительность нового диапазона: то есть обрезать диапазон, чтобы быть внутри [0, wmax]
,
Будьте уверены, что вы используете double
за wm, w1, w2, i1, i2
, Или, по крайней мере, что вы конвертируете в удвоение перед выполнением вычислений.