2016-07-26 28 views
0

Normalerweise sind die Standard-QScrollBars von PyQt zu klein für hohe dpi-Anzeigen. Deshalb kann es notwendig sein, sie anzupassen. Und wenn Sie es trotzdem tun, warum nicht von den ästhetischen Verbesserungen profitieren, die Sie machen können?Anpassen der QScrollbar in PyQt

Dies ist, wie man das 'Look and Feel' Ihrer QScrollBar zwicken:

######################################## 
#  My custom QScrollArea   # 
#  widget       # 
######################################## 

class MyScrollArea(QScrollArea): 

    def __init__(self, parent): 
     super(MyScrollArea, self).__init__(parent) 
     ... 

     self.setStyleSheet("""QScrollBar:vertical { 
        width: 45px; 
        margin: 45px 0 45px 0; 
        background: #32CC99; 
        } 

        QScrollBar::handle:vertical { 
        border: 10px solid grey; 
        background: white; 
        min-height: 10px; 
        } 

        QScrollBar::add-line:vertical { 
        border: 2px solid grey; 
        background: none; 
        height: 45px; 
        subcontrol-position: bottom; 
        subcontrol-origin: margin; 
        } 

        QScrollBar::sub-line:vertical { 
        border: 2px solid grey; 
        background: none; 
        height: 45px; 
        subcontrol-position: top; 
        subcontrol-origin: margin; 
        } 

        QScrollBar::up-arrow:vertical { 
        border: 5px solid grey; 
        height: 40px; 
        width: 40px 
        } 

        QScrollBar::down-arrow:vertical { 
        border: 5px solid grey; 
        height: 40px; 
        width: 40px        
        }""") 
     ... 

    ### End init ### 

### End Class ### 

ich die folgende Dokumentation gefunden, wie die Stylesheet-Setup:

http://doc.qt.io/qt-4.8/stylesheet-examples.html#customizing-qscrollbar d

DAS PROBLEM:

Nach der Anpassung der QS CrollBars, sie funktionieren perfekt. Der Benutzer erhält jedoch kein visuelles Feedback, wenn er entweder auf den Griff oder auf die Pfeile klickt. Wenn Sie zum Beispiel auf den Pfeil klicken, wird nicht die visuelle Rückmeldung angezeigt, dass der Pfeil gedrückt wurde. Hier

ist ein Beispiel dafür, wie es sein sollte:

enter image description here

+0

Ich bezweifle sehr, wenn Sie es mit Style Sheets erreichen können. StyleSheets können den Status des Bildlaufleisten-Griffs nicht ändern, wenn Sie auf den Pfeil klicken. Dazu müssen Sie möglicherweise die QScrollBar ableiten und selbst malen. – Marcus

Antwort

1

Ich weiß nicht, wie Stylesheets verwenden, um es zu erreichen.

Ich habe drei qss-Dateien erstellt.

a.qss

QScrollBar:vertical{ 
    background: black; 
    width: 10px; 
} 

b.qss

QScrollBar:vertical{ 
    background: black; 
    width: 10px; 
} 


QScrollBar::add-page:vertical{ 
    background: red; 
} 

c.qss

QScrollBar:vertical{ 
    background: black; 
    width: 10px; 
} 


QScrollBar::sub-page:vertical{ 
    background: red; 
} 

und der Code:

class Main(QScrollArea): 

    def __init__(self): 

     super(Main, self).__init__() 

     self.resize(300, 200) 

     self.index = QWidget() 
     self.index.setMinimumHeight(1000) 
     self.index.setMinimumWidth(500) 


     self.setWidget(self.index) 
     self.setWidgetResizable(True) 

     with open('a.qss', 'r') as f: 
      self.a_text = f.read() 
      self.setStyleSheet(self.a_text) 
     with open('b.qss', 'r') as f: 
      self.b_text = f.read() 
     with open('c.qss', 'r') as f: 
      self.c_text = f.read() 

     # save values. 
     self.value = 0 
     self.pre_value = 0 

     # save pause condition. 
     self.pauseCond = True 
     self.timer = QTimer() 

     self.timer.timeout.connect(self.timerout) 
     self.verticalScrollBar().actionTriggered.connect(self.change) 
     self.timer.start(300) 

    def change(self): 
     # if sliding the slider(click and Mouse pulley). 

     self.value = self.verticalScrollBar().sliderPosition() 

     # if sliding down/right. 
     if self.pre_value < self.value: 
      self.setStyleSheet(self.b_text) 
     # if sliding up/left. 
     elif self.pre_value > self.value: 
      self.setStyleSheet(self.c_text) 

     self.pre_value = self.verticalScrollBar().sliderPosition() 
     self.pauseCond = True 

    def timerout(self): 
     if not self.pauseCond: 
      return 1 

     # if click or pulley stop. 
     if self.verticalScrollBar().sliderPosition() == self.value: 
      self.setStyleSheet(self.a_text) 
      self.pauseCond = False 

Ich lerne Englisch, ich hoffe es stört dich nicht.

1

Sie können tatsächlich QStyle.hitTestComplexControl() verwenden, aber Sie müssen auch die Bildlaufleisten Unterklasse. Im folgenden Beispiel habe ich die vertikale Bildlaufleiste vollständig implementiert, Sie müssen nur die grundlegenden CSS-Teile des horizontalen ausfüllen.

class CustomScrollBar(QtWidgets.QScrollBar): 
    def __init__(self, *args, **kwargs): 
     QtWidgets.QScrollBar.__init__(self, *args, **kwargs) 
     self.baseSheet = ''' 
      QScrollBar {{ 
       width: 45px; 
       margin: 45px 0 45px 0; 
       background: #32CC99; 
      }} 

      QScrollBar::handle {{ 
       border: 10px solid grey; 
       background: white; 
       min-height: 10px; 
      }} 

      QScrollBar::add-line:vertical {{ 
       border: 2px solid grey; 
       background: none; 
       height: 45px; 
       subcontrol-position: bottom; 
       subcontrol-origin: margin; 
      }} 

      QScrollBar::sub-line:vertical {{ 
       border: 2px solid grey; 
       background: none; 
       height: 45px; 
       subcontrol-position: top; 
       subcontrol-origin: margin; 
      }} 

      QScrollBar::up-arrow:vertical {{ 
       subcontrol-position: bottom; 
       subcontrol-origin: margin; 
       {upArrow} 
      }} 

      QScrollBar::down-arrow:vertical {{ 
       subcontrol-position: bottom; 
       subcontrol-origin: margin; 
       {downArrow} 
      }} 

      QScrollBar::left-arrow:vertical {{ 
       subcontrol-position: bottom; 
       subcontrol-origin: margin; 
       {leftArrow} 
      }} 

      QScrollBar::right-arrow:vertical {{ 
       subcontrol-position: bottom; 
       subcontrol-origin: margin; 
       {rightArrow} 
      }} 
      ''' 
     self.arrowNormal = ''' 
       border-top: 5px solid lightgray; 
       border-left: 5px solid lightgray; 
       border-right: 5px solid gray; 
       border-bottom: 5px solid gray; 
      ''' 
     self.arrowPressed = ''' 
       border: 5px solid darkgray; 
      ''' 
     self.setStyleSheet(self.baseSheet.format(
      upArrow=self.arrowNormal, 
      downArrow=self.arrowNormal, 
      leftArrow=self.arrowNormal, 
      rightArrow=self.arrowNormal)) 

    def mousePressEvent(self, event): 
     QtWidgets.QScrollBar.mousePressEvent(self, event) 
     opt = QtWidgets.QStyleOptionSlider() 
     opt.initFrom(self) 

     subControl = self.style().hitTestComplexControl(self.style().CC_ScrollBar, opt, event.pos(), self) 
     if subControl == self.style().SC_ScrollBarAddLine: 
      if self.orientation() == QtCore.Qt.Vertical: 
       downArrow = self.arrowPressed 
       upArrow = leftArrow = rightArrow = self.arrowNormal 
      else: 
       rightArrow = self.arrowPressed 
       upArrow = downArrow = leftArrow = self.arrowNormal 
     elif subControl == self.style().SC_ScrollBarSubLine: 
      if self.orientation() == QtCore.Qt.Vertical: 
       upArrow = self.arrowPressed 
       downArrow = leftArrow = rightArrow = self.arrowNormal 
      else: 
       leftArrow = self.arrowPressed 
       rightArrow = upArrow = downArrow = self.arrowNormal 
     self.setStyleSheet(self.baseSheet.format(upArrow=upArrow, downArrow=downArrow, leftArrow=leftArrow, rightArrow=rightArrow)) 

    def mouseReleaseEvent(self, event): 
     QtWidgets.QScrollBar.mouseReleaseEvent(self, event) 
     self.setStyleSheet(self.baseSheet.format(
      upArrow=self.arrowNormal, 
      downArrow=self.arrowNormal, 
      leftArrow=self.arrowNormal, 
      rightArrow=self.arrowNormal)) 


class MyScrollArea(QtWidgets.QScrollArea): 
    def __init__(self, parent=None): 
     super(MyScrollArea, self).__init__(parent) 
     w = QtWidgets.QWidget() 
     w.setFixedSize(640, 480) 
     self.setWidget(w) 
     vScrollBar = CustomScrollBar(QtCore.Qt.Vertical) 
     self.setVerticalScrollBar(vScrollBar) 
+0

Vielen Dank! Ich werde versuchen, es morgen zu testen :-) –