Как правильно переопределить высоту строк и ширину столбцов в QTableView с помощью QAbstractTableModel?
У меня 5 столбцов (5 из которых скрыты), и в среднем я могу содержать до 5000 записей. Количество записей уже ставит крест на любом resizeToContent.
Для удобства в программе используется моноширинный шрифт. Но очень важно подстроиться под текущий размер окна.
Для контекста я создаю таблицу для отображения журналов. Первые два столбца имеют самые длинные строки: «00:00:00» и «КРИТИЧЕСКИЙ». Для третьего столбца я должен использовать либо сам заголовок, либо, если есть модуль (в модели данных есть метод получения списка уникальных модулей), длиннее заголовка, использовать его. Четвертый столбец, основное сообщение журнала, должен растягиваться по ширине и иметь перенос строки, что, в свою очередь, должно изменить высоту строки.
Таким образом, записи добавляются в реальном времени, и их нужно сразу отрисовывать на необходимой высоте, чтобы избежать рывков.
# screens/journal/frontend/log_table_widget.py
from PySide6.QtWidgets import (
QWidget, QVBoxLayout,
QTableView, QAbstractItemView
)
from PySide6.QtCore import Qt, Slot, Signal, Property
from PySide6.QtGui import QColor
from ..models.log_table_model import LogTableModel
from ..models.log_filter_proxy import LogFilterProxy
from ..models.log_search import LogSearch
from .filter_header import FilterHeaderView
class LogTableWidget(QWidget):
filter_requested = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
self._source_model: LogTableModel | None = None
self._proxy_model: LogFilterProxy | None = None
self._search: LogSearch | None = None
self.colors = {}
self._table: QTableView | None = None
self._setup_ui()
@Property(QColor)
def debug_color(self): return self.colors.get("DEBUG",QColor())
@debug_color.setter
def debug_color(self,value):
self.colors["DEBUG"] = value
@Property(QColor)
def info_color(self): return self.colors.get("INFO",QColor())
@info_color.setter
def info_color(self,value):
self.colors["INFO"] = value
@Property(QColor)
def warning_color(self): return self.colors.get("WARNING",QColor())
@warning_color.setter
def warning_color(self,value):
self.colors["WARNING"] = value
@Property(QColor)
def error_color(self): return self.colors.get("ERROR",QColor())
@error_color.setter
def error_color(self,value):
self.colors["ERROR"] = value
@Property(QColor)
def critical_color(self): return self.colors.get("CRITICAL",QColor())
@critical_color.setter
def critical_color(self,value):
self.colors["CRITICAL"] = value
def _setup_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self._table = self._create_table()
layout.addWidget(self._table)
def _create_table(self) -> QTableView:
table = QTableView()
table.setObjectName("LogTableView")
table.setShowGrid(False)
table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
table.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
table.setSortingEnabled(True)
header = FilterHeaderView(Qt.Orientation.Horizontal, table)
header.filter_requested.connect(self.filter_requested)
header.setSectionsMovable(False)
header.setSectionsClickable(True)
table.setHorizontalHeader(header)
table.verticalHeader().setVisible(False)
table.setAlternatingRowColors(True)
table.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
table.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
return table
def set_models(
self,
source_model: LogTableModel,
proxy_model: LogFilterProxy,
search: LogSearch
):
self._source_model = source_model
self._proxy_model = proxy_model
self._search = search
self._table.setModel(self._proxy_model)
self._table.sortByColumn(
LogFilterProxy.COL_TIME,
Qt.SortOrder.DescendingOrder
)
self._table.setColumnHidden(LogFilterProxy.COL_LINE, True)
self._connect_signals()
def _connect_signals(self):
if self._source_model is None or self._proxy_model is None:
return
self._source_model.rowsInserted.connect(self._on_rows_inserted)
@Slot()
def _on_rows_inserted(self):
pass
@Slot()
def _on_filter_applied(self):
pass
@Slot(int)
def select_row(self, proxy_row: int):
if proxy_row < 0 or self._proxy_model is None:
return
index = self._proxy_model.index(proxy_row, 0)
self._table.selectRow(proxy_row)
self._table.scrollTo(index, QAbstractItemView.ScrollHint.PositionAtCenter)
def scroll_to_bottom(self):
if self._proxy_model is None:
return
row_count = self._proxy_model.rowCount()
if row_count > 0:
self._table.selectRow(row_count-1)
self._table.scrollTo(self._proxy_model.index(row_count-1,0))
def scroll_to_top(self):
if self._proxy_model is None:
return
if self._proxy_model.rowCount() > 0:
self._table.selectRow(0)
self._table.scrollTo(self._proxy_model.index(0,0))
Подробнее здесь: https://stackoverflow.com/questions/798 ... qtableview
Как переопределить sizeHint для QTableView? ⇐ Python
Программы на Python
-
Anonymous
1769591070
Anonymous
Как правильно переопределить высоту строк и ширину столбцов в QTableView с помощью QAbstractTableModel?
У меня 5 столбцов (5 из которых скрыты), и в среднем я могу содержать до 5000 записей. Количество записей уже ставит крест на любом resizeToContent.
Для удобства в программе используется моноширинный шрифт. Но очень важно подстроиться под текущий размер окна.
Для контекста я создаю таблицу для отображения журналов. Первые два столбца имеют самые длинные строки: «00:00:00» и «КРИТИЧЕСКИЙ». Для третьего столбца я должен использовать либо сам заголовок, либо, если есть модуль (в модели данных есть метод получения списка уникальных модулей), длиннее заголовка, использовать его. Четвертый столбец, основное сообщение журнала, должен растягиваться по ширине и иметь перенос строки, что, в свою очередь, должно изменить высоту строки.
Таким образом, записи добавляются в реальном времени, и их нужно сразу отрисовывать на необходимой высоте, чтобы избежать рывков.
# screens/journal/frontend/log_table_widget.py
from PySide6.QtWidgets import (
QWidget, QVBoxLayout,
QTableView, QAbstractItemView
)
from PySide6.QtCore import Qt, Slot, Signal, Property
from PySide6.QtGui import QColor
from ..models.log_table_model import LogTableModel
from ..models.log_filter_proxy import LogFilterProxy
from ..models.log_search import LogSearch
from .filter_header import FilterHeaderView
class LogTableWidget(QWidget):
filter_requested = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
self._source_model: LogTableModel | None = None
self._proxy_model: LogFilterProxy | None = None
self._search: LogSearch | None = None
self.colors = {}
self._table: QTableView | None = None
self._setup_ui()
@Property(QColor)
def debug_color(self): return self.colors.get("DEBUG",QColor())
@debug_color.setter
def debug_color(self,value):
self.colors["DEBUG"] = value
@Property(QColor)
def info_color(self): return self.colors.get("INFO",QColor())
@info_color.setter
def info_color(self,value):
self.colors["INFO"] = value
@Property(QColor)
def warning_color(self): return self.colors.get("WARNING",QColor())
@warning_color.setter
def warning_color(self,value):
self.colors["WARNING"] = value
@Property(QColor)
def error_color(self): return self.colors.get("ERROR",QColor())
@error_color.setter
def error_color(self,value):
self.colors["ERROR"] = value
@Property(QColor)
def critical_color(self): return self.colors.get("CRITICAL",QColor())
@critical_color.setter
def critical_color(self,value):
self.colors["CRITICAL"] = value
def _setup_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self._table = self._create_table()
layout.addWidget(self._table)
def _create_table(self) -> QTableView:
table = QTableView()
table.setObjectName("LogTableView")
table.setShowGrid(False)
table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
table.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
table.setSortingEnabled(True)
header = FilterHeaderView(Qt.Orientation.Horizontal, table)
header.filter_requested.connect(self.filter_requested)
header.setSectionsMovable(False)
header.setSectionsClickable(True)
table.setHorizontalHeader(header)
table.verticalHeader().setVisible(False)
table.setAlternatingRowColors(True)
table.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
table.setHorizontalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
return table
def set_models(
self,
source_model: LogTableModel,
proxy_model: LogFilterProxy,
search: LogSearch
):
self._source_model = source_model
self._proxy_model = proxy_model
self._search = search
self._table.setModel(self._proxy_model)
self._table.sortByColumn(
LogFilterProxy.COL_TIME,
Qt.SortOrder.DescendingOrder
)
self._table.setColumnHidden(LogFilterProxy.COL_LINE, True)
self._connect_signals()
def _connect_signals(self):
if self._source_model is None or self._proxy_model is None:
return
self._source_model.rowsInserted.connect(self._on_rows_inserted)
@Slot()
def _on_rows_inserted(self):
pass
@Slot()
def _on_filter_applied(self):
pass
@Slot(int)
def select_row(self, proxy_row: int):
if proxy_row < 0 or self._proxy_model is None:
return
index = self._proxy_model.index(proxy_row, 0)
self._table.selectRow(proxy_row)
self._table.scrollTo(index, QAbstractItemView.ScrollHint.PositionAtCenter)
def scroll_to_bottom(self):
if self._proxy_model is None:
return
row_count = self._proxy_model.rowCount()
if row_count > 0:
self._table.selectRow(row_count-1)
self._table.scrollTo(self._proxy_model.index(row_count-1,0))
def scroll_to_top(self):
if self._proxy_model is None:
return
if self._proxy_model.rowCount() > 0:
self._table.selectRow(0)
self._table.scrollTo(self._proxy_model.index(0,0))
Подробнее здесь: [url]https://stackoverflow.com/questions/79877771/how-to-redefine-sizehint-for-qtableview[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия