Domanda

Ho un QTreeWidgetItem con due colonne di dati, c'è un modo per fare solo la seconda colonna modificabile? Quando faccio la seguente:

QTreeWidgetItem* item = new QTreeWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);

tutte le colonne diventano modificabili.

È stato utile?

Soluzione

Sembra che si dovrà rinunciare utilizzando QTreeWidget e QTreeWidgetItem e andare con QTreeView e QAbstractItemModel. Le classi "widget" sono classi di convenienza che sono implementazioni concrete delle versioni più astratti, ma più flessibili. QAbstractItemModel ha un flags(QModelIndex index) chiamata in cui si desidera restituire il valore appropriato per la colonna.

Altri suggerimenti

È possibile effettuare solo alcune colonne in una modificabile QTreeWidget utilizzando una soluzione:

1) Impostare la proprietà editTriggers del QTreeWidget a NoEditTriggers

2) Sugli articoli inserimento, impostare il Qt: bandiera ItemIsEditable dell'oggetto QTreeWidgetItem

3) Collegare il seguente slot a "itemDoubleClicked" segnale dell'oggetto QTreeWidget:

void MainWindow::onTreeWidgetItemDoubleClicked(QTreeWidgetItem * item, int column)
{
    if (isEditable(column)) {
        ui.treeWidget->editItem(item, column);
    }
}

dove "IsEditable" è una funzione che hai scritto che restituisce true per colonne modificabili e falsi per le colonne non modificabili.

Ho avuto lo stesso problema da poco e ho scoperto una soluzione che funziona con tutti i EditTriggers, non solo il DoubleClicked uno (ed il collegamento al segnale fa doppio clic)

crea un delegato, che restituisce un puntatore nullo per l'editor:

class NoEditDelegate: public QStyledItemDelegate {
    public:
      NoEditDelegate(QObject* parent=0): QStyledItemDelegate(parent) {}
      virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
        return 0;
      }
    };

E poi usarlo come un delegato personalizzato per la colonna

ui->parameterView->setItemDelegateForColumn(0, new NoEditDelegate(this));

sembrare la norma QTreeWidget non consente questo. Penso che ci siano due modi per farlo:

  1. Usa un QTreeView con la propria classe derivata da QAbstractItemModel e ignorare le bandiere funzione

  2. Usa un QTreeView con un QStandardItemModel. Poi, quando si aggiunge la voce è sufficiente impostare la colonna appropriata per consentire modifiche:

Ecco un po 'di codice per la seconda opzione:

QString x, y;
QList<QStandardItem*> newIt;
QStandardItem * item = new QStandardItem(x);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
newIt.append(item);
item = new QStandardItem(y);
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable);
newIt.append(item);
model->appendRow(newIt);

Trovo il secondo approccio più semplice, ma che dipende da quanto la flessibilità che vuoi con il tuo modello.

Il modo più semplice che ho trovato è stato quello di utilizzare Qt :: ItemFlags

void myClass::treeDoubleClickSlot(QTreeWidgetItem *item, int column)
{
    Qt::ItemFlags tmp = item->flags();
    if (isEditable(item, column)) {
        item->setFlags(tmp | Qt::ItemIsEditable);
    } else if (tmp & Qt::ItemIsEditable) {
        item->setFlags(tmp ^ Qt::ItemIsEditable);
    }
}

La parte superiore della if aggiunge la funzionalità di editing attraverso un OR, ei controlli di fondo, se è lì con AND, quindi rimuove con un XOR.

In questo modo si aggiunge la funzionalità di editing quando lo si desidera, e rimosso quando non lo fai.

Quindi collegare questa funzione per il segnale itemDoubleClicked() del widget albero, e scrivere il vostro 'per modificare o di non modificare' decisione all'interno del isEditable()

class EditorDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    EditorDelegate(QObject *parent):QItemDelegate(parent){};
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

QWidget* EditorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if(index.column() == 1)
    {
        return QItemDelegate::createEditor(parent, option, index);
    }
    return nullptr;
}

Nel QTreeWidget:

myQTreeWidget::myQTreeWidget()
{
    EditorDelegate *d = new EditorDelegate(this);
    this->setItemDelegate(d);
}

Forse un po 'tardi, ma può aiutare:

void MyClass::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column) {
    Qt::ItemFlags flags = item->flags();
    if(column == 0)
    {
        item->setFlags(flags & (~Qt::ItemIsEditable));
    }
    else
    {
        item->setFlags(flags | Qt::ItemIsEditable);
    } 
}

Ecco 0 è l'indice della colonna che si vuole fare in sola lettura.

flags & (~Qt::ItemIsEditable)

Imposta la posizione ItemIsEditable a 0 indipendentemente bandiera precedente del vostro articolo.

flags | Qt::ItemIsEditable

imposta su 1, indipendentemente bandiera precedente.

Sono nuovo di PySide e Python in generale, ma sono stato in grado di ottenere questo al lavoro registrando con la QTreeWidget per callback itemClicked. All'interno della richiamata, controllare la colonna e solo chiamare 'editItem' se è per una colonna che si desidera consentire la modifica.

class Foo(QtGui.QMainWindow):
...
def itemClicked(self, item, column):
   if column > 0:
      self.qtree.editItem(item, column)

Per non invocando editItem per la colonna 0, l'evento è praticamente eliminato.

ho scoperto che il codice qui sotto funziona bene per le mie esigenze e non "un pò" fermare la all'utente di modificare alcune parti di colonne:

Io fondamentalmente controllare per il ruolo e la colonna poi. Mi permetto solo per la modifica nella colonna 0. Quindi se l'utente modifica in qualsiasi altra colonna, poi mi fermo la modifica setData e nessun cambiamento è stato fatto.

void treeItemSubclassed::setData(int column, int role, const QVariant &value) {
    if (role == Qt::ItemIsEditable && column != 0){
        return;
    }
    QTreeWidgetItem::setData(column, role, value);
}

Imposta il figlio del tree-widget di modificabile o meno (tempi di albero), in base alla riga e colonna.

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