Получение размера / ширины полосы прокрутки в PyQt5? - PullRequest
0 голосов
/ 27 января 2019

Скажем, у вас есть полоса прокрутки PyQt5:

pyqt5scrollbar

Я бы хотел программно найти ширину полосы прокрутки "thumb" (правка: называется«Ползунок» в http://pyqt.sourceforge.net/Docs/PyQt4/qscrollbar.html),, а также его местоположение; я думаю, что пиксели были бы «естественными» единицами для этого на первый взгляд.

На рисунке выше я бы предположил, что start - этовсегда 0 - но могу ли я, и если да, то как, получить значения для left, right, width (хотя, если у нас есть left и right, width тривиально right-leftend в пикселях?

Я знаю, что существуют QScrollBar .value(), pageStep() и singleStep(), но я не могу точно сказать, относятся ли они к вышеуказанным измерениям впикселей.

(Если нужен пример PyQt5 с полосами прокрутки, см., например, код, который я разместил в Есть ли у вкладок фокус на колесе мыши над ними в прокрутке PyQt5? )

1 Ответ

0 голосов
/ 28 января 2019

В этом случае вы должны использовать метод subControlRect () класса QStyle () для получения прямоугольников, из которых вы можете получить необходимую информацию.

В следующем примере я создал собственный классQScrollBar, который выдает эту информацию через сигнал каждый раз, когда изменяется положение ползунка или изменяется размер QScrollBar.

from PyQt5 import QtCore, QtGui, QtWidgets

class Scrollbar(QtWidgets.QScrollBar):
    geometryChanged = QtCore.pyqtSignal(int, int, int, int, int)

    def __init__(self, parent=None):
        super(Scrollbar, self).__init__(parent)
        self.sliderMoved.connect(self.calculate_geometry)

    def resizeEvent(self, event):
        self.calculate_geometry()
        super(Scrollbar, self).resizeEvent(event)

    def calculate_geometry(self):
        opt = QtWidgets.QStyleOptionSlider()
        self.initStyleOption(opt)
        gr = self.style().subControlRect(QtWidgets.QStyle.CC_ScrollBar, opt,
            QtWidgets.QStyle.SC_ScrollBarGroove, self)
        sr = self.style().subControlRect(QtWidgets.QStyle.CC_ScrollBar, opt,
            QtWidgets.QStyle.SC_ScrollBarSlider, self)

        start = gr.left() if self.orientation() == QtCore.Qt.Horizontal else gr.top()
        left = sr.left() if self.orientation() == QtCore.Qt.Horizontal else sr.top()
        right = sr.right() if self.orientation() == QtCore.Qt.Horizontal else sr.bottom()
        width = sr.width() if self.orientation() == QtCore.Qt.Horizontal else sr.height()
        end = gr.right() if self.orientation() == QtCore.Qt.Horizontal else gr.bottom()
        self.geometryChanged.emit(start, left, width, right, end)

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        hlayv = QtWidgets.QHBoxLayout()
        hlayv.addWidget(QtWidgets.QLabel("start: "))
        self._start_label_v = QtWidgets.QLabel()
        hlayv.addWidget(self._start_label_v)
        hlayv.addWidget(QtWidgets.QLabel("left: "))
        self._left_label_v = QtWidgets.QLabel()
        hlayv.addWidget(self._left_label_v)
        hlayv.addWidget(QtWidgets.QLabel("width: "))
        self._width_label_v = QtWidgets.QLabel()
        hlayv.addWidget(self._width_label_v)
        hlayv.addWidget(QtWidgets.QLabel("right: "))
        self._right_label_v = QtWidgets.QLabel()
        hlayv.addWidget(self._right_label_v)
        hlayv.addWidget(QtWidgets.QLabel("end: "))
        self._end_label_v = QtWidgets.QLabel()
        hlayv.addWidget(self._end_label_v)

        hlayh = QtWidgets.QHBoxLayout()
        hlayh.addWidget(QtWidgets.QLabel("start: "))
        self._start_label_h = QtWidgets.QLabel()
        hlayh.addWidget(self._start_label_h)
        hlayh.addWidget(QtWidgets.QLabel("left: "))
        self._left_label_h = QtWidgets.QLabel()
        hlayh.addWidget(self._left_label_h)
        hlayh.addWidget(QtWidgets.QLabel("width: "))
        self._width_label_h = QtWidgets.QLabel()
        hlayh.addWidget(self._width_label_h)
        hlayh.addWidget(QtWidgets.QLabel("right: "))
        self._right_label_h = QtWidgets.QLabel()
        hlayh.addWidget(self._right_label_h)
        hlayh.addWidget(QtWidgets.QLabel("end: "))
        self._end_label_h = QtWidgets.QLabel()
        hlayh.addWidget(self._end_label_h)

        self.scrollarea = QtWidgets.QScrollArea()
        content_widget = QtWidgets.QLabel()
        content_widget.setStyleSheet('''background-color : red;''')
        content_widget.setFixedSize(1000, 1000)
        self.scrollarea.setWidget(content_widget)
        hscrollbar = Scrollbar()
        hscrollbar.geometryChanged.connect(self.on_vertical_geometryChanged)
        self.scrollarea.setHorizontalScrollBar(hscrollbar)
        self.scrollarea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

        vscrollbar =Scrollbar()
        self.scrollarea.setVerticalScrollBar(vscrollbar)
        vscrollbar.geometryChanged.connect(self.on_horizontal_geometryChanged)
        self.scrollarea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)

        vlay = QtWidgets.QVBoxLayout(self)
        vlay.addWidget(QtWidgets.QLabel("<b>Vertical: </b>"))
        vlay.addLayout(hlayv)
        vlay.addWidget(QtWidgets.QLabel("<b>Horizontal: </b>"))
        vlay.addLayout(hlayh)
        vlay.addWidget(self.scrollarea)

    @QtCore.pyqtSlot(int, int, int, int, int)
    def on_vertical_geometryChanged(self, start, left, width, right, end):
        self._start_label_v.setNum(start)
        self._left_label_v.setNum(left)
        self._width_label_v.setNum(width)
        self._right_label_v.setNum(right)
        self._end_label_v.setNum(end)

    QtCore.pyqtSlot(int, int, int, int, int)
    def on_horizontal_geometryChanged(self, start, left, width, right, end):
        self._start_label_h.setNum(start)
        self._left_label_h.setNum(left)
        self._width_label_h.setNum(width)
        self._right_label_h.setNum(right)
        self._end_label_h.setNum(end)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
...