Ho una GUI che consiste in un numero di cursori e invece di aggiornare manualmente i cursori quando i dati sottostanti cambiano, vorrei memorizzare i dati in una sottoclasse di QAbstractListModel e le posizioni del cursore si aggiornano automaticamente. Il mio sottoclasse si presenta così:Creazione di un'interfaccia modello/visualizzazione con cursori usando PyQt
from PyQt4 import QtCore
class myDataModel(QtCore.QAbstractListModel):
def __init__(self, initData, parent=None):
super(myDataModel, self).__init__(parent)
self.__data = initData
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if index.row() > len(self.__data):
return None
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self.__data[index.row()]
return None
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.__data)
def setData(self, index, value, role=QtCore.Qt.EditRole):
if not index.isValid() or role != QtCore.Qt.EditRole:
return False
self.__data[index.row()] = value
self.dataChanged.emit(index, index)
return True
Come faccio a collegare questo modello per i cursori nella mia GUI in modo che quando i dati nel modello è cambiato, i cursori cambiano, e viceversa?
Edit: Ecco un mockup dell'interfaccia di base che ho lavorato su:
Edit: Non ho ancora stato in grado di farlo funzionare. Qui è la mia classe del modello:
class dataModel(QtCore.QAbstractListModel):
def __init__(self, initData, parent=None):
super(dataModel, self).__init__(parent)
self.__data = initData
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
if index.row() > len(self.__data):
return None
if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
return self.__data[index.row()]
return None
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.__data)
def setData(self, index, value, role=QtCore.Qt.EditRole):
if not index.isValid() or role != QtCore.Qt.EditRole:
return False
self.__data[index.row()] = value
self.dataChanged.emit(index, index)
return True
Qui è la classe Delegate:
class sliderDelegate(QtGui.QItemDelegate):
'''
classdocs
'''
def __init__(self, parent=None):
'''
Constructor
'''
super(sliderDelegate, self).__init__(parent)
def setEditorData(self, editor, index):
editor.setValue(index.model().data(index, QtCore.Qt.EditRole))
def setModelData(self, editor, model, index):
model.setData(index, editor.value(), QtCore.Qt.EditRole)
E qui è il codice di impostazione:
self._model = dataModel([0 for i in xrange(20)])
self._parameterMapper = QtGui.QDataWidgetMapper(mainWindowInstance)
self._parameterMapper.setModel(self._model)
self._parameterMapper.setItemDelegate(sliderDelegate(mainWindowInstance))
self._parameterMapper.addMapping(self._mainWindowInstance.ui.mySlider, 0)
self._parameterMapper.toFirst()
Purtroppo ricevo il seguente errore quando toFirst() si chiama:
editor.setValue(index.model().data(index, QtCore.Qt.EditRole))
AttributeError: 'NoneType' object has no attribute 'data'
Qualsiasi aiuto sarebbe apprezzato.
Puoi fornire un esempio di come vorresti che fosse questa interfaccia (ad esempio in QtDesigner)? Inoltre, c'è un numero variabile di punti di dati (e quindi di cursori) o è fisso? –
@LegoStormtroopr Ho aggiunto il mockup su cui ho lavorato in QtDesigner. Il numero di cursori verrà corretto nell'applicazione, ce ne sono solo molti. Francamente, mi piacerebbe essere in grado di memorizzare tutte le impostazioni dei widget nell'applicazione in un modello, e fare in modo che le combobox, ecc. Si aggiornino anche quando il modello viene cambiato, ma ottenere il funzionamento di tutti i cursori sarebbe un buon inizio e si spera lasciatemi estrapolare il metodo agli altri widget. – Bitrex
Sfortunatamente, QAbstractListModel viene utilizzato al meglio come dati di elenco presentati in un modulo elenco. Potrebbe essere più semplice creare alcuni widget personalizzati (ad esempio raggruppare i 6 cursori a sinistra e un altro gruppo per l'8 a destra con le combo), quindi promuoverli in QtDesigner e scrivere codice personalizzato per le classi promosse? –