Pregunta

Tengo un QTreeWidgetItem con dos columnas de datos, ¿hay alguna manera de hacer sólo la segunda columna editable? Cuando hago lo siguiente:

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

todas las columnas se pueden editar.

¿Fue útil?

Solución

Parece que tendrá que renunciar a usar QTreeWidget y QTreeWidgetItem e ir con QTreeView y QAbstractItemModel. Las clases "Widget" son clases de conveniencia que son implementaciones concretas de las versiones más abstractas pero más flexibles. QAbstractItemModel tiene una flags(QModelIndex index) llamada donde le devuelva el valor adecuado para su columna.

Otros consejos

Se puede hacer sólo ciertas columnas en un editable QTreeWidget usando una solución:

1) Establecer la propiedad editTriggers del QTreeWidget a NoEditTriggers

2) En artículos Insertar, establecer el Qt: bandera ItemIsEditable del objeto QTreeWidgetItem

3) Conectar la siguiente ranura a la "itemDoubleClicked" señal del objeto QTreeWidget:

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

donde "isEditable" es una función que escribió que devuelve true de columnas editables y falsas para las columnas no editables.

Yo tenía el mismo problema hace poco y descubrí una solución que funciona con todos los EditTriggers, no sólo el doubleclicked uno (y la conexión a la señal hecho doble clic)

Crear un delegado, que devuelve un puntero nulo para el 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;
      }
    };

Y más tarde utilizarlo como un delegado a medida para su columna

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

parecer la norma QTreeWidget no permite esto. Creo que hay dos maneras de hacer esto:

  1. Utilice un QTreeView con su propia clase derivada de QAbstractItemModel y modifique las opciones de función

  2. Utilice un QTreeView con un QStandardItemModel. Luego, cuando se agrega el elemento acaba de establecer la columna apropiada para permitir ediciones:

Aquí hay un código para la segunda opción:

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

Me parece que el segundo enfoque más simple, pero eso depende de la cantidad de flexibilidad que quiera con su modelo.

La forma más sencilla que encontré fue utilizar 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 superior de la if añade la funcionalidad de edición a través de una OR, y los controles de fondo si está allí con AND, luego lo elimina con un XOR.

De esta manera la funcionalidad de edición se añade cuando lo desee, y se retira cuando no lo hace.

A continuación, conectar esta función para la señal itemDoubleClicked() del widget árbol y escribir tu 'a editar o no a editar' decisión dentro de 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;
}

En el QTreeWidget:

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

Tal vez un poco tarde, pero puede ayudar a:

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

A continuación, 0 es el índice de la columna que desea hacer de sólo lectura.

flags & (~Qt::ItemIsEditable)

Establece la posición ItemIsEditable a 0 sin tener en cuenta la anterior bandera de su artículo.

flags | Qt::ItemIsEditable

lo establece en 1, independientemente del pabellón anterior.

soy nuevo en PySide y Python en general, pero yo era capaz de conseguir que esto funcione registrándose con el QTreeWidget para devoluciones de llamada itemClicked. Dentro de la devolución de llamada, marque la columna y sólo llamar 'editItem' si es para una columna que desee permitir la edición.

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

Al no invocar editItem para la columna 0, el evento es básicamente descarta.

Me di cuenta de que el código de abajo funciona bien para mis necesidades y no "algo" detener la el usuario no podrá modificar ciertas partes de columnas:

Yo, básicamente, comprobar si hay papel y la columna a continuación. Sólo permitir la edición en la columna 0. Por lo tanto, si el usuario editar en cualquier otra columna, entonces hago para detener el setData editar y no se hace ningún cambio.

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

Configurar el niño del árbol en widgets o no editables (tiempos de árbol), basado en la fila y columna.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top