Dies ist mein erster Beitrag hier, aber ich habe eine Menge Hilfe von euch allen bekommen, seit ich angefangen habe zu programmieren.Wie können die zugrunde liegenden Daten von QAbstractTableModel vollständig geändert werden?
Ich bin neu in Qt und versuche im Moment mein erstes Projekt zu machen. Meine Frage betrifft die Kommunikation zwischen dem Modell, den zugrunde liegenden Daten und der Sichtweise.
Ich habe zuerst die Hintergrund-Dinge (Datenspeicherung etc.) von der GUI getrennt. Jetzt habe ich eine Vorlage Klasse Matrix
und ich schrieb eine Vorlage Klasse MatrixModel
, die von QAbstractTableModel
erbt. Dies funktioniert gut, bedeutet, dass ich die Tabelle bearbeiten kann und die Werte in der Ansicht und in den Daten vom Modell aktualisiert werden.
Nun meine Frage: Wie ändere ich die Daten im Modell, ohne eine neue Methode zu schreiben?
mainwindow.cpp:
matrix<int> m = {{1,2,3},{4,5,6},{7,8,9}};
MatrixModel<int>* model = new MatrixModel<int>(m);
QTableView* tableView = new QTableView;
tableView->setModel(model);
Gibt es eine Möglichkeit m.transpose()
auf das Modell der zugrunde liegenden Daten zu nennen? Was passiert, wenn ich m
ändere? Beeinflusst es die Daten des Modells? Ich habe viele Dinge ausprobiert, aber nichts hat funktioniert. Ein "Problem" ist, dass ich Standard-Signal/Slot-Syntax nicht verwenden kann, weil ich mit Template-Klassen arbeite.
Mein letzter Versuch war eine Update Klasse im Modell zu machen:
template<typename T>
void MatrixModel<T>::updateAll() {
QModelIndex topLeft = index(0,0);
QModelIndex bottomRight = index(rowCount()-1, columnCount()-1);
emit dataChanged(topLeft, bottomRight);
}
und ich versuchte es mit einem Knopf zu verbinden und eine Lambda-Funktion:
connect(transposeButton, &QPushButton::clicked, [=,&m,&model]() {
m.transpose(); model->updateAll();
});
aber das schien zu abstürzen mein Programm, wenn ich den Knopf drücke. Ich bin wirklich verzweifelt xD hoffe du kannst mir helfen. Wenn Sie weitere Informationen benötigen, wenden Sie sich bitte einfach ^^
Mit freundlichen Grüßen
Dennis
EDIT 1: Okay, so weit ich herausgefunden (mit Ihrer Hilfe :)), dass ich die Funktionen schreiben haben, die Matrix erneut im Modell (z. B. transpose()) und Datenänderungen von dort (mit emittieren dataChanged oder beginResetModel() ...), aber ich kann die zugrunde liegenden Daten Modelle nicht ändern. Wenn ich
schreibe dies im Hauptfenster: Abstürze
template<typename T>
void MatrixModel<T>::transpose() {
m(0,0) = 5;
}
mein Programm nur, wenn ich die Taste transponieren drücken:
connect(transposeButton, &QPushButton::clicked, [&model]() {
model->transpose();
});
dies im Modell. Wenn ich die Zeile
m(0,0) = 5;
kommentieren, funktioniert alles.
EDIT 2: Vielleicht gibt es ein Problem mit der Datenspeicherung, so ist hier mein Copykonstruktor und die privaten Variablen meiner Matrix-Klasse:
private:
std::vector <T> data;
size_t rows, columns;
//Copy constructor
template<typename T>
matrix<T>::matrix(const matrix<T>& other)
: rows(other.rows), columns(other.columns) {
data = other.data;
}
Wenn sich die Abmessungen deines Modells ändern, 'dataChanged() 'Signal ist nicht genug. Sie sollten 'beginResetModel()' aufrufen, bevor Sie Daten ändern, und dann 'endResetModel()' aufrufen, wenn Sie fertig sind. . . – Mike
Wenn also Ihre Matrix nicht quadratisch ist, kann der Aufruf von 'transpose()' nur das 'dataChanged()' Signal auslösen und zu ungültigen Indizes in Ihrer Matrix führen. – Mike
Okay, ich verstehe, aber ich kann nur anrufen das von meinem Modell. Aber ich rufe die Funktion m.transpose() von meinem Hauptfenster.cpp auf, wo ich das beginResetModel nicht aufrufen kann (weil es geschützt ist). Und ich möchte nicht alle Funktionen in meinem Matrixmodell neu schreiben. – syc