首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在QScrollbar中自定义PyQt

在QScrollbar中自定义PyQt
EN

Stack Overflow用户
提问于 2016-07-26 08:18:59
回答 2查看 2.9K关注 0票数 1

通常,来自PyQt的默认QScrollBar太小,不适合高dpi显示。这就是为什么有必要调整它们。一旦你做好了,为什么不从你所能做的美感中获益呢?

您可以这样调整QScrollBar的“外观和感觉”:

代码语言:javascript
复制
########################################
#     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之后,它们完美地工作了。但是,用户在单击句柄或箭头时不会得到任何视觉反馈。例如,单击箭头将不会产生箭头已被按下的视觉反馈。

下面是一个应该如何做到的例子:

EN

回答 2

Stack Overflow用户

发布于 2016-07-27 07:54:10

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

我创建了三个qss文件。

a.qss

代码语言:javascript
复制
    QScrollBar:vertical{
    background: black;
    width: 10px;
}

b.qss

代码语言:javascript
复制
    QScrollBar:vertical{
    background: black;
    width: 10px;
}


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

c.qss

代码语言:javascript
复制
    QScrollBar:vertical{
    background: black;
    width: 10px;
}


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

守则如下:

代码语言:javascript
复制
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

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

票数 1
EN

Stack Overflow用户

发布于 2018-01-15 19:33:33

您实际上可以使用QStyle.hitTestComplexControl(),但它也要求您对滚动条进行子类。在下面的示例中,我完全实现了垂直滚动条,您只需填写水平滚动条的基本css部分即可。

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38584550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档