Python 在PyQt中自定义QScrollbar
通常,PyQt的默认QScrollBar对于高dpi显示来说太小。这就是为什么有必要调整它们。不管怎样,一旦你做到了,为什么不从你所能做的美学改进中获益呢 这就是如何调整QScrollBar的“外观和感觉”:Python 在PyQt中自定义QScrollbar,python,qt,pyqt,pyqt5,Python,Qt,Pyqt,Pyqt5,通常,PyQt的默认QScrollBar对于高dpi显示来说太小。这就是为什么有必要调整它们。不管怎样,一旦你做到了,为什么不从你所能做的美学改进中获益呢 这就是如何调整QScrollBar的“外观和感觉”: ######################################## # My custom QScrollArea # # widget # ######################
########################################
# 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 ###
我找到了以下关于如何设置样式表的文档:
d
问题:
定制QScrollBars后,它们可以完美地工作。但是用户在单击手柄或箭头时不会得到任何视觉反馈。例如,单击箭头不会产生按下箭头的视觉反馈
下面是一个示例,说明应该如何:
我不知道如何使用样式表来实现它 我创建了三个qss文件 a、 qss
QScrollBar:vertical{
background: black;
width: 10px;
}
b、 qss
c、 qss
以及守则:
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
class Main(QScrollArea):
定义初始化(自):
超级(主,自).\uuuu初始化
自我调整大小(300200)
self.index=QWidget()
自索引设置最小高度(1000)
自索引设置最小宽度(500)
self.setWidget(self.index)
self.setWidgetResizeable(True)
以开放式('a.qss','r')作为f:
self.a_text=f.read()
self.setStyleSheet(self.a_文本)
以开放式('b.qss','r')作为f:
self.b_text=f.read()
以开放式('c.qss','r')作为f:
self.c_text=f.read()
#保存值。
self.value=0
self.pre_值=0
#保存暂停条件。
self.paussecond=True
self.timer=QTimer()
self.timer.timeout.connect(self.timerout)
self.verticalScrollBar().actionTriggered.connect(self.change)
自动定时器启动(300)
def更改(自我):
#如果滑动滑块(单击并用鼠标单击皮带轮)。
self.value=self.verticalScrollBar().sliderPosition()
#如果向下/向右滑动。
如果self.pre_值self.value:
self.setStyleSheet(self.c_文本)
self.pre_value=self.verticalScrollBar().sliderPosition()
self.paussecond=True
def时间路由(自身):
如果不是self.paussecond:
返回1
#如果单击或停止皮带轮。
如果self.verticalScrollBar().sliderPosition()==self.value:
self.setStyleSheet(self.a_文本)
self.paussecond=False
我正在学习英语,希望你不要介意。我不知道如何使用样式表来实现它 我创建了三个qss文件 a、 qss
QScrollBar:vertical{
background: black;
width: 10px;
}
b、 qss
c、 qss
以及守则:
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
class Main(QScrollArea):
定义初始化(自):
超级(主,自).\uuuu初始化
自我调整大小(300200)
self.index=QWidget()
自索引设置最小高度(1000)
自索引设置最小宽度(500)
self.setWidget(self.index)
self.setWidgetResizeable(True)
以开放式('a.qss','r')作为f:
self.a_text=f.read()
self.setStyleSheet(self.a_文本)
以开放式('b.qss','r')作为f:
self.b_text=f.read()
以开放式('c.qss','r')作为f:
self.c_text=f.read()
#保存值。
self.value=0
self.pre_值=0
#保存暂停条件。
self.paussecond=True
self.timer=QTimer()
self.timer.timeout.connect(self.timerout)
self.verticalScrollBar().actionTriggered.connect(self.change)
自动定时器启动(300)
def更改(自我):
#如果滑动滑块(单击并用鼠标单击皮带轮)。
self.value=self.verticalScrollBar().sliderPosition()
#如果向下/向右滑动。
如果self.pre_值self.value:
self.setStyleSheet(self.c_文本)
self.pre_value=self.verticalScrollBar().sliderPosition()
self.paussecond=True
def时间路由(自身):
如果不是self.paussecond:
返回1
#如果单击或停止皮带轮。
如果self.verticalScrollBar().sliderPosition()==self.value:
self.setStyleSheet(self.a_文本)
self.paussecond=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)
您实际上可以使用,但它也要求您对滚动条进行子类化。
在下面的示例中,我完全实现了垂直滚动条,您只需填写水平滚动条的基本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)
我非常怀疑你是否能用样式表来实现它。单击箭头时,样式表无法更改滚动条句柄的状态。为此,您可能必须对QScrollBar进行子类化,然后自己绘制。我非常怀疑您是否可以使用样式表来实现它。单击箭头时,样式表无法更改滚动条句柄的状态。为此,您可能需要对QScrollBar进行子类化,并自己绘制。非常感谢!我明天会试试看:-)非常感谢!明天我将尝试测试它:-)