Mam GUI, który składa się z wielu suwaków i zamiast aktualizować suwaki ręcznie, gdy zmieniają się dane podstawowe, chciałbym przechowywać dane w podklasie QAbstractListModel i automatycznie zmieniają pozycje suwaków. Moja podklasa wygląda następująco:Tworzenie interfejsu modelu/widoku z suwakami za pomocą 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
Jak mogę podłączyć ten model do suwaków w moim GUI tak, że kiedy dane w modelu zostanie zmieniony, suwaki zmieniają, i vice versa?
Edit: Tutaj jest makieta podstawowego interfejsu pracuję na:
Edycja: Wciąż nie udało się uzyskać to do pracy. Oto moja klasa model:
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
Oto klasa Delegat:
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)
A oto kod instalacyjny:
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()
Niestety otrzymuję następujący błąd podczas toFirst() nazywa się:
editor.setValue(index.model().data(index, QtCore.Qt.EditRole))
AttributeError: 'NoneType' object has no attribute 'data'
Każda pomoc będzie doceniona.
Czy możesz podać makietę wyglądu interfejsu (np. W QtDesigner)? Czy istnieje również zmienna liczba punktów danych (i tym samym suwaków) lub czy jest ona ustalona? –
@ LegoStormtroopr Dodałem makietę, nad którą pracowałem w QtDesigner. Liczba suwaków zostanie ustalona w aplikacji, jest ich tylko DUŻO. Szczerze mówiąc, chciałbym móc przechowywać wszystkie ustawienia widżetów w aplikacji w modelu i aktualizować listy comboboxów podczas zmiany modelu, ale uruchomienie wszystkich suwaków byłoby dobrym początkiem i mam nadzieję, że pozwól mi ekstrapolować metodę do innych widżetów. – Bitrex
Niestety, QAbstractListModel są najlepiej używane jako dane listy, które są przedstawione w formie listy. Może być łatwiej zrobić kilka niestandardowych widżetów (np. Zgrupowanie 6 suwaków po lewej i innej grupy po 8 po prawej z kombinacjami), a następnie promować je w QtDesigner i napisać niestandardowy kod dla promowanych klas? –