Подтвердить что ты не робот

Создание только одного столбца QTreeWidgetItem для редактирования

У меня есть QTreeWidgetItem с двумя столбцами данных, есть ли способ сделать только второй отредактированный столбец? Когда я делаю следующее:

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

все столбцы становятся редактируемыми.

4b9b3361

Ответ 1

Похоже, вам придется отказаться от использования QTreeWidget и QTreeWidgetItem и перейти с QTreeView и QAbstractItemModel. Классы "Виджет" - это классы удобства, которые являются конкретными реализациями более абстрактных, но более гибких версий. QAbstractItemModel имеет вызов flags(QModelIndex index), где вы вернете соответствующее значение для своего столбца.

Ответ 2

Вы можете сделать только определенные столбцы в редакторе QTreeWidget с помощью обходного пути:

1) Задайте свойство editTriggers для QTreeWidget для NoEditTriggers

2) При вставке элементов установите флаг Qt: ItemIsEditable объекта QTreeWidgetItem

3) Подключите следующий слот к сигналу "itemDoubleClicked" объекта QTreeWidget:

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

где "isEditable" - это функция, которую вы написали, которая возвращает true для редактируемых столбцов и false для не редактируемых столбцов.

Ответ 3

У меня была такая же проблема в последнее время и я обнаружил решение, которое работает со всеми EditTriggers, а не только с DoubleClicked (и соединение с двойным щелчком)

Создать делегат, который возвращает указатель NULL для редактора:

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

И позже использовать его как пользовательский делегат для столбца

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

Ответ 4

Похоже, что стандартный QTreeWidget не позволяет этого. Я думаю, что есть два способа сделать это:

  • Используйте QTreeView со своим собственным классом, производным от QAbstractItemModel, и переопределите функцию flags

  • Используйте QTreeView с QStandardItemModel. Затем, когда вы добавляете элемент, просто установите соответствующий столбец для внесения изменений:

Вот код для второго варианта:

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

Я считаю, что второй подход проще, но это зависит от того, какую гибкость вы хотите использовать в своей модели.

Ответ 5

Самый простой способ, который я нашел, - использовать 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);
    }
}

Верхняя часть if добавляет функции редактирования через OR, а нижняя - если она есть с AND, а затем удаляет ее с помощью XOR.

Таким образом, функциональность редактирования добавляется, когда вы этого хотите, и удаляется, когда вы этого не делаете.

Затем подключите эту функцию к сигналу виджета дерева itemDoubleClicked() и напишите свое решение "редактировать или не редактировать" внутри isEditable()

Ответ 6

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

В QTreeWidget:

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

Ответ 7

Установите дочерний элемент дерева-виджета для редактирования или нет (itmes дерева) на основе строки и столбца.

Ответ 8

Я новичок в PySide и Python в целом, но мне удалось заставить это работать, зарегистрировавшись с помощью QTreeWidget для обратных вызовов itemClicked. В пределах обратного вызова проверьте столбец и вызовите только "editItem", если он для столбца, который вы хотите разрешить редактирование.

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

Не вызывая editItem для столбца 0, событие в основном отбрасывается.

Ответ 9

Я узнал, что приведенный ниже код хорошо работает для моих нужд и делает "любопытное" прекращение пользователь может редактировать некоторые части столбцов:

Я в основном проверяю роль, а затем - столбец. Я разрешаю только редактирование в столбце 0. Поэтому, если пользователь отредактирует его в любом другом столбце, я остановлю редактирование setData и никаких изменений не будет.

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