Hier mein Code: http://paste.pocoo.org/show/119209/
Entscheidend ist die Methode setData, bei der ich mir nicht sicher bin, ob sie von mir richtig implementiert wurde. Das Problem ist, dass ich in den Zellen Werte einfügen kann, aber sie verschwinden sofort nach dem Drücken der Eingabetaste. Habe ich das mit dem emitten von dataChanged so richtig gemacht? Wie kann ich es erreichen, dass die Werte nach der Eingabe in der Zelle bleiben?
Probleme beim Erstellen von editierbaren Models
Guten morgen,
da nur ein Code Stück von dir da is konnt ich es net probieren...
Nimm ma das Signal
Soweit ich das verstanden habe wird dieses Signal genutz um den View neu zu zeichnen, während wohl nur signaliesiert das etwas geändert wurde...
>> Beschreibung auf Riverbank
da nur ein Code Stück von dir da is konnt ich es net probieren...
Nimm ma das Signal
Code: Alles auswählen
layoutChanged ()
Code: Alles auswählen
dataChanged (const QModelIndex&,const QModelIndex&)
>> Beschreibung auf Riverbank
There are 10 kinds of people. Those who understand binary notation, and those who do not.
Leider bewirkte es bei mir nichts, vielleicht habe ich die Methoden auch nur falsch eingesetzt. Damit ihr mein Problem nachvollziehen könnt, hier alle benötigten Dateien:
main_window.py: http://paste.pocoo.org/show/119402/
model.py: http://paste.pocoo.org/show/119403/
main.ui: http://paste.pocoo.org/show/119404/
main_window.py: http://paste.pocoo.org/show/119402/
model.py: http://paste.pocoo.org/show/119403/
main.ui: http://paste.pocoo.org/show/119404/
Also, da du ja dein eigenes Model gebaut hast must du auch eine Delegateklasse dazu basteln, sonst weiß ja der View nicht wie er mit deinen selbst eingeführten Daten arbeiten soll...
Sind noch einige andre nützliche Funktionen drinnen die man evtl noch integrieren kann... www.riverbankcomputing.co.uk
und in der main mußt du das Delegate noch zuweißen:
Sind noch einige andre nützliche Funktionen drinnen die man evtl noch integrieren kann... www.riverbankcomputing.co.uk
Code: Alles auswählen
# model.py
from __future__ import with_statement
from os import path
import pickle
import sys
from PyQt4 import QtCore, QtGui
from babel.dates import get_day_names
################# CHANGES ###########################
class TimeTableDelegate(QtGui.QItemDelegate):
def __init__(self):
QtGui.QItemDelegate.__init__(self)
def setModelData(self, editor, model, index):
"""Funtion holt die Daten aus dem Editorfenster ab und schickt sie ans Model zum aendern/speichern"""
txt = editor.text()
model.setData(index, QtCore.QVariant(txt))
def setEditorData(self, editor, index):
""" Funktion setzt den Editortext auf den Text der Zelle"""
text = # TODO: hier den text irgendwie über den index holen
editor.setText(text)
############## END CHANGES ###########################
class TimeTable(QtCore.QAbstractTableModel):
def __init__(self, filename, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
with open(filename, 'rb') as fileobj:
try:
self.lessons = pickle.load(fileobj)
except EOFError:
# create an empty timetable with 7 days and 8 lessons each day
self.lessons = [
[QtCore.QVariant() for _ in xrange(7)] for _ in xrange(8)
]
[ ... ]
def setData(self, index, value, role=QtCore.Qt.EditRole):
################# CHANGES ###########################
# FIXED
if index.isValid() and role == QtCore.Qt.EditRole:
self.lessons[index.row()][index.column()] = value
self.emit(QtCore.SIGNAL("layoutChanged ()"))
return True
else:
return False
############### END CHANGES #########################
Code: Alles auswählen
#main_window.py
#!/usr/bin/env python
import sys
from os import path
from PyQt4 import QtCore, QtGui, uic
from model import *
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
uic.loadUi('main.ui', self)
# file where the data is stored
filename = path.join(path.dirname(
path.abspath(__file__)), 'data.pickle'
)
# table view is the central widget
view = QtGui.QTableView(self)
model = TimeTable(filename, view)
self.delegate = TimeTableDelegate()
view.setItemDelegate(self.delegate)
################# CHANGES ###########################
view.setModel(model)
self.setCentralWidget(view)
############## END CHANGES ###########################
self.connect(
self.actionQuit,
QtCore.SIGNAL('triggered()'),
self.close
)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
There are 10 kinds of people. Those who understand binary notation, and those who do not.
Unsinn, ein eigenes Modell impliziert noch lange nicht die Notwendigkeit eines eigenen Delegates, Qt4 kann mit Standarddaten (Text, Bilder, Zahlen) alleine umgehen. Ein Delegate wird nur und ausschließlich dann benötigt, wenn man "exotische" Daten anzeigen oder die Anzeige von Standard-Datentypen verändern möchte (z.B. eine Combobox für die Eingabe verwenden möchte).Traggger hat geschrieben:Also, da du ja dein eigenes Model gebaut hast must du auch eine Delegateklasse dazu basteln, sonst weiß ja der View nicht wie er mit deinen selbst eingeführten Daten arbeiten soll...
Das eigentliche Problem ist, dass der Code des OP das übergebene QVariant-Exemplar direkt speichert. Ändert man den Code so, dass Zeichenketten gespeichert werden, und übergebene Werte mittels "QVariant.toString()" konvertiert werden, funktioniert die Anzeige.
Ich weiß nicht, wo die Ursache liegt, müsste ich raten, würde ich sagen, dass QVariant sinnvollerweise nur eine schwache Referenz auf das enthaltene Objekt hält. Die Eingabe wird im Delegate offenbar auf dem Stack alloziert, und daher gelöscht, sobald die Methode des Delegate, die auf die Eingabe reagiert, beendet ist. Normalerweise ist das kein Problem, da QStrings und andere elementare Datentypen "implicitly shared" sind. In diesem Fall existiert aber keine direkte Referenz auf dieses Datum, sondern lediglich eine indirekte, schwache Referenz über QVariant. Daher sieht Qt4 keine Referenz mehr und löscht das Objekt.
Ok, dann habe ich das aus der Hilfe und dem Beispiel falsch interpretiert... Sorry!!ein eigenes Modell impliziert noch lange nicht die Notwendigkeit eines eigenen Delegates
Ich habe bisher immer mit eignen Datentypen sowas erstellt, deswegen habe ich da wohl ein bissl in die falsche Richtung gedacht...
There are 10 kinds of people. Those who understand binary notation, and those who do not.
Dankeschön, das wars! Ich hätte nicht gedacht, dass mein Problem so knifflig war.lunar hat geschrieben:Das eigentliche Problem ist, dass der Code des OP das übergebene QVariant-Exemplar direkt speichert. Ändert man den Code so, dass Zeichenketten gespeichert werden, und übergebene Werte mittels "QVariant.toString()" konvertiert werden, funktioniert die Anzeige.
Edit: Zum besseren Verständnis hier nochmal die model.py (die anderen Dateien blieben unverändert): http://paste.pocoo.org/show/119572/