只能使QTreeWidgetItem的一列可编辑

And*_*nck 26 c++ flags qt qtreewidgetitem

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

QTreeWidgetItem* item = new QTreeWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
Run Code Online (Sandbox Code Playgroud)

所有列都可以编辑.

d11*_*d11 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

其中"isEditable"是您编写的函数,对于可编辑列返回true,对不可编辑列返回false.

  • 双击不是开始编辑的唯一方法,但有很多其他编辑触发器(任何键,编辑键(Windows/Linux上的F2),当前项目已更改等),具体取决于配置( setEditTriggers).所以这看起来有点不完整. (7认同)

小智 20

我最近遇到了同样的问题并发现了一个适用于所有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;
      }
    };
Run Code Online (Sandbox Code Playgroud)

然后将其用作列的自定义委托

ui->parameterView->setItemDelegateForColumn(0, new NoEditDelegate(this));
Run Code Online (Sandbox Code Playgroud)

  • 很棒的选择.您还可以将委托分配给整个视图,并通过检查`index.column()`来检查它是否是阻塞列.您还可以通过将`index.internalPointer()`重新编写为`QTreeWidgetItem*'来访问QTreeWidgetItem本身,以便更好地控制何时阻止编辑,例如仅在项目有子项时阻止编辑(如我的情况) . (2认同)

Har*_*ich 8

看起来你将不得不使用放弃QTreeWidget,并QTreeWidgetItem与去QTreeViewQAbstractItemModel."Widget"类是便利类,它们是更抽象但更灵活的版本的具体实现.QAbstractItemModel有一个调用flags(QModelIndex index),您将返回列的适当值.

  • 不一定(如果我没有记错的话).请参阅下面的答案. (2认同)

Bla*_*ise 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);
Run Code Online (Sandbox Code Playgroud)

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


cla*_*ark 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

顶部if通过a添加编辑功能OR,底部检查是否存在AND,然后用a删除它XOR.

这样,编辑功能会在您需要时添加,并在您不需要时删除.

然后将此函数连接到树窗口小部件的itemDoubleClicked()信号,并在其中写下"编辑或不编辑"的决定isEditable()