qsql tableview / qlsqlmodel mit checkboxen erweitern

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
zmanid
User
Beiträge: 11
Registriert: Donnerstag 23. Juli 2009, 14:18
Wohnort: Berlin

hallo,
nun gehts , es tut was es tun sollte.
hier noch mal die Zusammenfassung.

Ich habe eine Datenbank mit den Feldern

Code: Alles auswählen

datafields = ["id", "name", "height", "owner", "date"]
, id is der primaerschluessel und ein autoincrement.
Die Darstelllung und das Control erfolgt ueber einen QSqltableView.
dieser View soll aber eine Zusatzspalte Checkstat erhalten, ueber die sich einzelne zeilen auswaehlen (und ggf weiterverarbeiten) lassen.

Der Tableview is hat die Spaltenzuordnung
ID, NAME,HEIGHT, OWNER, DATE, CHECKSTAT = range(6)
is editable und nach Spalten sortierbar.

Der Basisdialog dazu enthaelt im init()

Code: Alles auswählen

...
self.model = OptionSqlTableModel(self, self.db)
self.model.setTable("datatable")
self.model.select()
self.model.initCheckstat()
self.tableView.setModel(self.model)
...
Das dazu noetige eigene OptionSqlTabelmodel sieht so aus:

Code: Alles auswählen

class OptionSqlTableModel(QSqlTableModel):
    def __init__(self,  parent = None , db = QSqlDatabase):
        print "OptionSqlTableModel::init()"
        super(OptionSqlTableModel, self).__init__(parent,db)
        self.checkstat = {}
und verwaltet den checkstat ueber ein Dictionary. Damit der checkstat auch bei allen sortierungen funktioniert, wird er ueber die ID der jeweiligen zeile "geschluesselt". Dazu gibts im Model die Funktion:

Code: Alles auswählen

def initCheckstat(self):
#in diesem dict wird der status der zeile gespeiert, im init ist die tablelle noch leer
    for row in range(self.rowCount(self)):
        index =  QSqlTableModel.index(self, row, ID )
        thisID = self.data(index).toString()
        self.checkstat[thisID] = QVariant(Qt.Checked)
Die data() Methode muss angepasst werden und fuer diese Spalte den Zustand aus dem checkstat-dictionary abholen:

Code: Alles auswählen

def data(self, index, role=Qt.DisplayRole):
    if index.column() == CHECKSTAT: 
        if role == Qt.CheckStateRole:
             thisrow = index.row()
             idIndex = QSqlTableModel.index(self, thisrow, ID)
             thisId = QSqlTableModel.data(self, idIndex).toString()
             return self.checkstat.get(thisId)
                
        else:
            return QSqlTableModel.data(self, index, role)
setData() braucht ebenfalls eine Spezialbehandlung fuer die checkstat spalte und sieht nun so aus:

Code: Alles auswählen

def setData(self, index, value, role = Qt.EditRole):
        if index.isValid():
            if (index.column() == CHECKSTAT  and role  == Qt.CheckStateRole):
                print "CHECKSTAT:value int ", value.toInt(), "CHECKSTAT:value string: ",  value.toString(),
                print "CHECKSTAT:value bool ", value.toBool()

                thisrow = index.row()
                idIndex = QSqlTableModel.index(self, thisrow, ID)   #index zur id-spalte
                thisId = QSqlTableModel.data(self, idIndex).toString()   #  gefundene ID

                if value.toInt()[0]== 0:  # (is checked)
                    print "value is  0"
                    self.checkstat[thisId] = QVariant(Qt.Unchecked)
                    self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), index, index)

                elif value.toInt()[0]== 2:  # (is unchecked)
                    self.checkstat[thisId] = QVariant(Qt.Checked)
                    self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), index, index)

            else:
                QSqlTableModel.setData(self, index, value, role)
            return True
        return False

Die Zusatzsspalte im tableview heisst "use this" kommt zustande ueber

Code: Alles auswählen

def headerData(self, section, orientation, role = Qt.DisplayRole):
      if section == CHECKSTAT and orientation == Qt.Horizontal:
            return QVariant("use this")
      else:
            return QSqlTableModel.headerData(self, section, orientation, role)
Das neue model will auch noch wissen wie die Dimensionen sind, dazu

Code: Alles auswählen

def columnCount(self, index):
        colcount = QSqlTableModel.columnCount(self)
        return colcount + 1
und

Code: Alles auswählen

def rowCount(self, index):
        rowcount = QSqlTableModel.rowCount(self)
        return rowcount
Vielen Dank fuer die Hilfe von ischisch und lunar!
gruss dirk
INFACT
User
Beiträge: 385
Registriert: Freitag 5. Dezember 2008, 16:08

Code: Alles auswählen

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import Qt

app = QApplication(sys.argv)

listWidget = QListWidget()

for i in xrange(10):
    item = QListWidgetItem("Checkbox")
    item.setCheckState(Qt.Checked)
    listWidget.addItem(item)
    
listWidget.show()
app.exec_()
print item.checkState() # die letzte checkbox!
[b][i]ein kleines game für die die lust haben http://konaminut.mybrute.com[/i][/b]
;-)
Antworten