QTreeView 未跨越 parent 宽度或高度
QTreeView not spanning parent width or height
所以我是 QtGui 的新手,正在查找如何做事,我发现这很简洁 example on QTreeView。当我让它自己工作时,我注意到它没有像我预期的那样填充 space:
所以我一直在寻找答案,但在 Python 或 C++ 资源中都找不到太多答案。我已经 checking the documentation 很多次了,但仍然没有完全找到我正在寻找的东西。
所以很明显有些东西没有正确的尺寸政策,但我很难弄清楚是什么。到目前为止,我已经淘汰了几个潜在候选人:
- 持有 QTreeView 实例的 QWidget 实例正确地跨越了它所在的布局(QWidget 跨越了 QGroupBox 的宽度减去一点边距)。
- 由于 QTreeView 的 parent 小部件是正确的尺寸,我认为它是 QTreeView 更本地化的东西,但是当我使用 setSizePolicy 时,我使用的 none 策略似乎解决了问题。可能有多个我不知道的步骤?
- QTreeView继承的
viewport
(来自QAbstractScrollArea比我想象的小很多。用一个新的空QWidget调用QTreeView的setViewport()
方法只会重绘non-header内容背景是灰色而不是白色,我怀疑这很接近但不是我需要看的地方。
- QTreeView 还有其他 children(除了
viewport
)我仍在调查中。
- 我尝试过的大部分内容都在下面的代码中被注释掉了。
这是我要重现的源代码:
import sys
from PySide.QtGui import *
class TreeTime(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.main_widget = QWidget()
self.main_layout = QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.statusBar()
self.make_tree()
self.show()
def make_tree(self):
# init widgets
self.tgb = QGroupBox("[Tree Group Box Title]")
self.main_layout.addWidget(self.tgb)
tgb_layout = QVBoxLayout()
self.tgb.setLayout(tgb_layout)
tgb_widget = QWidget()
tgb_layout.addWidget(tgb_widget)
debug_btn = QPushButton("DEBUG")
tgb_layout.addWidget(debug_btn)
view = QTreeView(parent=tgb_widget)
# view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
view.setSelectionBehavior(QAbstractItemView.SelectRows)
model = QStandardItemModel()
model.setHorizontalHeaderLabels(['col1', 'col2', 'col3'])
view.setModel(model)
view.setUniformRowHeights(True)
# populate data
for i in range(10):
parent1 = QStandardItem('Family {}. Some long status text for sp'.format(i))
for j in range(3):
child1 = QStandardItem('Child {}'.format(i*3+j))
child2 = QStandardItem('row: {}, col: {}'.format(i, j+1))
child3 = QStandardItem('row: {}, col: {}'.format(i, j+2))
parent1.appendRow([child1, child2, child3])
model.appendRow(parent1)
# span container columns
view.setFirstColumnSpanned(i, view.rootIndex(), True)
# expand third container
index = model.indexFromItem(parent1)
view.expand(index)
# select last row
selmod = view.selectionModel()
index2 = model.indexFromItem(child3)
selmod.select(index2, QItemSelectionModel.Select|QItemSelectionModel.Rows)
def print_debug_info():
print('')
for child in view.children():
print("child "+repr(child)) #not sure what all these are yet
print('')
print('self.main_widget.frameSize: '+repr(self.main_widget.frameSize()))
print('view.parent().parent().frameSize(): '+repr(view.parent().parent().frameSize())) #group box
# print('self.frameSize: '+repr(self.frameSize()))
print('self.tgb.frameSize: '+repr(self.tgb.frameSize()))
print('view.parent(): '+repr(view.parent()))
print('view.parent().frameSize(): '+repr(view.parent().frameSize()))
# print('view.parent().frameSize(): '+repr(view.parent().frameSize())+" (before)")
# print('view.parent().adjustSize(): '+repr(view.parent().adjustSize()))
# print('view.parent().frameSize(): '+repr(view.parent().frameSize())+" (after)")
print('view.viewport(): '+repr(view.viewport()))
print('view.viewport().frameSize(): '+repr(view.viewport().frameSize()))
# print('view.parent().parent().parent().frameSize(): '+repr(view.parent().parent().parent().frameSize()))
# print('calling setViewport: '+repr(view.setViewport(QWidget())))
# view.adjustSize()
debug_btn.clicked.connect(print_debug_info)
def sayHello(self):
self.statusBar().showMessage("Hello World!")
import time; time.sleep(2)
self.statusBar().showMessage("")
def sayWords(self, words):
self.statusBar().showMessage(words)
if __name__ == '__main__':
app = QApplication([])
tt = TreeTime()
sys.exit(app.exec_())
我正在使用 Windows 8.1 机器和 Python 3.4.3,PySide 版本 1.2.2 - 任何帮助将不胜感激! (另外,如果我遗漏了任何重要细节,请告诉我)
更新(5/19/2015):我尝试将我的 DEBUG 按钮移到 QGroupBox 之外,结果是 QTreeView 被折叠成一个完全无法辨认的大小,所以你不能'甚至告诉 object 是什么了,所以它似乎正在最小化使用的 space,即使我取消注释行:
view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
一位朋友认为这可能只是 windows 的问题,而不是我的代码,但我没有任何证据支持这一点。
2015 年 5 月 19 日更新:我已经执行了@titusjan 提供的建议,但我有相同的 problem/behavior。
您必须使用 setLayout
方法来 link 小部件的布局。所以改变...
self.main_layout = QVBoxLayout(self.main_widget)
进入
self.main_layout = QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
类似于 tgb_view
布局(为清楚起见,我将其重命名为 tgb_layout
)。
最后你忘记将树视图添加到此布局中,因此添加:
tgb_view.addWidget(view)
为了方便起见,我将所有相关的修改代码放在下面。
def initUI(self):
self.main_widget = QWidget()
self.main_layout = QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.statusBar()
self.make_tree()
self.show()
def make_tree(self):
# init widgets
self.tgb = QGroupBox("[Tree Group Box Title]")
self.main_layout.addWidget(self.tgb)
tgb_view = QVBoxLayout()
self.tgb.setLayout(tgb_view)
tgb_widget = QWidget()
tgb_view.addWidget(tgb_widget)
debug_btn = QPushButton("DEBUG")
tgb_view.addWidget(debug_btn)
view = QTreeView(parent=tgb_widget)
tgb_view.addWidget(view)
...
大小政策内容不是必需的,默认值就可以了。
您需要删除多余的 tp_widget
并将 view
添加到 tgb_layout
:
def make_tree(self):
# init widgets
self.tgb = QGroupBox("[Tree Group Box Title]")
self.main_layout.addWidget(self.tgb)
tgb_layout = QVBoxLayout()
self.tgb.setLayout(tgb_layout)
view = QTreeView()
tgb_layout.addWidget(view)
...
debug_btn = QPushButton("DEBUG")
tgb_layout.addWidget(debug_btn)
请注意,当您将小部件添加到布局时,它们将自动重新设置为布局的父级(无论何时),因此实际上没有必要在构造函数中设置一个。
另请注意:
tgb_layout = QVBoxLayout(self.tgb)
完全等同于:
tgb_layout = QVBoxLayout()
self.tgb.setLayout(tgb_layout)
因为布局将始终重新确定其所设置的小部件的父级。
所以我是 QtGui 的新手,正在查找如何做事,我发现这很简洁 example on QTreeView。当我让它自己工作时,我注意到它没有像我预期的那样填充 space:
所以我一直在寻找答案,但在 Python 或 C++ 资源中都找不到太多答案。我已经 checking the documentation 很多次了,但仍然没有完全找到我正在寻找的东西。
所以很明显有些东西没有正确的尺寸政策,但我很难弄清楚是什么。到目前为止,我已经淘汰了几个潜在候选人:
- 持有 QTreeView 实例的 QWidget 实例正确地跨越了它所在的布局(QWidget 跨越了 QGroupBox 的宽度减去一点边距)。
- 由于 QTreeView 的 parent 小部件是正确的尺寸,我认为它是 QTreeView 更本地化的东西,但是当我使用 setSizePolicy 时,我使用的 none 策略似乎解决了问题。可能有多个我不知道的步骤?
- QTreeView继承的
viewport
(来自QAbstractScrollArea比我想象的小很多。用一个新的空QWidget调用QTreeView的setViewport()
方法只会重绘non-header内容背景是灰色而不是白色,我怀疑这很接近但不是我需要看的地方。 - QTreeView 还有其他 children(除了
viewport
)我仍在调查中。 - 我尝试过的大部分内容都在下面的代码中被注释掉了。
这是我要重现的源代码:
import sys
from PySide.QtGui import *
class TreeTime(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.main_widget = QWidget()
self.main_layout = QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.statusBar()
self.make_tree()
self.show()
def make_tree(self):
# init widgets
self.tgb = QGroupBox("[Tree Group Box Title]")
self.main_layout.addWidget(self.tgb)
tgb_layout = QVBoxLayout()
self.tgb.setLayout(tgb_layout)
tgb_widget = QWidget()
tgb_layout.addWidget(tgb_widget)
debug_btn = QPushButton("DEBUG")
tgb_layout.addWidget(debug_btn)
view = QTreeView(parent=tgb_widget)
# view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
view.setSelectionBehavior(QAbstractItemView.SelectRows)
model = QStandardItemModel()
model.setHorizontalHeaderLabels(['col1', 'col2', 'col3'])
view.setModel(model)
view.setUniformRowHeights(True)
# populate data
for i in range(10):
parent1 = QStandardItem('Family {}. Some long status text for sp'.format(i))
for j in range(3):
child1 = QStandardItem('Child {}'.format(i*3+j))
child2 = QStandardItem('row: {}, col: {}'.format(i, j+1))
child3 = QStandardItem('row: {}, col: {}'.format(i, j+2))
parent1.appendRow([child1, child2, child3])
model.appendRow(parent1)
# span container columns
view.setFirstColumnSpanned(i, view.rootIndex(), True)
# expand third container
index = model.indexFromItem(parent1)
view.expand(index)
# select last row
selmod = view.selectionModel()
index2 = model.indexFromItem(child3)
selmod.select(index2, QItemSelectionModel.Select|QItemSelectionModel.Rows)
def print_debug_info():
print('')
for child in view.children():
print("child "+repr(child)) #not sure what all these are yet
print('')
print('self.main_widget.frameSize: '+repr(self.main_widget.frameSize()))
print('view.parent().parent().frameSize(): '+repr(view.parent().parent().frameSize())) #group box
# print('self.frameSize: '+repr(self.frameSize()))
print('self.tgb.frameSize: '+repr(self.tgb.frameSize()))
print('view.parent(): '+repr(view.parent()))
print('view.parent().frameSize(): '+repr(view.parent().frameSize()))
# print('view.parent().frameSize(): '+repr(view.parent().frameSize())+" (before)")
# print('view.parent().adjustSize(): '+repr(view.parent().adjustSize()))
# print('view.parent().frameSize(): '+repr(view.parent().frameSize())+" (after)")
print('view.viewport(): '+repr(view.viewport()))
print('view.viewport().frameSize(): '+repr(view.viewport().frameSize()))
# print('view.parent().parent().parent().frameSize(): '+repr(view.parent().parent().parent().frameSize()))
# print('calling setViewport: '+repr(view.setViewport(QWidget())))
# view.adjustSize()
debug_btn.clicked.connect(print_debug_info)
def sayHello(self):
self.statusBar().showMessage("Hello World!")
import time; time.sleep(2)
self.statusBar().showMessage("")
def sayWords(self, words):
self.statusBar().showMessage(words)
if __name__ == '__main__':
app = QApplication([])
tt = TreeTime()
sys.exit(app.exec_())
我正在使用 Windows 8.1 机器和 Python 3.4.3,PySide 版本 1.2.2 - 任何帮助将不胜感激! (另外,如果我遗漏了任何重要细节,请告诉我)
更新(5/19/2015):我尝试将我的 DEBUG 按钮移到 QGroupBox 之外,结果是 QTreeView 被折叠成一个完全无法辨认的大小,所以你不能'甚至告诉 object 是什么了,所以它似乎正在最小化使用的 space,即使我取消注释行:
view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
一位朋友认为这可能只是 windows 的问题,而不是我的代码,但我没有任何证据支持这一点。
2015 年 5 月 19 日更新:我已经执行了@titusjan 提供的建议,但我有相同的 problem/behavior。
您必须使用 setLayout
方法来 link 小部件的布局。所以改变...
self.main_layout = QVBoxLayout(self.main_widget)
进入
self.main_layout = QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
类似于 tgb_view
布局(为清楚起见,我将其重命名为 tgb_layout
)。
最后你忘记将树视图添加到此布局中,因此添加:
tgb_view.addWidget(view)
为了方便起见,我将所有相关的修改代码放在下面。
def initUI(self):
self.main_widget = QWidget()
self.main_layout = QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.statusBar()
self.make_tree()
self.show()
def make_tree(self):
# init widgets
self.tgb = QGroupBox("[Tree Group Box Title]")
self.main_layout.addWidget(self.tgb)
tgb_view = QVBoxLayout()
self.tgb.setLayout(tgb_view)
tgb_widget = QWidget()
tgb_view.addWidget(tgb_widget)
debug_btn = QPushButton("DEBUG")
tgb_view.addWidget(debug_btn)
view = QTreeView(parent=tgb_widget)
tgb_view.addWidget(view)
...
大小政策内容不是必需的,默认值就可以了。
您需要删除多余的 tp_widget
并将 view
添加到 tgb_layout
:
def make_tree(self):
# init widgets
self.tgb = QGroupBox("[Tree Group Box Title]")
self.main_layout.addWidget(self.tgb)
tgb_layout = QVBoxLayout()
self.tgb.setLayout(tgb_layout)
view = QTreeView()
tgb_layout.addWidget(view)
...
debug_btn = QPushButton("DEBUG")
tgb_layout.addWidget(debug_btn)
请注意,当您将小部件添加到布局时,它们将自动重新设置为布局的父级(无论何时),因此实际上没有必要在构造函数中设置一个。
另请注意:
tgb_layout = QVBoxLayout(self.tgb)
完全等同于:
tgb_layout = QVBoxLayout()
self.tgb.setLayout(tgb_layout)
因为布局将始终重新确定其所设置的小部件的父级。