Найти - Пользователи
Полная версия: [PyQt4] QAbstractTableModel - setHeaderData()
Начало » GUI » [PyQt4] QAbstractTableModel - setHeaderData()
1 2
Bujhm666
Подскажите пожалуйста как у QAbstractTableModel реализовать метод setHeaderData. Второй день бьюсь, ни чего не получается.
dartNNN
Что конкретно нужно? Что конкретно не получается? И где конкретный код? :)
Bujhm666
Опишу поподробней задачу. Нас интересует вертикальный заголовок 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_())
dartNNN
Урмх. Как-то все это странно выглядит. QAbstractTableModel - абстрактный класс (ооп термин абстрактный класс знаком?) который используется для определения списка методов, которые должны быть реализованы. Т.е. QTableView является наследником QAbstractTableModel и определяет метод setHeaderData так, как это необходимо для нормальной работы. Если MyTableModel наследовать от QTableModel, то не придется самому писать метод setHeaderData. Посмотрите примеры к PyQt там вроде должна быть нумерация строк. Там вроде вообще наследуется от QSqlQueryModel. Одним словом думаю вас куда-то не туда занесло.
Bujhm666
dartNNN
Если MyTableModel наследовать от QTableModel, то не придется самому писать метод setHeaderData.
Или я Вас не понял, или…. Это что за класс “QTableModel” - не нашел такого. Можно подробнее.

dartNNN
Посмотрите примеры к PyQt там вроде должна быть нумерация строк. Там вроде вообще наследуется от QSqlQueryModel. Одним словом думаю вас куда-то не туда занесло.
Вот пример из документации “sql” - “cachedtable.py”, добавлена только сортировка щелчком по заголовку столбца. Модуль connection стандартный из документации. И теперь смотрим - и видим, что нумерация строк работает так же криво. Да и почему нельзя переопределить метод setHeaderData, ведь мы же реализуем headerData, data, setData и т.д. Вот я и интересуюсь возможностью такой реализации. Если я гдето ошибаюсь, прошу направить на путь истинный, т.к. с QT работаю всего второй месяц.

#!/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_())
dartNNN
Bujhm666
Это что за класс “QTableModel”
Упс очепятка:) Извиняюсь. Имел ввиду QTableView
Bujhm666
Да и почему нельзя переопределить метод setHeaderData
Я не говорил, что нельзя. Я имел ввиду, что это вовсе не обязательно в рамках данной проблемы. Признаюсь, что не знаю как надо правильно переопределять setHeaderData()
Но я не понимаю, чего такого кривого в стандартной нумерации строк? Самая верхняя строка всегда под номером 1. Если вам надо, чтобы строка всегда сохраняла свой номер после сортировки (я правильно понял?), то проще (по-моему) использовать дополнительное поле в записи или как нибудь так.
Bujhm666
dartNNN
Но я не понимаю, чего такого кривого в стандартной нумерации строк? Самая верхняя строка всегда под номером 1. Если вам надо, чтобы строка всегда сохраняла свой номер после сортировки (я правильно понял?), то проще (по-моему) использовать дополнительное поле в записи или как нибудь так.
Нет наверно вы меня не поняли. Мне надо чтобы нумерация строк всегда (при любой сортировке) было по порядку сверху вниз (1234567…….). Т.е чтобы заголовки строк не принимали участия в сортировке.
apologize828
Привет товарищи! у меня возник тоже вот такой вопрос:
пишу вот эту строчку для QTableView:

self.my_table.setSortingEnabled(True)

Полазив в дезайнере(для QTableWidget), как я понял, именно она и включает возможность сортировки,кликая по заголовку таблице?
Но если в QTableWidget там уже автоматически работает сортировка для каждого заголовка столбца, то как абстоит дело в QTableView?
Получается нужно еще самому мутить сигнал и слот?типа
self.my_table.horizontalHeader().sectionClicked.connect()
или какой сигнал использовать?
Bujhm666
Выше два примера, в обоих присутствует сортировка при клике на заголовок столбца. Нужно использовать QSortFilterProxyModel и включить сортировку для QTableView. Там буквально 4 строчки - разберетесь.
apologize828
То-то и оно)),но почему для QTableWidget все по-другому, хотя если не ошибаюсь QTableView наследуется от QTableWidget, то все должно быть по-аналогии зачем такие замуты?или я чего то не понимаю))Посмотри в дизайнере для QTableWidget как это работает,там не надо никаких проксифильтр!
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB