27

我有QTreeWidgetItem两列数据,有没有办法只使第二列可编辑?当我执行以下操作时:

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

所有列都变得可编辑。

4

10 回答 10

30

您只能使用解决方法使 QTreeWidget 中的某些列可编辑:

1)设置QTreeWidget的editTriggers属性为NoEditTriggers

2) 在插入项目时,设置 QTreeWidgetItem 对象的 Qt:ItemIsEditable 标志

3) 将以下插槽连接到 QTreeWidget 对象的“itemDoubleClicked”信号:

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

其中“isEditable”是您编写的一个函数,它对可编辑的列返回 true,对不可编辑的列返回 false。

于 2012-11-14T07:22:49.040 回答
22

我最近遇到了同样的问题,并发现了一个适用于所有 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));
于 2011-01-11T11:22:33.860 回答
9

看起来您将不得不放弃使用QTreeWidgetandQTreeWidgetItem并使用QTreeViewand QAbstractItemModel。“Widget”类是更抽象但更灵活版本的具体实现的便利类。QAbstractItemModel有一个调用flags(QModelIndex index),您将在其中为您的列返回适当的值。

于 2010-05-10T12:00:50.290 回答
8

似乎标准的 QTreeWidget 不允许这样做。我认为有两种方法可以做到这一点:

  1. 将 QTreeView 与您自己的从 QAbstractItemModel 派生的类一起使用并覆盖 flags 函数

  2. 将 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);

我发现第二种方法更简单,但这取决于您希望模型具有多大的灵活性。

于 2010-12-01T15:17:33.850 回答
6

我发现最简单的方法是使用 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()

于 2013-07-12T15:45:41.817 回答
3
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);
}
于 2011-02-11T01:21:01.960 回答
3

也许有点晚了,但可能会有所帮助:

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

这里 0 是您要设为只读的列的索引。

flags & (~Qt::ItemIsEditable)

将 ItemIsEditable 位置设置为 0,而不管项目的前一个标志。

flags | Qt::ItemIsEditable

将其设置为 1,而不管先前的标志。

于 2018-03-10T04:27:58.503 回答
1

我发现下面的代码可以很好地满足我的需要,并且“有点”阻止用户编辑列的某些部分:

我基本上检查角色然后列。我只允许在第 0 列中进行编辑。因此,如果用户在任何其他列中对其进行编辑,那么我将停止 setData 编辑并且不会进行任何更改。

void treeItemSubclassed::setData(int column, int role, const QVariant &value) {
    if (role == Qt::ItemIsEditable && column != 0){
        return;
    }
    QTreeWidgetItem::setData(column, role, value);
}
于 2017-11-02T11:09:24.047 回答
0

根据行和列设置树小部件的子级是否可编辑(树的项目)。

于 2010-05-10T11:32:38.970 回答
0

一般来说,我是 PySide 和 Python 的新手,但我能够通过向 QTreeWidget 注册 itemClicked 回调来使其工作。在回调中,检查列并仅在您希望允许编辑的列中调用“editItem”。

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

通过不为第 0 列调用 editItem,该事件基本上被丢弃。

于 2011-01-10T23:59:06.730 回答