只能使QTreeWidgetItem的一列可编辑

时间:2010-05-10 10:40:15

标签: c++ qt flags qtreewidgetitem

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

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

所有列都可以编辑。

10 个答案:

答案 0 :(得分:27)

您只能使用解决方法使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。

答案 1 :(得分:18)

我最近遇到了同样的问题并发现了一个适用于所有EditTriggers的解决方案,而不仅仅是DoubleClicked(以及与双击信号的连接)

创建一个Delegate,它为编辑器返回一个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));

答案 2 :(得分:8)

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

  1. 将QTreeView与您自己的类派生自QAbstractItemModel并覆盖flags函数

  2. 将QTreeView与QStandardItemModel一起使用。然后,当您添加项目时,只需设置相应的列以允许编辑:

  3. 以下是第二个选项的一些代码:

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

    我发现第二种方法更简单,但这取决于您对模型的灵活程度。

答案 3 :(得分:7)

您似乎必须放弃使用QTreeWidgetQTreeWidgetItem,然后选择QTreeViewQAbstractItemModel。 “Widget”类是便利类,它们是更抽象但更灵活的版本的具体实现。 QAbstractItemModel有一个电话flags(QModelIndex index),您可以在其中返回适当的列值。

答案 4 :(得分: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()

内写下“编辑或不编辑”决策

答案 5 :(得分: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);
}

答案 6 :(得分:2)

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

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。

答案 7 :(得分:1)

我是PySide和Python的新手,但我能够通过注册QTreeWidget来获取itemClicked回调来实现这一点。在回调中,检查列并仅调用'editItem',如果它是您要允许编辑的列。

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

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

答案 8 :(得分: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);
}

答案 9 :(得分:0)

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