PyQt5如何判断scrollArea的滚动条是否可见?
How to determine whether the scrollbar of scrollArea is visible in PyQt5?
嗯。题目看起来很简单,但是我得到的结果和我想的不一样。
我有一个应用程序,其高度取决于其内容。这是 auto-resize 代码:
def resizeApp(self):
n = len(self.listOfWidgets)
if self.screenHEIGHT - 40 > n * 125 + 50:
self.resize(self.width(), n * 125 + 50)
self.scrollArea.resize(self.scrollArea.width(), n * 125 + 20)
else:
self.resize(self.width(), self.screenHEIGHT - 40)
self.scrollArea.resize(self.scrollArea.width(), self.screenHEIGHT - 40 - 30)
print(self.scrollArea.verticalScrollBar().isVisible())
可以看到resize后我们可以定义verticalScrollbar的可见性。查看应用程序和控制台屏幕截图。我们可以看到该应用程序有 verticalScrollbar,但控制台说它没有。 isVisible() 似乎有点滞后并告诉我之前的状态。
例如。当我添加小部件时,虽然没有 verticalScrollbar,但控制台显示 False(verticalScrollbar 不可见)。当小部件数量需要 verticalScrollbar 时,scrollArea 创建此 verticalScrollbar,但是我收到消息说 verticalScrollbar 不可见。后来,在添加了一个小部件之后,我收到消息说 verticalScrollbar 是可见的。
反之亦然。当我删除小部件时,我收到一条消息,提示在删除另一个小部件后 verticalScrollbar 可见。但是它应该说我 "False" 早了一步。
我是不是漏掉了什么?
UPDATE1. 根据要求,我添加了一个没有冗余代码的工作示例。您可以从我的保管箱下载 zip 存档 >here<
假设您覆盖了 QScrollArea class,那么您只需设置它的策略,就像这样:
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
通过这种方式,您可以选择要查看的任何栏、何时查看以及查看哪一个,只需在需要时设置这些策略即可。
这是我前段时间做过的 QScrollArea,对我来说完全有效:
"""It takes care of the scroll area with slides."""
# !/usr/bin/python
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QPoint
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QScrollArea
class ScrollArea(QScrollArea):
"""ScrollArea is a personalized scroll area."""
initial_pos = QPoint()
pressed = False
def __init__(self, parent=None):
"""Init UI."""
super(ScrollArea, self).__init__(parent)
self.init_ui()
def init_ui(self):
"""Init all ui object requirements."""
self.setFixedWidth(200)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setStyleSheet("""
QScrollArea{
background-color:transparent;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
border: 0px solid ;
border-color: rgb(0,0,0,100)
}
QScrollBar:vertical{
border:1px solid;
border-color: rgb(197,197,199,100);
width: 7px;
margin: 0px 0px 0px 0px;
background: rgb(234,234,234,100);
}
QScrollBar::handle:vertical {
background: rgba(14,65,148,100);
}
QScrollBar::add-line:vertical{
height: 0px;
}
QScrollBar::sub-line:vertical{
height: 0px;
}
""")
self.setWidgetResizable(True)
def mousePressEvent(self, event):
"""Update initial click location of scroll area."""
self.pressed = True
self.initial_pos = self.verticalScrollBar().value() + event.pos().y()
def mouseReleaseEvent(self, event):
"""Update next location to be used in scroll area location."""
self.pressed = False
self.initial_pos = self.verticalScrollBar().value()
def mouseMoveEvent(self, event):
"""Update value location of scroll area according to init location."""
if self.pressed:
self.verticalScrollBar().setValue(
self.initial_pos - event.pos().y())
在尝试应用许多不同的解决方案之后,我找到了最简单的一个。这个不是最合适的,但是它解决了我的问题。
如果我有两个代码分支,它们确定小部件高度并取决于内部小部件的数量,因此我可以预测何时需要滚动条。这就是为什么我们可以在 "if" 的这两个分支中更改主要小部件的宽度。以下是调整大小功能的更改方式:
def resizeApp(self):
n = len(self.listOfWidgets)
if self.screenHEIGHT - 40 > n * 125 + 50:
self.resize(135, n * 125 + 50)
self.scrollArea.resize(self.scrollArea.width(), n * 125 + 20)
else:
self.resize(150, self.screenHEIGHT - 40)
self.scrollArea.resize(self.scrollArea.width(), self.screenHEIGHT - 40 - 30)
就是这样!
嗯。题目看起来很简单,但是我得到的结果和我想的不一样。
我有一个应用程序,其高度取决于其内容。这是 auto-resize 代码:
def resizeApp(self):
n = len(self.listOfWidgets)
if self.screenHEIGHT - 40 > n * 125 + 50:
self.resize(self.width(), n * 125 + 50)
self.scrollArea.resize(self.scrollArea.width(), n * 125 + 20)
else:
self.resize(self.width(), self.screenHEIGHT - 40)
self.scrollArea.resize(self.scrollArea.width(), self.screenHEIGHT - 40 - 30)
print(self.scrollArea.verticalScrollBar().isVisible())
可以看到resize后我们可以定义verticalScrollbar的可见性。查看应用程序和控制台屏幕截图。我们可以看到该应用程序有 verticalScrollbar,但控制台说它没有。 isVisible() 似乎有点滞后并告诉我之前的状态。
例如。当我添加小部件时,虽然没有 verticalScrollbar,但控制台显示 False(verticalScrollbar 不可见)。当小部件数量需要 verticalScrollbar 时,scrollArea 创建此 verticalScrollbar,但是我收到消息说 verticalScrollbar 不可见。后来,在添加了一个小部件之后,我收到消息说 verticalScrollbar 是可见的。
反之亦然。当我删除小部件时,我收到一条消息,提示在删除另一个小部件后 verticalScrollbar 可见。但是它应该说我 "False" 早了一步。
我是不是漏掉了什么?
UPDATE1. 根据要求,我添加了一个没有冗余代码的工作示例。您可以从我的保管箱下载 zip 存档 >here<
假设您覆盖了 QScrollArea class,那么您只需设置它的策略,就像这样:
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
通过这种方式,您可以选择要查看的任何栏、何时查看以及查看哪一个,只需在需要时设置这些策略即可。
这是我前段时间做过的 QScrollArea,对我来说完全有效:
"""It takes care of the scroll area with slides."""
# !/usr/bin/python
# -*- coding: utf-8 -*-
from PyQt5.QtCore import QPoint
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QScrollArea
class ScrollArea(QScrollArea):
"""ScrollArea is a personalized scroll area."""
initial_pos = QPoint()
pressed = False
def __init__(self, parent=None):
"""Init UI."""
super(ScrollArea, self).__init__(parent)
self.init_ui()
def init_ui(self):
"""Init all ui object requirements."""
self.setFixedWidth(200)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setStyleSheet("""
QScrollArea{
background-color:transparent;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
border: 0px solid ;
border-color: rgb(0,0,0,100)
}
QScrollBar:vertical{
border:1px solid;
border-color: rgb(197,197,199,100);
width: 7px;
margin: 0px 0px 0px 0px;
background: rgb(234,234,234,100);
}
QScrollBar::handle:vertical {
background: rgba(14,65,148,100);
}
QScrollBar::add-line:vertical{
height: 0px;
}
QScrollBar::sub-line:vertical{
height: 0px;
}
""")
self.setWidgetResizable(True)
def mousePressEvent(self, event):
"""Update initial click location of scroll area."""
self.pressed = True
self.initial_pos = self.verticalScrollBar().value() + event.pos().y()
def mouseReleaseEvent(self, event):
"""Update next location to be used in scroll area location."""
self.pressed = False
self.initial_pos = self.verticalScrollBar().value()
def mouseMoveEvent(self, event):
"""Update value location of scroll area according to init location."""
if self.pressed:
self.verticalScrollBar().setValue(
self.initial_pos - event.pos().y())
在尝试应用许多不同的解决方案之后,我找到了最简单的一个。这个不是最合适的,但是它解决了我的问题。
如果我有两个代码分支,它们确定小部件高度并取决于内部小部件的数量,因此我可以预测何时需要滚动条。这就是为什么我们可以在 "if" 的这两个分支中更改主要小部件的宽度。以下是调整大小功能的更改方式:
def resizeApp(self):
n = len(self.listOfWidgets)
if self.screenHEIGHT - 40 > n * 125 + 50:
self.resize(135, n * 125 + 50)
self.scrollArea.resize(self.scrollArea.width(), n * 125 + 20)
else:
self.resize(150, self.screenHEIGHT - 40)
self.scrollArea.resize(self.scrollArea.width(), self.screenHEIGHT - 40 - 30)
就是这样!