Python中定制QScrollbar

2024-05-19 06:22:06 发布

您现在位置:Python中文网/ 问答频道 /正文

通常PyQt的默认QScrollBar对于高dpi显示来说太小了。这就是为什么有必要对它们进行调整。不管怎样,一旦你做到了,为什么不从你能做出的美学改进中获益呢?在

这就是如何调整QScrollBar的“外观”的方法:

########################################
#     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 ###

我找到了以下有关如何设置样式表的文档:

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

问题:

在定制了QScrollBars之后,它们可以完美地工作。但当用户点击手柄或箭头时,不会得到任何视觉反馈。例如,单击箭头将不会导致箭头被按下的视觉反馈。在

下面是一个示例,说明应该如何:

enter image description here


Tags: marginselfinit箭头widthgreybackgroundheight
2条回答

我不知道如何使用样式表来实现它。在

我创建了三个qss文件。在

a.qss公司

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

b.qss公司

^{pr2}$

c.qss公司

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


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

代码:

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

我在学英语,希望你不要介意。在

实际上,您可以使用^{},但它也要求您对滚动条进行子类化。 在下面的示例中,我完全实现了垂直滚动条,您只需填充水平滚动条的基本css部分。在

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)

相关问题 更多 >

    热门问题