Форум сайта python.su
0
Подскажите пожалуйста как у QAbstractTableModel реализовать метод setHeaderData. Второй день бьюсь, ни чего не получается.
Офлайн
0
Что конкретно нужно? Что конкретно не получается? И где конкретный код? :)
Офлайн
0
Опишу поподробней задачу. Нас интересует вертикальный заголовок QTableView - нужна простая нумерация строк по порядку, вдобавок она должна оставаться правильной при включенной сортировке по заголовку столбца. Т.е. всегда 1,2,3,4,5….100… Если делаю так как в коде ниже, получается черт знает что, а не нумерация по порядку. Я хотел создавать вертикальный заголовок в цикле уже после формирования модели в TableView, методом setHeaderData(), но насколько я понял у QAbstractTableModel этот метод не организован (нужно создавать самому), чтото типа:
def setHeaderData(self, section, orientation, value, role):
if …….:
.
.
.
model.headerDataChanged.emit(orientation, section, section)
return True
else:
return False
Вот с наполнением функции у меня полная непонятка.
В интернете не нашел ни одного примера реализации этого метода.
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
class MyWindow(QtGui.QWidget):
def __init__(self, *args):
QtGui.QWidget.__init__(self, *args)
table = self.createTable()
layout = QtGui.QVBoxLayout()
layout.addWidget(table)
self.setLayout(layout)
def createTable(self):
tv = QtGui.QTableView()
tm = MyTableModel(self)
# set the proxy model
pm = QtGui.QSortFilterProxyModel(self)
pm.setSourceModel(tm)
tv.setModel(pm)
tv.setMinimumSize(400, 300)
# show vertical header
tv.verticalHeader().setVisible(True)
# Сортировка по щелчку на заголовке столбца
tv.setSortingEnabled(True)
tv.sortByColumn(0, QtCore.Qt.AscendingOrder)
return tv
class MyTableModel(QtCore.QAbstractTableModel):
def __init__(self, parent=None, *args):
QtCore.QAbstractTableModel.__init__(self, parent, *args)
self.colLabels = ['Col1', 'Col2', 'Col3', 'Col4', 'Col5']
self.cached = [
['89','cell12','cell13','cell14','cell15',],
['34','cell22','cell23','cell24','cell25',],
['56','cell32','cell33','cell34','cell35',],
['18','cell42','cell43','cell44','cell45',],
['22','cell52','cell53','cell54','cell55',],
['44','cell62','cell63','cell64','cell65',],
['19','cell72','cell73','cell74','cell75',],
['76','cell82','cell83','cell84','cell85',],
]
def rowCount(self, parent):
return len(self.cached)
def columnCount(self, parent):
return len(self.colLabels)
def data(self, index, role):
if not index.isValid():
return QtCore.QVariant()
elif role != QtCore.Qt.DisplayRole and role != QtCore.Qt.EditRole:
return QtCore.QVariant()
value = ''
if role == QtCore.Qt.DisplayRole:
row = index.row()
col = index.column()
value = self.cached[row][col]
return QtCore.QVariant(value)
def headerData(self, section, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return QtCore.QVariant(self.colLabels[section])
#заголовки строк
if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
return QtCore.QVariant("%s" % str(section + 1))
return QtCore.QVariant()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
Офлайн
0
Урмх. Как-то все это странно выглядит. QAbstractTableModel - абстрактный класс (ооп термин абстрактный класс знаком?) который используется для определения списка методов, которые должны быть реализованы. Т.е. QTableView является наследником QAbstractTableModel и определяет метод setHeaderData так, как это необходимо для нормальной работы. Если MyTableModel наследовать от QTableModel, то не придется самому писать метод setHeaderData. Посмотрите примеры к PyQt там вроде должна быть нумерация строк. Там вроде вообще наследуется от QSqlQueryModel. Одним словом думаю вас куда-то не туда занесло.
Офлайн
0
dartNNNИли я Вас не понял, или…. Это что за класс “QTableModel” - не нашел такого. Можно подробнее.
Если MyTableModel наследовать от QTableModel, то не придется самому писать метод setHeaderData.
dartNNNВот пример из документации “sql” - “cachedtable.py”, добавлена только сортировка щелчком по заголовку столбца. Модуль connection стандартный из документации. И теперь смотрим - и видим, что нумерация строк работает так же криво. Да и почему нельзя переопределить метод setHeaderData, ведь мы же реализуем headerData, data, setData и т.д. Вот я и интересуюсь возможностью такой реализации. Если я гдето ошибаюсь, прошу направить на путь истинный, т.к. с QT работаю всего второй месяц.
Посмотрите примеры к PyQt там вроде должна быть нумерация строк. Там вроде вообще наследуется от QSqlQueryModel. Одним словом думаю вас куда-то не туда занесло.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui, QtSql
import connection
class TableEditor(QtGui.QDialog):
def __init__(self, tableName, parent=None):
super(TableEditor, self).__init__(parent)
self.model = QtSql.QSqlTableModel(self)
self.model.setTable(tableName)
self.model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
self.model.select()
self.model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
self.model.setHeaderData(1, QtCore.Qt.Horizontal, "First name")
self.model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name")
self.pm = QtGui.QSortFilterProxyModel(self)
self.pm.setSourceModel(self.model)
view = QtGui.QTableView()
view.setModel(self.pm)
# Сортировка по щелчку на заголовке столбца
view.setSortingEnabled(True)
view.sortByColumn(0, QtCore.Qt.AscendingOrder)
submitButton = QtGui.QPushButton("Submit")
submitButton.setDefault(True)
revertButton = QtGui.QPushButton("&Revert")
quitButton = QtGui.QPushButton("Quit")
buttonBox = QtGui.QDialogButtonBox(QtCore.Qt.Vertical)
buttonBox.addButton(submitButton, QtGui.QDialogButtonBox.ActionRole)
buttonBox.addButton(revertButton, QtGui.QDialogButtonBox.ActionRole)
buttonBox.addButton(quitButton, QtGui.QDialogButtonBox.RejectRole)
submitButton.clicked.connect(self.submit)
revertButton.clicked.connect(self.model.revertAll)
quitButton.clicked.connect(self.close)
mainLayout = QtGui.QHBoxLayout()
mainLayout.addWidget(view)
mainLayout.addWidget(buttonBox)
self.setLayout(mainLayout)
self.setWindowTitle("Cached Table")
def submit(self):
self.model.database().transaction()
if self.model.submitAll():
self.model.database().commit()
else:
self.model.database().rollback()
QtGui.QMessageBox.warning(self, "Cached Table",
"The database reported an error: %s" % self.model.lastError().text())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
if not connection.createConnection():
sys.exit(1)
editor = TableEditor('person')
editor.show()
sys.exit(editor.exec_())
Офлайн
0
Bujhm666Упс очепятка:) Извиняюсь. Имел ввиду QTableView
Это что за класс “QTableModel”
Bujhm666Я не говорил, что нельзя. Я имел ввиду, что это вовсе не обязательно в рамках данной проблемы. Признаюсь, что не знаю как надо правильно переопределять setHeaderData()
Да и почему нельзя переопределить метод setHeaderData
Офлайн
0
dartNNNНет наверно вы меня не поняли. Мне надо чтобы нумерация строк всегда (при любой сортировке) было по порядку сверху вниз (1234567…….). Т.е чтобы заголовки строк не принимали участия в сортировке.
Но я не понимаю, чего такого кривого в стандартной нумерации строк? Самая верхняя строка всегда под номером 1. Если вам надо, чтобы строка всегда сохраняла свой номер после сортировки (я правильно понял?), то проще (по-моему) использовать дополнительное поле в записи или как нибудь так.
Офлайн
1
Привет товарищи! у меня возник тоже вот такой вопрос:
пишу вот эту строчку для QTableView:
self.my_table.setSortingEnabled(True)
Полазив в дезайнере(для QTableWidget), как я понял, именно она и включает возможность сортировки,кликая по заголовку таблице?
Но если в QTableWidget там уже автоматически работает сортировка для каждого заголовка столбца, то как абстоит дело в QTableView?
Получается нужно еще самому мутить сигнал и слот?типа
self.my_table.horizontalHeader().sectionClicked.connect()
или какой сигнал использовать?
Офлайн
0
Выше два примера, в обоих присутствует сортировка при клике на заголовок столбца. Нужно использовать QSortFilterProxyModel и включить сортировку для QTableView. Там буквально 4 строчки - разберетесь.
Офлайн
1
То-то и оно)),но почему для QTableWidget все по-другому, хотя если не ошибаюсь QTableView наследуется от QTableWidget, то все должно быть по-аналогии зачем такие замуты?или я чего то не понимаю))Посмотри в дизайнере для QTableWidget как это работает,там не надо никаких проксифильтр!
Офлайн