Я делаю программное обеспечение с поверхностью рисования, которая представляет график (например, функция sin) (дочерний элемент QWidget), и я хотел бы, чтобы QScrollBar действовал как QScrollArea. Так что, если мой виджет для рисования показывает 750 точек (мой график состоит из точек), но есть 1000 точек, я бы хотел, чтобы ползунок прокрутки занимал 75% доступного пространства.
Я не могу использовать QScrollArea, потому что прокрутка пропорциональна размеру содержащегося в нем виджета. В моем случае, прокрутка должна быть пропорциональна количеству точек на экране. Я знаю, как получить мой коэффициент, но я не знаю, как правильно настроить QScrollBar
Пример: я отредактировал значение PageStep, но я не понимаю, как это работает. Я могу установить pageStep на 100 с диапазоном [0,99], и он заполнит половину QScrollBar.
Мой интерфейс:
QWidget (Vertical Layout) //Main Widget
Drawing Surface (Child of QWidget)
QScrollBar (Horizontal)
Ну, я думаю, что я могу сделать что-то с этим:
http://harmattan-dev.nokia.com/docs/library/html/qt4/qscrollbar.html
Взаимосвязь между длиной документа, диапазоном значений, используемых в полосе прокрутки, и шагом страницы проста во многих распространенных ситуациях. Диапазон значений полосы прокрутки определяется путем вычитания выбранного шага страницы из некоторого значения, представляющего длину документа. В таких случаях полезно следующее уравнение: длина документа = максимум () — минимум () + pageStep ().
Таким образом, в моем случае длина — это число точек, и я могу установить в минимуме () значение 0. Итак, как вы можете видеть на рисунке, сделать что-то вроде QScrollArea. Соотношение: PercentageVisible = PageStep / Length, а другое уравнение равно Length = PageStep + Max.
У меня есть два уравнения, два пропущенных значения (PageStep и Maximum) и два известных значения (PercentageVisible и Length).
Пример: у меня 1024 точки, но показаны только 75% из них.
0,75 = PageStep / 1024 ———-> PageStep = 768
1024 = Макс. + 768 —————-> Макс. = 256
Вы можете попробовать это в своем программном обеспечении, и оно будет работать. Я знаю, что не так уж много людей должны воспроизводить это, потому что QScrollArea выполнит эту работу в большинстве случаев.
Например, этот код находится в слоте, реагирующем на событие изменения размера:
ui.sbarRange->setPageStep(u64SampleCount * dRatio);
ui.sbarRange->setMaximum(u64SampleCount - ui.sbarRange->pageStep());
Вы можете создать новый подкласс QWidget и переопределить sizeHint
а также paintEvent
, в paintEvent
ты можешь использовать event->rect()
определить, какая область в настоящее время выставлена и должна быть нарисована. Обратите внимание, что paintEvent
должен быть быстрым, если вы не хотите, чтобы ваше окно зависало. Также вам нужно поместить созданный виджет в QScrollArea
,
Вот простой пример, который рисует синусоиду:
class SinWidget : public QWidget {
public:
QSize sizeHint() const {
return QSize(10000, 200);
}
void paintEvent(QPaintEvent* event) {
QPainter painter(this);
for(int x = event->rect().left(); x <= event->rect().right(); x++) {
painter.drawPoint(x, 100.0 + qSin(0.05 * x) * 20.0);
}
}
};
QScrollArea area;
area.setWidget(new SinWidget());
area.show();
Этот пример будет хорошо работать с очень большим размером виджета (например, 100 000 пикселей). Так что полного перерисовки или выделения памяти не происходит. Вам нужно только сохранить свой paintEvent
быстро.