Как задать разные ширины колонок у QTreeView
У меня есть QTreeView и мне надо чтобы он был на всю ширину окна.
Есть ли возможность задать первой колонке мин возможную ширину, а остальных растянуть по всей ширине?
main.py
from PyQt5 import QtCore, QtGui, QtWidgets
datas = {
"Category 1": [
("New Game 2", "Playnite", "", "", "Never", "Not Played", ""),
("New Game 3", "Playnite", "", "", "Never", "Not Played", ""),
],
"No Category": [
("New Game", "Playnite", "", "", "Never", "Not Plated", ""),
]
}
class GroupDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super(GroupDelegate, self).__init__(parent)
self._plus_icon = QtGui.QIcon('data/images/plus.png')
self._minus_icon = QtGui.QIcon('data/images/minus.png')
def initStyleOption(self, option, index):
super(GroupDelegate, self).initStyleOption(option, index)
if not index.parent().isValid():
is_open = bool(option.state & QtWidgets.QStyle.State_Open)
option.features |= QtWidgets.QStyleOptionViewItem.HasDecoration
option.icon = self._minus_icon if is_open else self._plus_icon
class GroupView(QtWidgets.QTreeView):
def __init__(self, model, parent=None):
super(GroupView, self).__init__(parent)
self.setIndentation(0)
self.setExpandsOnDoubleClick(False)
self.clicked.connect(self.on_clicked)
delegate = GroupDelegate(self)
self.setItemDelegateForColumn(0, delegate)
self.setModel(model)
self.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.setStyleSheet("background-color: #0D1225;")
@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_clicked(self, index):
if not index.parent().isValid() and index.column() == 0:
self.setExpanded(index, not self.isExpanded(index))
class GroupModel(QtGui.QStandardItemModel):
def __init__(self, parent=None):
super(GroupModel, self).__init__(parent)
self.setColumnCount(8)
self.setHorizontalHeaderLabels(["", "Name", "Library", "Release Date", "Genre(s)", "Last Played", "Time Played", ""])
for i in range(self.columnCount()):
it = self.horizontalHeaderItem(i)
it.setForeground(QtGui.QColor("#F2F2F2"))
def add_group(self, group_name):
item_root = QtGui.QStandardItem()
item_root.setEditable(False)
item = QtGui.QStandardItem(group_name)
item.setEditable(False)
ii = self.invisibleRootItem()
i = ii.rowCount()
for j, it in enumerate((item_root, item)):
ii.setChild(i, j, it)
ii.setEditable(False)
for j in range(self.columnCount()):
it = ii.child(i, j)
if it is None:
it = QtGui.QStandardItem()
ii.setChild(i, j, it)
it.setBackground(QtGui.QColor("#002842"))
it.setForeground(QtGui.QColor("#F2F2F2"))
return item_root
def append_element_to_group(self, group_item, texts):
j = group_item.rowCount()
print(j)
'''
item_icon = QtGui.QStandardItem()
item_icon.setEditable(False)
item_icon.setIcon(QtGui.QIcon("game.png"))
item_icon.setBackground(QtGui.QColor("#0D1225"))
group_item.setChild(j, 0, item_icon)
'''
for i, text in enumerate(texts):
item = QtGui.QStandardItem(text)
item.setEditable(False)
item.setBackground(QtGui.QColor("#0D1225"))
item.setForeground(QtGui.QColor("#F2F2F2"))
group_item.setChild(j, i+1, item)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
model = GroupModel(self)
tree_view = GroupView(model)
self.setCentralWidget(tree_view)
for group, childrens in datas.items():
group_item = model.add_group(group)
for children in childrens:
model.append_element_to_group(group_item, children)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(720, 240)
w.show()
sys.exit(app.exec_())
Ответы (2 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте заменить строку:
self.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
на строки:
self.setColumnWidth(0, 20)
self.header().setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(4, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(5, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(6, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(7, QtWidgets.QHeaderView.Stretch)
self.setFocusPolicy(QtCore.Qt.NoFocus)
main.py
from PyQt5 import QtCore, QtGui, QtWidgets
datas = {
"Category 1": [
("New Game 2", "Playnite", "", "", "Never", "Not Played", ""),
("New Game 3", "Playnite", "", "", "Never", "Not Played", ""),
],
"No Category": [
("New Game", "Playnite", "", "", "Never", "Not Plated", ""),
]
}
class GroupDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None):
super(GroupDelegate, self).__init__(parent)
self._plus_icon = QtGui.QIcon('Ok.png') # ('data/images/plus.png')
self._minus_icon = QtGui.QIcon('ball.png') # ('data/images/minus.png')
def initStyleOption(self, option, index):
super(GroupDelegate, self).initStyleOption(option, index)
if not index.parent().isValid():
is_open = bool(option.state & QtWidgets.QStyle.State_Open)
option.features |= QtWidgets.QStyleOptionViewItem.HasDecoration
option.icon = self._minus_icon if is_open else self._plus_icon
class GroupView(QtWidgets.QTreeView):
def __init__(self, model, parent=None):
super(GroupView, self).__init__(parent)
self.setIndentation(0)
self.setExpandsOnDoubleClick(False)
self.clicked.connect(self.on_clicked)
delegate = GroupDelegate(self)
self.setItemDelegateForColumn(0, delegate)
self.setModel(model)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
#- self.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.setColumnWidth(0, 20)
self.header().setSectionResizeMode(1, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(2, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(4, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(5, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(6, QtWidgets.QHeaderView.Stretch)
self.header().setSectionResizeMode(7, QtWidgets.QHeaderView.Stretch)
self.setFocusPolicy(QtCore.Qt.NoFocus)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.setStyleSheet("background-color: #0D1225;")
@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_clicked(self, index):
if not index.parent().isValid() and index.column() == 0:
self.setExpanded(index, not self.isExpanded(index))
class GroupModel(QtGui.QStandardItemModel):
def __init__(self, parent=None):
super(GroupModel, self).__init__(parent)
self.setColumnCount(8)
self.setHorizontalHeaderLabels(["", "Name", "Library", "Release Date", "Genre(s)", "Last Played", "Time Played", ""])
for i in range(self.columnCount()):
it = self.horizontalHeaderItem(i)
# it.setForeground(QtGui.QColor("#F2F2F2"))
def add_group(self, group_name):
item_root = QtGui.QStandardItem()
item_root.setEditable(False)
item = QtGui.QStandardItem(group_name)
item.setEditable(False)
ii = self.invisibleRootItem()
i = ii.rowCount()
for j, it in enumerate((item_root, item)):
ii.setChild(i, j, it)
ii.setEditable(False)
for j in range(self.columnCount()):
it = ii.child(i, j)
if it is None:
it = QtGui.QStandardItem()
ii.setChild(i, j, it)
it.setBackground(QtGui.QColor("#002842"))
it.setForeground(QtGui.QColor("#F2F2F2"))
return item_root
def append_element_to_group(self, group_item, texts):
j = group_item.rowCount()
print(j)
'''
item_icon = QtGui.QStandardItem()
item_icon.setEditable(False)
item_icon.setIcon(QtGui.QIcon("game.png"))
item_icon.setBackground(QtGui.QColor("#0D1225"))
group_item.setChild(j, 0, item_icon)
'''
for i, text in enumerate(texts):
item = QtGui.QStandardItem(text)
item.setEditable(False)
item.setBackground(QtGui.QColor("#0D1225"))
item.setForeground(QtGui.QColor("#F2F2F2"))
group_item.setChild(j, i+1, item)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
model = GroupModel(self)
tree_view = GroupView(model)
self.setCentralWidget(tree_view)
for group, childrens in datas.items():
group_item = model.add_group(group)
for children in childrens:
model.append_element_to_group(group_item, children)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(720, 240)
w.show()
sys.exit(app.exec_())
Автор решения: Alexander Chernin
→ Ссылка
После строки:
self.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
Добавьте вот эти две:
self.header().setSectionResizeMode(0, QtWidgets.QHeaderView.Fixed)
self.header().resizeSection(0, 25)
