2015-07-04 84 views
0

我可以找到一些如何在标准视图中使用标准模型的例子。如何在Qt或PyQt中使用QDataWidgetMapper?

http://doc.qt.io/qt-5/modelview.html

http://doc.qt.io/qt-5/qtwidgets-itemviews-simplewidgetmapper-example.html

但我就是无法找到如何使用QAbstractModel让我自己model,并把它用在我自己的view/widget一个例子。

更新模型后,展台视图将更新,但不是我自己的视图。 run result

全码:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

from PyQt5.QtWidgets import (QWidget, QLabel, QDataWidgetMapper, 
           QLineEdit, QApplication, QGridLayout) 
from PyQt5.QtCore import QAbstractListModel, Qt 
from PyQt5.QtWidgets import QListView 


class Window(QWidget): 
    def __init__(self, model, parent=None): 
     super(Window, self).__init__(parent) 

     self.model = model 

     # Set up the widgets. 
     nameLabel = QLabel("Na&me:") 
     nameEdit = QLineEdit() 

     # Set up the mapper. 
     self.mapper = QDataWidgetMapper(self) 
     self.mapper.setModel(self.model) 
     self.mapper.addMapping(nameEdit, 0) 

     layout = QGridLayout() 
     layout.addWidget(nameLabel, 0, 0, 1, 1) 
     layout.addWidget(nameEdit, 0, 1, 1, 1) 
     self.setLayout(layout) 

     self.mapper.toFirst() 


class MyModel(QAbstractListModel): 
    def __init__(self, status=[], parent=None): 
     super().__init__(parent) 
     self.status = status 

    def rowCount(self, index_parent=None, *args, **kwargs): 
     return len(self.status) 

    def data(self, index, role=Qt.DisplayRole, parent=None): 
     if not index.isValid(): 
      return None 
     row = index.row() 
     if row == 0: 
      print(index) 
      if role == Qt.DisplayRole: 
       return self.status[row] 
      elif role == Qt.EditRole: # if it's editing mode, return value for editing 

       return self.status[row] 

    def flags(self, index): 
     return Qt.ItemIsEnabled | Qt.ItemIsEditable 

    def setData(self, index, value='', role=Qt.EditRole): 
     row = index.row() 

     if role == Qt.EditRole: 
      self.status[row] = value 
      self.dataChanged.emit(index, index) # inform the other view to request new data 
      return True 
     else: 
      return False 


if __name__ == '__main__': 
    import sys 

    app = QApplication(sys.argv) 

    myModel_on_mywindow = MyModel([1, 2, 3]) 
    mywindow = Window(myModel_on_mywindow) 
    mywindow.setWindowTitle('myModel_on_mywindow') 
    mywindow.show() 
    myModel_on_mywindow.status[0] = 2 

    myModel_on_qlistview = MyModel([1, 2, 3]) 
    qlistview = QListView() 
    qlistview.show() 
    qlistview.setModel(myModel_on_qlistview) 
    qlistview.setWindowTitle('myModel_on_qlistview') 

    myModel_on_qlistview.status[0] = 2 

    sys.exit(app.exec_()) 
+0

什么[模型子类参考](http://doc.qt.io/qt-5/model-view-programming.html#model-subclassing-reference)和[化QAbstractItemModel](HTTP:// doc.qt.io/qt-5/qabstractitemmodel.html)? – Miki

+0

@Miki谢谢。我知道如何制作一个定制的模型。但我不知道如何在我的小部件上使用它。 –

+0

现在怎么样? @ekhumoro –

回答

3

您的自定义模型需要重写抽象模型的某些功能,这取决于你继承哪一个。这是子类化QAbstractListModel的一个小例子。您可以在Qt文档中阅读更多关于这一点:结合使用自定义模型一个QDataMapper时QAbstractListModel Details

class MyModel(QAbstractListModel): 
    def __init__(parent=None): 
     QAbstractListModel.__init__(parent) 
     self.content = [] # holds the data, you want to present 

    def rowCount(index): 
     return len(self.content) 
    # This defines what the view should present at given index 
    def data(index, role): 
     if index.isValid() and role == Qt.DisplayRole): 
      dataElement = self.content[index.row()] 
      if index.colum() == 0: 
       return dataElement.someBoolField 
      if index.colum() == 1: 
       return dataElement.someIntField 
      # ... 
     } 
     return QVariant() # this is like returning nothing 
    } 
    # If your items should be editable. Automatically called, when user changes the item. 
    def setData(index, value, role): 
     if index.isValid(): 
      dataElement = self.content[index.row()].get() 
      if index.column() == 0: 
       return dataElement.tryToSetBoolField(value.toBool()) 
      if index.column() == 1: 
       return dataElement.tryToSetIntField(value.toInt()) 
      # ... 
     } 
     return True 
    } 
}; 

# connecting your view with your model 
model = MyModel() 
myView = QTreeView() # or something else 
myView.setModel(model) 

编辑

要更新您的看法,请拨打setCurrentIndex(changedIndex)或其包装后改变模型,像这样在您的情况:

myModel_on_mywindow.status[0] = 2 
myModel.mapper.toFirst() 

上QDataMapper Qt的文档中详细说明提到了这一点:

的导航功能toFirst(),toNext(),toPrevious(),toLast()和setCurrentIndex()可用于从模型在模型导航和更新的内容的窗口小部件。

+0

感谢您的回答。我已经完成了这个工作。这里的问题是如何将它应用到我的小部件,如下所示:class BicMainWindow(QWidget,Ui_Form): –

+0

对不起,延迟答案。我编辑了我的答案来解决你的问题。在更改模型后调用'setCurrentIndex()'或其包装器。 –

+0

@x平方非常感谢您的回答。我编辑了我的问题。对不起,开始时不太清楚。我不知道应该问一个新问题还是仍然使用这个问题。你可以运行我的代码,你会发现问题。 –

相关问题