2017-08-23 7 views
0

PyQtでモデル/ビューを学習しようとしています(このスレッドを参照:Unable to inherit from QAbstractItemModel)。マッピング割り当てを追加しようとすると、アプリケーションがハングしています。私のカスタムデータモデルクラスは次のとおりです。QDataWidgetMapper.addMapping(...)によってアプリケーションがハングする

class MyCustomDataModel(QAbstractItemModel): 

    def __init(self, parent = None): 
     super(MyCustomDataModel, self).__init__(parent) 

     self.parent = None 


    def rowCount(self, parent): 
     return 1 

    def data(self, index, role): 

     if not index.isValid(): 
      return None 

     if role == Qt.DisplayRole or role == Qt.EditRole: 

      if index.column() == 0: 
       return self.parent.value0 
      elif index.column() == 1: 
       return self.parent.value1 
      elif index.column() == 1: 
       return self.parent.value2 

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

     if role == Qt.EditRole: 
      if index.column() == 0: 
       self.parent.value0 = value 
      elif index.column() == 1: 
       self.parent.value1 = value 
      elif index.column() == 2: 
       self.parent.value2 = value 

      self.dataChanged.emit(index, index) 

ここでは、データモデルを使用しようとしているクラスがあります。それは私がウィジェットにマップしたい変数が含まれています

class MyCustomType(AnotherCustomTypeThatInheritsQListWidgetItem): 

def __init__(self, parent = None): 
    super(MyCustomType, self).__init__(parent) 

    # Some member data: 
    self.value0 = 0 
    self.value1 = 1 
    self.value2 = 2 

    # Instantiate a model: 
    self.dataModel = MyCustomDataModel() 
    self.dataModel.parent = self 

私は3つのにQLineEditウィジェットを含む複合ウィジェットを持っている:

class MyCompositeWidget(QWidget): 

    def __init__(self, parent = None): 
     super(MyCompositeWidget, self).__init__(parent) 

     self.dataMapper = QDataWidgetMapper() 

     # Instantiate three line edits: 
     self.lineEdit1 = QLineEdit() 
     self.lineEdit2 = QLineEdit() 
     self.lineEdit3 = QLineEdit() 

     # Add widgets to layout, set layout, etc. Not shown but widgets display properly. 

    def Activate(self, anInstanceofMyCustomType): 

     self.dataMapper.setModel(anInstanceOfMyCustomType.dataModel) 
     self.dataMapper.addMapping(self.lineEdit1, 0) # This line causes application to hang indefinately 
     self.dataMapper.addMapping(self.lineEdit2, 1) 
     self.dataMapper.addMapping(self.lineEdit3, 2) 

実行時にアプリケーションが示されている「addMapping」コールでハング"Activate(...)"機能で使用します。チュートリアルはオンラインではっきりとわかりません。私はかなり "index.column()"マッピングについて混乱していることを認めなければなりませんが、これはインデックスがデータメンバーに割り当てられる方法です。とにかく、どんな助けも非常に高く評価されています...私はこれを学ぶために多くの時間を費やしてきました。

+0

ここに行く1つの方法は、必要でないものをすべて削除してから、動作する状態になるまでコードをさらに単純化することです。最小限の完全な例は、他の人が問題を調査するのを手助けすることです。 – Trilarion

答えて

1

QtのModel-View Programmingフレームワークのクラスをよく理解しているかどうかはわかりません。 its documentationと読むことをお勧めします(ドラッグアンドドロップに関するプロキシはスキップできます)。必要に応じてそれを数回読んで、それを完全に理解するまでにはしばらく時間がかかりました。

いずれにせよ、いくつかのシナリオがあり、これらのシナリオでは異なるクラスを使用することが重要です。単純なものから複雑なものへ順番に:

  1. 便利なクラスを使用します。小さなモデルを持ち、 というモデルを表示するウィジェットが1つしかない場合に、これを使用できます。このシナリオではconvinience classes、 を使用し、すべてが「ウィジェット」で終わる名前:QListWidget,QTableWidget、 およびQTreeWidgetを使用します。別のモデルクラスにリンクされていない場合は、対応する商品クラス(QListWidgetItem,QTableWidgetItemおよびQTreeWidgetItem)で直接入力します。これらのクラスはすべてサブクラス化されていません!それらをオーバーライドすると、おそらく未知の動作につながります。
  2. 標準モデルクラスを使用します。小さなモデルを持っていても、同じモデル上に複数のビューが必要な場合は、これらを使用します。この場合、QStandardItemModelを作成し、それにQStandardItemオブジェクトを移入します。 1つまたは複数のビュークラス(QListView,QTableView、またはQTreeView)を作成し、モデルに接続します。
  3. 新しいモデルを作成します。これは、大きなモデルをお持ちの場合に最適なソリューションです。 QAbstractListModel', 'QAbstactTableModel', or 'QAbstractItemModel(残念ながらQAbstractTreeModelはありません)のいずれかの基本クラスをオーバーライドし、さまざまなメソッドを実装します。どのメソッドをオーバーライドするかは、モデルに必要な機能によって異なります(Model Subclassing Reference参照)。このアプローチの利点は、より高いパフォーマンスと柔軟性です。モデルの実装では通常のPythonデータ構造を使用でき、dataメソッドはビューの要求に応じて、可視セルのデータのみを返します。通常のPythonデータ構造を使用してデータを格納することができます。事前にQtアイテムオブジェクトにデータを入れる必要はありません。

上記のクラスを混在させないでください。つまり、ウィジェットのアイテムを標準モデルに入れたり、その逆に入れたりしないでください。

あなたの状況について詳しく知ることなく、私はシナリオ2があなたに一番当てはまると思います。そのため、QStandardModelを作成し、QStandardItemオブジェクトで埋めることをお勧めします。最初の反復では、QListViewまたはQTableViewを使用してモデルを検査します。正常に動作する場合にのみ、DataWidgetMapperに接続します。簡単に始める!

最後に、MVCEを次回作成してください。完了したことを確認してください!たとえば、anInstanceOfMyCustomTypeのような構文を使用せず、オブジェクトインスタンスを作成する実際のコードを表示してください。それ以外の場合は、重要な情報を省略する危険があります。また、問題を再現し、必要に応じて調査し、可能な回答を確認することもできます。

関連する問題