gpt4 book ai didi

python - 如何将固定标题添加到 QScrollArea?

转载 作者:太空宇宙 更新时间:2023-11-04 01:36:23 42 4
gpt4 key购买 nike

我目前有一个 QScrollArea 定义为:

self.results_grid_scrollarea = QScrollArea()
self.results_grid_widget = QWidget()
self.results_grid_layout = QGridLayout()
self.results_grid_layout.setSizeConstraint(QLayout.SetMinAndMaxSize)
self.results_grid_widget.setLayout(self.results_grid_layout)
self.results_grid_scrollarea.setWidgetResizable(True)
self.results_grid_scrollarea.setWidget(self.results_grid_widget)
self.results_grid_scrollarea.setViewportMargins(0,20,0,0)

它很高兴地嵌套在其他布局/小部件中,按预期调整大小等。

为了为网格列提供标题,我使用了另一个位于滚动区域正上方的 QGridLayout - 这有效......但看起来有点奇怪,即使样式适当,特别是当按需(垂直)滚动条时根据需要出现或消失,标题不再与网格列正确对齐。我知道这是一件审美的事情……但我有点挑剔 ;)

其他小部件在其他地方以编程方式添加/删除到 self.results_grid_layout。上面的最后一行是我最近添加的,因为我认为使用创建的边距区域会很容易,docs对于 setViewportMargins 状态:

Sets margins around the scrolling area. This is useful for applications such as spreadsheets with "locked" rows and columns. The marginal space is is left blank; put widgets in the unused area.

但我终其一生都无法弄清楚如何真正实现这一目标,要么我的 GoogleFu 今天抛弃了我,要么关于如何实际实现这一目标的信息/示例很少。

我的头脑告诉我,我可以只分配一个由布局(包含任意数量的其他小部件)控制的小部件到滚动区域 - 正如我所做的那样。如果我将 QHeaderview 添加到网格布局的第 0 行,它会出现在视口(viewport)的边距下方并与布局的其余部分一起滚动吗?还是我遗漏了什么,只见树木不见森林?

我只是在学习 Python/Qt,所以任何帮助、指示和/或示例(最好使用 Python 但不是必需的)将不胜感激!


编辑:按照目前给出的建议(我认为),我提出了以下小测试程序来尝试:

import sys
from PySide.QtCore import *
from PySide.QtGui import *

class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setMinimumSize(640, 480)

self.container_widget = QWidget()
self.container_layout = QVBoxLayout()
self.container_widget.setLayout(self.container_layout)
self.setCentralWidget(self.container_widget)

self.info_label = QLabel(
"Here you can see the problem.... I hope!\n"
"Once the window is resized everything behaves itself.")
self.info_label.setWordWrap(True)

self.headings_widget = QWidget()
self.headings_layout = QGridLayout()
self.headings_widget.setLayout(self.headings_layout)
self.headings_layout.setContentsMargins(1,1,0,0)

self.heading_label1 = QLabel("Column 1")
self.heading_label1.setContentsMargins(16,0,0,0)
self.heading_label2 = QLabel("Col 2")
self.heading_label2.setAlignment(Qt.AlignCenter)
self.heading_label2.setMaximumWidth(65)
self.heading_label3 = QLabel("Column 3")
self.heading_label3.setContentsMargins(8,0,0,0)
self.headings_layout.addWidget(self.heading_label1,0,0)
self.headings_layout.addWidget(self.heading_label2,0,1)
self.headings_layout.addWidget(self.heading_label3,0,2)
self.headings_widget.setStyleSheet(
"background: green; border-bottom: 1px solid black;" )

self.grid_scrollarea = QScrollArea()
self.grid_widget = QWidget()
self.grid_layout = QGridLayout()
self.grid_layout.setSizeConstraint(QLayout.SetMinAndMaxSize)
self.grid_widget.setLayout(self.grid_layout)
self.grid_scrollarea.setWidgetResizable(True)
self.grid_scrollarea.setWidget(self.grid_widget)
self.grid_scrollarea.setViewportMargins(0,30,0,0)
self.headings_widget.setParent(self.grid_scrollarea)
### Add some linedits to the scrollarea just to test
rows_to_add = 10
## Setting the above to a value greater than will fit in the initial
## window will cause the lineedits added below to display correctly,
## however - using the 10 above, the lineedits do not expand to fill
## the scrollarea's width until you resize the window horizontally.
## What's the best way to fix this odd initial behaviour?
for i in range(rows_to_add):
col1 = QLineEdit()
col2 = QLineEdit()
col2.setMaximumWidth(65)
col3 = QLineEdit()
row = self.grid_layout.rowCount()
self.grid_layout.addWidget(col1,row,0)
self.grid_layout.addWidget(col2,row,1)
self.grid_layout.addWidget(col3,row,2)
### Define Results group to hold the above sections
self.test_group = QGroupBox("Results")
self.test_layout = QVBoxLayout()
self.test_group.setLayout(self.test_layout)
self.test_layout.addWidget(self.info_label)
self.test_layout.addWidget(self.grid_scrollarea)
### Add everything to the main layout
self.container_layout.addWidget(self.test_group)


def resizeEvent(self, event):
scrollarea_vpsize = self.grid_scrollarea.viewport().size()
scrollarea_visible_size = self.grid_scrollarea.rect()
desired_width = scrollarea_vpsize.width()
desired_height = scrollarea_visible_size.height()
desired_height = desired_height - scrollarea_vpsize.height()
new_geom = QRect(0,0,desired_width+1,desired_height-1)
self.headings_widget.setGeometry(new_geom)


def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
app.exec_()

if __name__ == '__main__':
main()

这些是您所指的方法吗?一切都按预期工作,这正是我所追求的,除了在用户调整窗口大小之前的一些奇怪的初始行为,一旦调整大小,一切都会排列起来并且很好。我可能又想多了,或者至少忽略了一些事情……有什么想法吗?

最佳答案

我遇到了类似的问题,但解决方法略有不同。而不是使用一个 QScrollArea我使用两个并将较低滚动区域的移动转发到顶部。下面的代码是做什么的

  1. 它在 QVBoxLayout 中创建两个 QScrollArea 小部件。
  2. 它禁用顶部 QScrollArea 的滚动条的可见性并为其分配一个固定的高度。
  3. 使用valueChanged较低 QScrollArea 的水平滚动条的信号可以将水平滚动条值从较低 QScrollArea“转发”到顶部,从而在窗口顶部产生一个固定的标题。

class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)

widget = QWidget()
self.setCentralWidget(widget)

vLayout = QVBoxLayout()
widget.setLayout(vLayout)

# TOP
scrollAreaTop = QScrollArea()
scrollAreaTop.setWidgetResizable(True)
scrollAreaTop.setFixedHeight(30)
scrollAreaTop.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scrollAreaTop.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scrollAreaTop.setWidget(QLabel(" ".join([str(i) for i in range(100)])))

# BOTTOM
scrollAreaBottom = QScrollArea()
scrollAreaBottom.setWidgetResizable(True)
scrollAreaBottom.setWidget(QLabel("\n".join([" ".join([str(i) for i in range(100)]) for _ in range(10)])))
scrollAreaBottom.horizontalScrollBar().valueChanged.connect(lambda value: scrollAreaTop.horizontalScrollBar().setValue(value))

vLayout.addWidget(scrollAreaTop)
vLayout.addWidget(scrollAreaBottom)

Window resulting from above code.

关于python - 如何将固定标题添加到 QScrollArea?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9378894/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com