0

我无法找到 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_())
4

1 回答 1

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

我添加了一个resizeEvent也可以在第一次显示时以及在小部件的任何调整大小期间正确放置指示器。

于 2012-07-18T20:30:57.117 回答