2011-11-29 34 views
0

您有任何想法,示例如何使用QTableView與用Python編寫的自定義ORM(例如Web2Py DAL)。QTableView和自定義ORM

所以我有一個查詢的結果和字段描述列的特性,因爲結果:

ID (int) Name (str) 
1   Lisa 
2   Maria 

我想打一個類ResultSetModel可以綁在QTableView。我可以有這個類的許多對象,每個對象都有自己的查詢 - 就像在QSqlQueryModel中一樣。但QSqlQueryModel處理Qt中的SQL基礎結構,但我有自己的ORM來處理數據庫。

謝謝

UPDATE:

假設我有一個表有很多行。我不想要求他們所有人,並將他們保存在模型中。我需要一個與QTableView一起工作的模型,當用戶向下或向上滾動視圖時,請求下一個或前一個記錄。

QAbstractItemModel.fetchMore很有趣,但沒有做我想要的。

您可以在examples/itemviews/fetchmore.py中看到提取更多示例。當您向下滾動到最後時,它會請求更多部分數據,但也會保留舊記錄。當你向上滾動時它不會做同樣的事情。

想象一下,我有幾百萬人在Persons表中。我想請求並保存在我的模型/內存中,只有視圖中顯示的記錄。

什麼,我想實現如下所示:http://www.youtube.com/watch?v=hQlE0rrr7wI

即一旦顯示視圖,底層模型將根據需要請求儘可能多的行以顯示在屏幕上。在向下滾動/向上滾動時 - 其他行將逐步從DB請求。

回答

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

'高清rowCount時(個體經營,指數):返回LEN(self.items)' - 這意味着項目是從DB已經申請的記錄列表。當用戶滾動QTableView時,我需要以塊的形式請求記錄。此外,我可能不知道總數或記錄...像這裏一樣:http://cep.xor.aps.anl.gov/software/qt4-x11-4.2.2-browser/dc/d7c/qsqlquerymodel_8cpp-source .html#l00034 – warvariuc

+0

是不是QAbstractTableModel.fetchMore()這樣做的標準方法? – AlexVhr

+0

感謝您嘗試提供幫助。請閱讀 – warvariuc

相關問題