2012-07-17 37 views
0

我很难找到QScrollBar的滑块的正确中心(我需要粘贴一个文本小部件来显示滑块的位置)。我试着通过将滑动条的位置除以文档宽度来标准化滑块的位置,然后通过它的width()来缩放它。但这并不准确,因为滚动条的装饰和按钮没有被考虑在内。所以当你拖动标签时,标签就会徘徊,不会坚持到中心。 下面是我目前的代码,它需要考虑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

这将是真的很难,就像你已经发现,要正确映射滑块部分的像素范围,同时考虑平台之间的各种风格的差异。太多的因素(上左,右,滑块本身的大小,额外的按钮......)

这实在是不起眼的,这需要一个比较费事找出来,但实际上你需要查询的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类型的子控件。它使用选择使您返回滑块的QRect
  3. 然后你就可以对应为正常移动pageIndicator

我添加了一个resizeEvent也恰当地放置在首秀的指标,在​​对任何尺寸调整小部件。

+0

谢谢。我必须添加'None'作为style.subControlRect()的第四个参数,因为一些样式似乎期望一个widget作为第四个控件(不太确定原因)。尽管偏移量有点不同(有时它位于中心,有时略偏离边),但现在这种方式跟不同样式的轨迹要好得多。但我可以忍受这一点。谢谢! – 2012-07-18 23:10:42