跟踪QScrollBar的中心

时间:2012-07-17 22:35:08

标签: qt pyqt pyqt4 pyside

我无法找到QScrollBar滑块的正确中心(我需要将文本小部件粘贴到它上面以显示滑块的位置)。我尝试通过将滑块的位置除以文档宽度来标准化滑块的位置,然后按它的宽度()缩放它。但这并不准确,因为滚动条的装饰和按钮没有被考虑在内。所以标签在你拖动时会徘徊,不会粘在中心。 下面是我当前的代码,它不知何故需要考虑QScrollBar的按钮,框架等,以找到滚动区域的正确开始和结束位置。 有人可以帮忙吗?

import sys
from PySide.QtGui import *
from PySide.QtCore import *

class PageScroller(QScrollBar):
    '''Set the total number of pages.'''
    def __init__(self, parent=None):
        super(PageScroller, self).__init__(parent)

        self.pageIndicator = QLabel('|', parent)
        self.valueChanged.connect(self.updateSlider)
        self.setOrientation(Qt.Orientation.Horizontal)
        self.setPageStep(1)

    def updateSlider(self, event):
        scrollAreaWidth = self.maximum() - self.minimum() + self.pageStep()
        sliderPos = (self.sliderPosition() + self.pageStep()/2.0) / float(scrollAreaWidth) * self.width()
        indicatorPos = QPoint(sliderPos - self.pageIndicator.width()/2, -self.pageIndicator.height())
        self.pageIndicator.move(self.mapToParent(indicatorPos))

        self.update()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    #app.setStyle('plastique') # tyhis makes the sliding more obvious
    mainWindow = QWidget()
    layout = QVBoxLayout(mainWindow)
    s = PageScroller(mainWindow)
    layout.addWidget(s)
    mainWindow.resize(400, 100)
    mainWindow.show()


    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:1)

正如您所发现的那样,要正确映射滑块部分的像素范围,同时考虑平台之间的各种样式差异,这将非常困难。太多因素(左侧和右侧的额外按钮,滑块尺寸本身,......)

这真的很模糊,需要一些搜索才能找到它,但实际上你需要查询QScrollBar的SubControl。您可以获得的是滚动句柄的QRect:

def resizeEvent(self, event):
    super(PageScroller, self).resizeEvent(event)
    self.updateSlider()

def updateSlider(self, val=None):
    opt = QStyleOptionSlider()
    self.initStyleOption(opt)
    style = self.style()
    handle = style.subControlRect(style.CC_ScrollBar, opt, 
                                    style.SC_ScrollBarSlider)
    sliderPos = handle.center()
    sliderPos.setY(-self.pageIndicator.height())
    self.pageIndicator.move(self.mapToParent(sliderPos))
  1. 您首先必须创建一个空的QStyleOptionSlider,并使用PageScroller的当前状态填充它。
  2. 然后您必须从PageScroller获取样式,并使用subControlRect查询ComplexControl ScrollBar类型的子控件,SubControl ScrollBarSlider类型。它使用opts返回滑块的QRect
  3. 然后您可以正常映射并移动pageIndicator
  4. 我添加了一个resizeEvent,以便在第一次显示时以及在小部件的任何调整大小期间正确放置指示符。