python - 具有固定尺寸的滚动区域
问题描述
我很抱歉标题,但我不能以更好的方式解释这个话题。
我有一个带有 gridlayout 的滚动区域,它具有可变数量的行和列。在网格的每个单元格中,我都有一个 QLabel。我希望滚动区域的视口具有固定大小,因此我可以在不使用滚动条的情况下仅查看一定数量的标签。相反,在这段代码中,我查看了所有标签,如果它们的数量变化,它们总是插入到视口空间中,并且它们的尺寸发生了变化。
我应该在不更改 self.scrollArea.setWidgetResizable(False) 行的情况下执行此操作,因为如果设置为 True,我正在实施的缩放系统将不起作用。
可能吗?
import sys
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtWidgets import ( QVBoxLayout, QHBoxLayout, QGridLayout, QApplication, QMainWindow,
QLabel, QWidget, QPushButton, QScrollArea
)
class MyScrollingArea(QWidget):
def __init__(self, parent=None):
super(MyScrollingArea).__init__()
self.vertLayout = QVBoxLayout()
self.vertLayout.setContentsMargins(0, 0, 0, 0)
self.vertLayout.setSpacing(0)
self.gridLayout = QGridLayout()
self.gridContainer = QWidget()
self.scrollArea = QScrollArea()
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scrollArea.setWidgetResizable(False)
self.scrollArea.setWidget(self.gridContainer)
self.populate( )
buttonsArea=self.zoomMenu()
self.gridContainer.setLayout(self.gridLayout )
self.vertLayout.addWidget(self.scrollArea)
self.vertLayout.addWidget(buttonsArea)
self.setLayout(self.vertLayout )
def zoomMenu(self):
widButtonFooter = QWidget()
layButtonFooter = QHBoxLayout()
widButtonFooter.setLayout(layButtonFooter)
butZommMinus = QPushButton("-")
butZommPlus = QPushButton("+")
layButtonFooter.addWidget(butZommMinus)
layButtonFooter.addWidget(butZommPlus)
return widButtonFooter
def populate(self):
colors = ( "navy","green", "magenta","cyan", "yellow","red", "orange", "blue","purple", "gold","silver", "lightblue", "lime" )
for row in range(0,10):
for col in range (0,20):
self.addLabel(row,col,colors[row])
def addLabel(self,row,col,color):
label = MyLabel(row,col,80,100,color,str(row) + "." + str(col))
self.gridLayout.addWidget(label,row,col)
def resizeEvent(self, event):
self.gridContainer.resize(self.width(), self.height())
super(MyScrollingArea, self).resizeEvent(event)
class MyLabel(QLabel):
def __init__(self,row,col, w, h, color, text):
super().__init__()
self.color=color
self.setStyleSheet("border:10px solid " + self.color + ";")
self.setText(text)
self.setAlignment(Qt.AlignCenter)
self.setGeometry(QRect(0, 0, w, h))
def mousePressEvent(self,QMouseEvent):
if QMouseEvent.button() == Qt.LeftButton:
self.setStyleSheet("background-color:" + self.color + ";")
elif QMouseEvent.button() == Qt.RightButton:
self.setStyleSheet("border:10px solid " + self.color + ";")
class MyGrid(QMainWindow):
def __init__(self):
super().__init__()
self.resize(1000, 800)
self.saScrollMeasureBox = MyScrollingArea()
widPanelMeasure = QWidget()
layvPanelMeasure = QVBoxLayout()
widPanelMeasure.setLayout(layvPanelMeasure)
layvPanelMeasure.addWidget(self.saScrollMeasureBox)
self.setCentralWidget(widPanelMeasure)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyGrid()
window.show()
app.exec_()
解决方案
布局管理器没有特定的尺寸,只有尺寸提示,可能还有最小和/或最大尺寸,所有这些都基于它包含的项目,使用它们的尺寸提示、约束和策略。
在要添加到布局的小部件上设置几何图形是没有意义的,因为布局管理它们的大小和位置。解决方案是setFixedSize
改用。
由于如果有剩余空间,布局也会自动调整小部件的位置(并且它们都无法扩展其大小),因此您可以在布局的末尾添加一个拉伸以确保它们始终保持相同的间距即使边缘有更多可用空间。对于盒装布局,使用 就足够了addStretch()
,但对于网格布局,您必须指定特定行和列的拉伸。
为了更好地理解 Qt 是如何处理所有这些(广泛而复杂的)方面的,我建议您阅读更多关于提示和策略、QSizePolicy和布局管理的内容,并使用更简单的案例进行更多实验,甚至使用Designer。
以下修改要求将该widgetResizable
属性设置为True
。
class MyScrollingArea(QWidget):
# ...
def populate(self):
colors = (
"navy", "green", "magenta", "cyan", "yellow", "red", "orange",
"blue", "purple", "gold", "silver", "lightblue", "lime"
)
rows = 10
columns = 20
for row in range(rows):
for col in range (columns):
self.addLabel(row, col, colors[row])
self.gridLayout.setColumnStretch(columns, 1)
self.gridLayout.setRowStretch(rows, 1)
class MyLabel(QLabel):
def __init__(self, row, col, w, h, color, text):
super().__init__()
self.color = color
self.setStyleSheet("border:10px solid " + self.color + ";")
self.setText(text)
self.setAlignment(Qt.AlignCenter)
self.setFixedSize(w, h)
我建议您对空格更加小心,在逗号后面(以及等号周围)应始终使用空格,以提高可读性。阅读更多关于 Python 代码的官方样式指南。
推荐阅读
- javascript - 无法在 html 和 css 中正确设置 ul 和 li
- opengl - (openGL) 是否应该避免处理不存在的制服?
- agora.io - 是否可以通过 agora.io 在 Unity(Android、iOS)[不是 1 对 1] 中进行广播?
- c++ - 有没有办法提高涉及 const 表达式的编译速度?
- docker - 如何根据 rabbitmq 队列消息率缩放 k8s pod?
- python - 如何将自定义 css 代码添加到由 python Bokeh、save() 生成的独立 HTML 文件中?
- python - 在列表中生成字符串元素的组合,将它们限制为特定的字符数量
- bash - 如何使用多次出现的相同模式?
- javascript - OnCreate 函数未触发但 OnWrite 函数触发
- android - 安卓可以接IOS蓝牙信号吗