请考虑以下代码:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class Gallery(QScrollArea):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setFixedWidth(175)
self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Expanding)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# Set widget and layout
self._scroll_widget = QWidget()
self._layout = QVBoxLayout()
self._layout.setContentsMargins(0, 0, 0, 0)
self._layout.setSpacing(25)
self._scroll_widget.setLayout(self._layout)
self.setWidget(self._scroll_widget)
self.setWidgetResizable(True)
# Stretch
self._layout.addStretch(1) # Stretch above widgets
self._layout.addStretch(1) # Stretch below widgets
# Initialize ---------------------------------|
for _ in range(10):
self.add_item()
def resizeEvent(self, event: QResizeEvent) -> None:
super().resizeEvent(event)
# Calculate Margins --------------------|
children = self._scroll_widget.findChildren(QLabel)
first_widget = children[0]
last_widget = children[-1]
self._layout.setContentsMargins(
0,
int(event.size().height() / 2 - first_widget.size().height() / 2),
0,
int(event.size().height() / 2 - last_widget.size().height() / 2)
)
def add_item(self) -> None:
widget = QLabel()
widget.setStyleSheet('background: #22FF88')
widget.setFixedSize(90, 125)
child_count = len(
self._scroll_widget.findChildren(QLabel)
)
self._layout.insertWidget(1 + child_count, widget,
alignment=Qt.AlignCenter)
if __name__ == '__main__':
app = QApplication([])
window = Gallery()
window.show()
app.exec()
当前,布局的边距是动态设置的,因此,无论窗口大小如何,第一个和最后一个项目始终垂直居中:
我现在想要实现的是,每当我滚动(通过鼠标滚轮或箭头键,因为滚动条被禁用)时,下一个小部件应该位于垂直中心的位置,也就是说,我想将滚动模式从每像素切换到每小部件,这样无论我滚动多远,我永远不会在两个小部件之间着陆
如何做到这一点
我发现QAbstractItemView提供了将ScrollMode切换到ScrollPerItem的选项,尽管我不确定这是否是我所需要的,因为我在尝试子类化QAbstractItemView时有点不知所措
编辑:
这显示了我在改编@musicamante的答案后注意到的延迟:
这并不是真正的破坏,但我在更大的项目中看不到它,所以我想有些东西并没有按它应该的方式工作
由于QScrollArea提供的大部分功能实际上都将被忽略,因此从中进行子类化并不会带来很多好处。相反,它可能使事情变得更加复杂
此外,使用布局也不是很有用:小部件的“容器”不受滚动区域的限制,在这种情况下,所有大小提示和调整大小的功能几乎都是无用的
一个解决方案可以是将所有项目设置为“滚动区域”的子项,甚至可以是基本的QWidget或QFrame,但为了更好地支持样式,我选择使用QAbstractScrollArea
诀窍是根据每个子部件的几何图形计算其正确位置。请注意,我假设所有小部件都有一个固定的大小,否则您可能需要使用它们的sizeHint、minimumSizeHint或minimum sizeHint,并检查它们的大小策略
下面是一个可能的实现(为了正确显示结果,我更改了项的创建):
相关问题 更多 >
编程相关推荐