您是否有任何想法,示例如何将QTableView
与使用Python编写的自定义ORM(例如Web2Py DAL
)一起使用。
所以我有一个查询结果和描述该结果中列的属性的字段:
ID (int) Name (str)
1 Lisa
2 Maria
我想创建一个可以绑定到ResultSetModel
的课程QTableView
。我可以拥有这个类的许多对象,每个对象都有自己的查询 - 比如QSqlQueryModel
。但QSqlQueryModel
处理Qt中的SQL基础结构,但我有自己的ORM来处理数据库。
谢谢
更新:
假设我有一张包含很多行的表格。我不想要求所有这些并将它们保存在模型中。当用户向下或向上滚动视图时,我需要一个与QTableView一起工作的模型,用于请求下一个或上一个记录。
QAbstractItemModel.fetchMore很有趣,但没有做我想要的。
您可以在examples/itemviews/fetchmore.py
中看到“获取更多”示例。向下滚动到最后,它会请求额外的数据部分,但也会保留旧记录。滚动时它不会这样做。
想象一下,我在人员表中有数百万人。我想请求并在模型/内存中保留视图中显示的记录。
我想要实现的目标如下所示:http://www.youtube.com/watch?v=hQlE0rrr7wI
即。一旦显示视图,底层模型就会根据需要在屏幕上显示尽可能多的行。向下/向上滚动时 - 从DB逐步请求其他行。
答案 0 :(得分:1)
这是一个使用elixir和pyside的工作示例。某处应该有session.commit()
(点击“保存”按钮或类似的东西)。除此之外,它功能齐全
from elixir import *
from PySide import QtGui, QtCore
import operator, sys
class ColumnDescriptor(object):
#This holds properties, controlling how each field looks/behaves in GUI"""
def __init__(self, field_id):
self.id = field_id
self.verbose_name = self.id.capitalize().replace('_', ' ')
self.comment = None
class Person(Entity): #ORM entity class
#ORM entity fields
id_number = Field(Integer)
name = Field(Unicode(50))
def __init__(self, name, id_number):
self.name = name
self.id_number = id_number
class PersonView():
columns = []
col = ColumnDescriptor('id_number')
col.comment = "Person's identification code"
columns.append(col)
col = ColumnDescriptor('name')
col.verbose_name = 'Full name'
col.comment = "Person's full name"
columns.append(col)
def __init__(self):
self.total_records = Person.query.count()
def get_items(self, limit, offset = 0):
return Person.query.offset(offset).limit(limit).all()
class TableModel(QtCore.QAbstractTableModel):
#A one-size-fits-all model based on a view descriptor
numberPopulated = QtCore.Signal(int)
def __init__(self, view, editable = False, limit = 50):
super(TableModel, self).__init__()
self.view = view
self.editable = editable
self.current_page = 1
self.items_per_page = limit
self.items = view.get_items(self.items_per_page)
def columnCount(self, index):
return len(self.view.columns)
def rowCount(self, index):
return len(self.items)
def loadPage(self):
self.beginResetModel()
self.items = []
self.endResetModel()
self.items = self.view.get_items(self.items_per_page,
self.current_page * self.items_per_page)
self.beginInsertRows(QtCore.QModelIndex(), 0, len(self.items))
self.endInsertRows()
self.numberPopulated.emit(len(self.items))
def prevPage(self):
self.current_page = self.current_page - 1
self.loadPage()
def nextPage(self):
self.current_page = self.current_page + 1
self.loadPage()
def headerData(self, column, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self.view.columns[column].verbose_name
def data(self, index, role):
if index.isValid():
if (role == QtCore.Qt.DisplayRole) or (role == QtCore.Qt.EditRole):
field_name = self.view.columns[index.column()].id
value = self.items[index.row()].__getattribute__(field_name)
if value:
return unicode(value)
else:
return ''
def flags(self, index):
if not index.isValid():
return QtCore.Qt.ItemIsEnabled
else:
if self.editable:
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
else:
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
class MyWindow(QtGui.QWidget):
def __init__(self):
super(MyWindow, self).__init__()
self.layout = QtGui.QVBoxLayout(self)
self.grid = QtGui.QTableView(self)
self.grid.setModel(TableModel(PersonView(), True))
self.layout.addWidget(self.grid)
self.layoutButtons = QtGui.QHBoxLayout(self)
self.layout.addLayout(self.layoutButtons)
self.btnPrevious = QtGui.QPushButton("Previous", self)
self.btnNext = QtGui.QPushButton("Next",self)
self.layoutButtons.addWidget(self.btnPrevious)
self.layoutButtons.addWidget(self.btnNext)
self.btnPrevious.clicked.connect(self.grid.model().prevPage)
self.btnNext.clicked.connect(self.grid.model().nextPage)
if __name__ == "__main__":
metadata.bind = "sqlite:///persons.sqlite"
setup_all(True)
#fill the table up, if empty
if not Person.query.all():
for n in range(1,1000):
p = Person(u'Person', n)
session.commit()
app = QtGui.QApplication(sys.argv)
win = MyWindow()
win.show()
app.exec_()