QT: Comment puis-je mettre en évidence les éléments dupliqués dans QListWidget? (qtjambi)

StackOverflow https://stackoverflow.com/questions/7383979

Question

J'ai besoin de mettre en œuvre un mécanisme de mise en évidence des valeurs dupliquées. Les valeurs sont modifiées via le délégué en fonction du type de valeur (String - édition de ligne, boîtes à rotation long et grandes). Actuellement, j'ai implémenté cette fonctionnalité à l'aide d'une classe supplémentaire qui stocke toutes les valeurs et leur nombre dans deux listes "parallèles". Et après avoir ajouté une nouvelle valeur, j'augmente son nombre de comptes (ou la diminution lorsque la valeur répétée est supprimée), mais cette solution semble être trop volumineuse. Avez-vous d'autres idées sur la mise en évidence dans setModelData(...) Méthode de 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);
        }
    }
}
Était-ce utile?

La solution

J'utilise généralement des cartes pour ce type de tâches:

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);
        }
    }
}

La mise en évidence maintenant devrait être activée si

values.get(value) > 1

est true.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top