Ft: Wie hebe ich doppelte Elemente in QListWidget hervor?(qtjambi)
-
29-10-2019 - |
Frage
Ich muss einen Mechanismus zum Hervorheben doppelter Werte implementieren.Die Werte werden je nach Werttyp durch Delegieren bearbeitet (String-Line-Edit, lange und große Dezimal-Spin-Boxen).Derzeit habe ich diese Funktion mit Hilfe einer zusätzlichen Klasse implementiert, die alle Werte und ihre Anzahl in zwei "parallelen" Listen speichert.Und nachdem ich einen neuen Wert hinzugefügt habe, erhöhe ich die Anzahl (oder verringere sie, wenn der wiederholte Wert entfernt wird), aber diese Lösung scheint zu sperrig zu sein.Habt ihr noch andere Ideen zum Hervorheben der setModelData(...)
-Methode von QItemDelegate?
/**
* Stores a delegates' existing values
*/
private final class DelegateValuesStorage {
private final List<Object> values = new ArrayList<Object>();
private final List<Integer> counts = new ArrayList<Integer>();
....
//Add value or increase a count if exists
public void add(final Object value) {
if(values.contains(value)) {
final int valueIndex = values.indexOf(value);
final int oldCount = counts.get(valueIndex);
counts.remove(valueIndex);
counts.add(valueIndex, oldCount + 1);
} else {
values.add(value);
counts.add(1);
}
}
....
//Decrease a count or remove value if it doesn't exist anymore
public void decreaseCount(final Object value) {
if(value == null) {
return;
}
final int index = values.indexOf(value);
if(index >= 0) {
final int oldCount = counts.get(index);
if(oldCount >= 2) {
counts.remove(index);
counts.add(index, oldCount - 1);
} else {
values.remove(index);
counts.remove(index);
}
}
}
/**
* Delegate
*/
private class ConcreteDelegate extends QItemDelegate {
private final DelegateValuesStorage values = new DelegateValuesStorage();
...
@Override
public void setModelData(final QWidget editor, final QAbstractItemModel model, final QModelIndex index) {
if(editor instanceof ValEditor) { // ValEditor is an abstraction of line edit and spin box over values' data types
final Object value = ((ValEditor) editor).getValue();
model.setData(index, value, Qt.ItemDataRole.UserRole);
final String newData = (value == null) ? "" : String.valueOf(value);
values.add(newData);
final String oldData = (String) model.data(index, Qt.ItemDataRole.DisplayRole);
values.decreaseCount(oldData);
model.setData(index, newData, Qt.ItemDataRole.DisplayRole);
model.setData(index, new QColor(0, 0, 0), Qt.ItemDataRole.ForegroundRole);
redrawItems(model); // runs through values and colors them red if count >= 2; or black if count == 1
} else {
super.setModelData(editor, model, index);
}
}
}
Lösung
Normalerweise verwende ich Karten für diese Art von Aufgaben:
private final class DelegateValuesStorage {
private final Map<Object, Integer> values = new HashMap<Object, Integer>();
....
//Add value or increase a count if exists
public void add(final Object value) {
Integer count = values.get(value);
if (count == null) {
values.put(value, 1);
} else {
values.put(value, count + 1);
}
}
....
//Decrease a count or remove value if it doesn't exist anymore
public void decreaseCount(final Object value) {
if(value == null) {
return;
}
Integer count = values.get(value);
if (count == null) {
// decreasing a "new" value - could be an error too
return;
}
if (count <= 1) {
// remove the value from the map
values.remove(value);
} else {
values.put(value, count - 1);
}
}
}
Das Hervorheben sollte jetzt aktiviert sein, wenn
values.get(value) > 1
ist true
.