2017-01-03 8 views
0

Ich habe QAbstractProxyModel subklassifiziert und sein Quellmodell ist eine Unterklasse von QSqlTableModel. Das Proxy-Modell muss jeweils nur eine Zeile des Quellmodells anzeigen. Hier ist der Code:setData gibt false für QAbstractProxyModel zurück

bool SensorDisplayModel::setData(const QModelIndex &index, const QVariant &value, int role) 
{ 
    if(!index.isValid()) 
     return false; 

    QModelIndex sourceIdx = mapToSource(index); 

    if(role == Qt::DisplayRole || role == Qt::EditRole) 
    { 
     if(sourceIdx.isValid()) 
     { 
      if(sourceModel()->setData(sourceIdx, value, role)) 
      { 
//    emit dataChanged(index, index); 
       return true; 
      } 
      return false; 
     } 
     else 
      return false; 
    } 

    return false; 
} 

Quelle Modell:

bool SensorModel::setData(const QModelIndex &index, const QVariant &value, int role) 
{ 
    if(!index.isValid()) 
     return false; 

    if(role == Qt::EditRole || role == Qt::DisplayRole) 
    { 
     if(index.column() != 0) 
      return QSqlTableModel::setData(index, value, Qt::EditRole) && 
       QSqlTableModel::setData(index, value, Qt::DisplayRole); 
     else 
      return QSqlTableModel::setData(index, value, role); 
    } 

    return false; 
} 

Die folgenden wird aufgerufen, wenn eine neue Zeile mit dem Source-Modell hinzugefügt werden muss:

void SensorDisplayModel::addSensor() 
{ 
    QString ro_id; 
    bool success = false; 

    if(sensorModel->insertRows(sensorModel->rowCount(), 1)) 
    { 
     selectedRow = sensorModel->rowCount() - 1; 
     ro_id = "DB-" + QString("%1").arg(SensorDisplayModel::id_no, 
              3, 10, QChar('0')); 
     comboBoxItems.append(ro_id); 
     success = setData(createIndex(0, 0), QVariant(comboBoxItems), Qt::EditRole); 
     success &= setData(createIndex(0, 0), QVariant(ro_id), Qt::DisplayRole); 
     SensorDisplayModel::id_no++; 
     success &= setData(createIndex(0, 1), QVariant(QString("Name"))); 
     success &= setData(createIndex(0, 2), QVariant(-1)); 
     success &= setData(createIndex(0, 3), QVariant(-1)); 
     success &= setData(createIndex(0, 4), QVariant((long long)0)); 
     success &= setData(createIndex(0, 5), QVariant(QString("??"))); 
     success &= setData(createIndex(0, 6), QVariant(QString("??"))); 

     if(success) 
      emit dataChanged(createIndex(0, 0), createIndex(0, columnCount() - 1)); 

     ID2Row[data(createIndex(0, 0)).toString()] = selectedRow; 
    } 
} 

SelectedRow ist ein privates Mitglied Das speichert die aktuelle Zeile des Quellmodells.

Die setData() gibt immer false zurück. Das Quellenmodell ist auf manuelle Übermittlung festgelegt. Was mache ich falsch?

Bearbeiten:

Ich erkannte das Problem. Das Quellenmodell, das ich verwende, ist eine Unterklasse von QSqlTableModel, die QSqlQueryModels setData für jede andere Rolle als EditRole aufruft. Da QSqlQueryModel selbst setData nicht neu implementiert, ruft es setData von QAbstractItemModel auf, das immer false zurückgibt.

Also mache ich jetzt alle setData() Aufrufe mit EditRole und data() liefert Werte aus dem Quellmodell, das unter EditRole gespeichert ist.

+0

Welche der beiden 'setData()' Methoden gibt 'false' zurück? I.e. ist die Methode des Proxys, die '' '' ''' '' '' '' ''' alleine zurückgibt oder weil die Methode des Quellenmodells dies getan hat? –

+1

Welche 'false' wird zurückgegeben? Sie haben drei "False" im Proxy-Modell und zwei im Hauptmodell. –

+0

Alle setData-Methoden für das Haupt- und Proxy-Modell geben false zurück. sourceModel() -> setData() gibt false zurück. – user2522981

Antwort

1

Hier legen Sie Daten nur für EditRole und DisplayRole fest. Andere Rollen wie ForegroundRole werden nicht festgelegt, weil Sie false zurückgeben. Offensichtlich müssen Sie beide Modelle nicht unterklassen, weil Ihr Code nichts anderes als die Standardklassen tut. Wenn Sie später einen Code hinzufügen möchten, zumindest die letzte return false in dem ersten Block ändern

return QAbstractProxyModel::setData(index,value,role); 

und letzte return false in dem zweiten Block zu

return QSqlTableModel::setData(index,value,role); 

Auch dies:

if(index.column() != 0) 
     return QSqlTableModel::setData(index, value, Qt::EditRole) && 
      QSqlTableModel::setData(index, value, Qt::DisplayRole); 
    else 
     return QSqlTableModel::setData(index, value, role); 

hat keinen Sinn.

+0

Es tut mir leid..aber ich bin neu zu modellieren/Ansicht Programmierung mit Qt. Ich möchte dieselben Werte für die Edit- und die Display-Rolle für alle außer der ersten Spalte festlegen. Kannst du mir erklären, was ich falsch mache? – user2522981

+0

Sie haben eine Bedingung in Bezug auf diese beiden Rollen. Hier stellen Sie sowieso Daten ein, sei es die 0. Spalte oder eine andere. Wenn/else Block keinen Sinn hat, weil Sie in beiden Fällen denselben Job machen. –

+0

Aber der Wert, den ich übergebe, wird für beide Rollen in der ersten Spalte unterschiedlich sein. Wenn ich den else entfernen würde, würde der Wert für beide Rollen nicht auf die Rolle gesetzt werden, mit der setData() zuletzt aufgerufen wurde? – user2522981