Уведомления

Группа в Telegram: @pythonsu

#1 Май 6, 2010 13:03:16

Bujhm666
От:
Зарегистрирован: 2010-03-23
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Подскажите пожалуйста как у QAbstractTableModel реализовать метод setHeaderData. Второй день бьюсь, ни чего не получается.



Офлайн

#2 Май 7, 2010 06:01:21

dartNNN
От:
Зарегистрирован: 2009-12-08
Сообщения: 199
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Что конкретно нужно? Что конкретно не получается? И где конкретный код? :)



Офлайн

#3 Май 7, 2010 10:52:11

Bujhm666
От:
Зарегистрирован: 2010-03-23
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Опишу поподробней задачу. Нас интересует вертикальный заголовок 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_())



Офлайн

#4 Май 7, 2010 18:17:59

dartNNN
От:
Зарегистрирован: 2009-12-08
Сообщения: 199
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Урмх. Как-то все это странно выглядит. QAbstractTableModel - абстрактный класс (ооп термин абстрактный класс знаком?) который используется для определения списка методов, которые должны быть реализованы. Т.е. QTableView является наследником QAbstractTableModel и определяет метод setHeaderData так, как это необходимо для нормальной работы. Если MyTableModel наследовать от QTableModel, то не придется самому писать метод setHeaderData. Посмотрите примеры к PyQt там вроде должна быть нумерация строк. Там вроде вообще наследуется от QSqlQueryModel. Одним словом думаю вас куда-то не туда занесло.



Офлайн

#5 Май 8, 2010 09:11:47

Bujhm666
От:
Зарегистрирован: 2010-03-23
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

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_())



Офлайн

#6 Май 8, 2010 15:40:31

dartNNN
От:
Зарегистрирован: 2009-12-08
Сообщения: 199
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Bujhm666
Это что за класс “QTableModel”
Упс очепятка:) Извиняюсь. Имел ввиду QTableView
Bujhm666
Да и почему нельзя переопределить метод setHeaderData
Я не говорил, что нельзя. Я имел ввиду, что это вовсе не обязательно в рамках данной проблемы. Признаюсь, что не знаю как надо правильно переопределять setHeaderData()
Но я не понимаю, чего такого кривого в стандартной нумерации строк? Самая верхняя строка всегда под номером 1. Если вам надо, чтобы строка всегда сохраняла свой номер после сортировки (я правильно понял?), то проще (по-моему) использовать дополнительное поле в записи или как нибудь так.



Офлайн

#7 Май 8, 2010 16:04:19

Bujhm666
От:
Зарегистрирован: 2010-03-23
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

dartNNN
Но я не понимаю, чего такого кривого в стандартной нумерации строк? Самая верхняя строка всегда под номером 1. Если вам надо, чтобы строка всегда сохраняла свой номер после сортировки (я правильно понял?), то проще (по-моему) использовать дополнительное поле в записи или как нибудь так.
Нет наверно вы меня не поняли. Мне надо чтобы нумерация строк всегда (при любой сортировке) было по порядку сверху вниз (1234567…….). Т.е чтобы заголовки строк не принимали участия в сортировке.



Офлайн

#8 Май 8, 2010 16:29:47

apologize828
От:
Зарегистрирован: 2010-02-13
Сообщения: 223
Репутация: +  1  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Привет товарищи! у меня возник тоже вот такой вопрос:
пишу вот эту строчку для QTableView:

self.my_table.setSortingEnabled(True)

Полазив в дезайнере(для QTableWidget), как я понял, именно она и включает возможность сортировки,кликая по заголовку таблице?
Но если в QTableWidget там уже автоматически работает сортировка для каждого заголовка столбца, то как абстоит дело в QTableView?
Получается нужно еще самому мутить сигнал и слот?типа
self.my_table.horizontalHeader().sectionClicked.connect()
или какой сигнал использовать?



Офлайн

#9 Май 8, 2010 16:48:57

Bujhm666
От:
Зарегистрирован: 2010-03-23
Сообщения: 36
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

Выше два примера, в обоих присутствует сортировка при клике на заголовок столбца. Нужно использовать QSortFilterProxyModel и включить сортировку для QTableView. Там буквально 4 строчки - разберетесь.



Офлайн

#10 Май 8, 2010 22:27:42

apologize828
От:
Зарегистрирован: 2010-02-13
Сообщения: 223
Репутация: +  1  -
Профиль   Отправить e-mail  

[PyQt4] QAbstractTableModel - setHeaderData()

То-то и оно)),но почему для QTableWidget все по-другому, хотя если не ошибаюсь QTableView наследуется от QTableWidget, то все должно быть по-аналогии зачем такие замуты?или я чего то не понимаю))Посмотри в дизайнере для QTableWidget как это работает,там не надо никаких проксифильтр!



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version