Python 具有固定尺寸的滚动区域
我很抱歉这个标题,但我无法更好地解释这个话题 我有一个带有gridlayout的scrollarea,它的行数和列数可变。在网格的每个单元格中,我都有一个QLabel。 我希望scrollarea的视口有一个固定的大小,因此我可以只查看一定数量的标签,而不使用滚动条。 相反,在这段代码中,我查看所有标签,如果它们的数量可变,它们总是插入到视口的空间中,并且其尺寸发生更改 我应该在不更改self.scrollArea.setWidgetResizeable(False)行的情况下执行此操作,因为如果将其设置为True,我正在实现的缩放系统将无法工作 可能吗Python 具有固定尺寸的滚动区域,python,pyqt5,qlabel,qscrollarea,Python,Pyqt5,Qlabel,Qscrollarea,我很抱歉这个标题,但我无法更好地解释这个话题 我有一个带有gridlayout的scrollarea,它的行数和列数可变。在网格的每个单元格中,我都有一个QLabel。 我希望scrollarea的视口有一个固定的大小,因此我可以只查看一定数量的标签,而不使用滚动条。 相反,在这段代码中,我查看所有标签,如果它们的数量可变,它们总是插入到视口的空间中,并且其尺寸发生更改 我应该在不更改self.scrollArea.setWidgetResizeable(False)行的情况下执行此操作,因为如
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如何处理所有这些(广泛而复杂的)方面,我建议您阅读更多关于和的内容,并使用更简单的案例进行更多的实验,甚至使用
以下修改要求将widgetResizeable
属性设置为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)
我建议您更小心使用空格,在逗号之后(以及在等号周围)应始终使用空格,以提高可读性。阅读更多有关官方的信息。我不确定我是否理解你的要求。这些“标签”是否总是具有相同的大小(可能基于缩放级别)?你能提供一些显示预期结果的图片吗?同样,考虑将要添加到布局中的小部件的几何形状是完全没有用的,因为布局无论如何都会覆盖该几何图形。谢谢!我只是想了解当我们必须指定不同小部件的大小时,它们之间的交互。我可以在评论中发布图片吗?或者我必须修改主消息吗?这是一个非常广泛的主题,在处理滚动区域时会变得非常复杂。基本概念是布局管理器完全按照他们的名字做:他们管理项目的布局、大小和位置,同时考虑可能的约束(最小/最大大小)、大小提示(首选大小)和策略(如何通过布局调整小部件的大小)。这就是为什么设置几何体是毫无意义的:布局负责这一点。如果您想要固定大小,请使用
setFixedSize()
。然后,您会说“如果设置为True,我正在实现的缩放系统将无法工作”。什么“变焦系统”?我建议您澄清您正在做什么以及需要实现什么,如果“缩放系统”是强制性的,您应该向我们解释它的功能、方式和原因(可能通过扩展代码)。如果要提供图像,请将其添加到帖子中;您目前的声誉不允许您嵌入它们,但其他用户可以编辑它以显示它。我只是在研究GUI,所以现在对我来说更重要的是如何工作。如果我将此值设置为true,我将得到所需的布局(图像的左侧),但它无法调整大小。因此,我的第一个问题是:是否有一种方法可以通过使用内容小部件的某些属性而不是布局的标志来获得左侧的布局?因为我不了解这种布局行为,这对我来说很重要,如果我想了解这些库,而不仅仅是让应用程序工作。谢谢你,我会研究你答案中的所有链接。也谢谢你的风格建议:)@Nunkij非常欢迎你。记住,如果一个答案解决了你的问题,你应该点击左边的灰色勾号,将其标记为已接受(这是获得声誉的众多方法之一,这也会给你更多特权,比如发布图片;请参见)。正如你所见,我是这个网站的新手,我不知道这个功能。我将尽快测试代码,以便单击按钮:)再次感谢!