Domanda

Ho bisogno di implementare un meccanismo per evidenziare i valori duplicati.I valori vengono modificati tramite delegate a seconda del tipo di valore (stringa - modifica riga, numeri decimali lunghi e grandi - caselle di selezione).Attualmente, ho implementato questa funzionalità con l'aiuto di una classe aggiuntiva che memorizza tutti i valori e il loro conteggio in due elenchi "paralleli".E dopo aver aggiunto un nuovo valore aumento il suo numero di conteggio (o diminuisco quando viene rimosso il valore ripetuto), ma questa soluzione sembra essere troppo ingombrante.Avete altre idee per evidenziare nel metodo setModelData(...) di 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);
        }
    }
}
È stato utile?

Soluzione

Di solito utilizzo le mappe per questo tipo di attività:

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

L'evidenziazione ora dovrebbe essere abilitata se

values.get(value) > 1

è true.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top