仅使 QTreeWidgetItem 的一列可编辑

发布于 2024-09-01 02:54:25 字数 211 浏览 11 评论 0原文

我有一个包含两列数据的 QTreeWidgetItem,有什么方法可以使第二列可编辑吗?当我执行以下操作时:

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

所有列都变为可编辑。

I have a QTreeWidgetItem with two columns of data, is there any way to make only the second column editable? When I do the following:

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

all columns become editable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

天赋异禀 2024-09-08 02:54:25

您可以使用解决方法仅使 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。

You can make only certain columns in a QTreeWidget editable using a workaround:

1) Set the editTriggers property of the QTreeWidget to NoEditTriggers

2) On inserting items, set the Qt:ItemIsEditable flag of the QTreeWidgetItem object

3) Connect the following slot to the "itemDoubleClicked" signal of the QTreeWidget object:

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

where "isEditable" is a function you wrote that returns true for editable columns and false for non-editable columns.

女中豪杰 2024-09-08 02:54:25

我最近遇到了同样的问题,发现了一种适用于所有 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));

I had the same problem recently and discovered a solution which works with all EditTriggers, not only the DoubleClicked one (and the connection to the double clicked signal)

Create a Delegate, that returns a NULL Pointer for the 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;
      }
    };

And later use it as a custom delegate for your column

ui->parameterView->setItemDelegateForColumn(0, new NoEditDelegate(this));
坐在坟头思考人生 2024-09-08 02:54:25

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

Looks like you will have to forgo using QTreeWidget and QTreeWidgetItem and go with QTreeView and QAbstractItemModel. The "Widget" classes are convenience classes that are concrete implementations of the more abstract but more flexible versions. QAbstractItemModel has a call flags(QModelIndex index) where you would return the appropriate value for your column.

别靠近我心 2024-09-08 02:54:25

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

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

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

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

Seem like the standard QTreeWidget doesn't allow this. I think there are two ways to do this:

  1. Use a QTreeView with your own class derived from QAbstractItemModel and override the flags function

  2. Use a QTreeView with a QStandardItemModel. Then when you add the item just set the appropriate column to allow edits:

Here's some code for the second option:

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

I find the second approach simpler but that depends on how much flexibility you want with your model.

暖伴 2024-09-08 02:54:25

我发现的最简单的方法是使用 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 添加编辑功能,底部检查它是否存在 < code>AND,然后使用 XOR 将其删除。

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

然后将此函数连接到树小部件的 itemDoubleClicked() 信号,并在 isEditable() 内写入您的“编辑或不编辑”决策

The simplest way that I found was to use 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);
    }
}

The top of the if adds the editing functionality through an OR, and the bottom checks if it is there with AND, then removes it with a XOR.

This way the editing functionality is added when you want it, and removed when you don't.

Then connect this function to the tree widget's itemDoubleClicked() signal, and write your 'to edit or not to edit' decision inside of isEditable()

短暂陪伴 2024-09-08 02:54:25
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);
}
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;
}

In the QTreeWidget:

myQTreeWidget::myQTreeWidget()
{
    EditorDelegate *d = new EditorDelegate(this);
    this->setItemDelegate(d);
}
宁愿没拥抱 2024-09-08 02:54:25

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

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。

Maybe a little late, but may help :

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

Here 0 is the index of the column you want to make readonly.

flags & (~Qt::ItemIsEditable)

Sets the ItemIsEditable position to 0 regardless the previous flag of your item.

flags | Qt::ItemIsEditable

Sets it to 1 regardless the previous flag.

深爱成瘾 2024-09-08 02:54:25

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

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

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

I found out that the code below works well for my needs and does "kinda" stop the
user from editing certain parts of columns:

I basically check for role and then column. I only allow for editing in column 0. So if user edit it in any other column, then I stop the setData edit and no change is being made.

void treeItemSubclassed::setData(int column, int role, const QVariant &value) {
    if (role == Qt::ItemIsEditable && column != 0){
        return;
    }
    QTreeWidgetItem::setData(column, role, value);
}
呆橘 2024-09-08 02:54:25

根据行和列设置树小部件的子项可编辑或不可编辑(树的项)。

Set the child of the tree-widget editable or not(itmes of tree), based on the row and column.

木有鱼丸 2024-09-08 02:54:25

一般来说,我对 PySide 和 Python 很陌生,但我可以通过向 QTreeWidget 注册 itemClicked 回调来使其工作。在回调中,检查列,并且仅当您想要允许编辑的列时才调用“editItem”。

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

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

I'm new to PySide and Python in general, but I was able to get this to work by registering with the QTreeWidget for itemClicked callbacks. Within the callback, check the column and only call 'editItem' if it's for a column you want to allow editing.

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

By not invoking editItem for column 0, the event is basically discarded.

苦行僧 2024-09-08 02:54:25

对于那些寻找 Olaf Schumann 的答案 的 PyQt 实现的人,可以使用类似的方法。

首先,我们对自定义项委托进行子类化,返回 None (无编辑器小部件):

from qgis.PyQt.QtWidgets import QStyledItemDelegate


class NonEditableDelegate(QStyledItemDelegate):
    def createEditor(self, _parent, _option, _index):
        return None

然后,我们将自定义委托应用于所需的列

tree.setItemDelegateForColumn(0, NonEditableDelegate())

For those looking for a PyQt implementation of Olaf Schumann's answer, a similar approach is possible.

First, we sub-class our custom item delegate, returning None (no editor widget):

from qgis.PyQt.QtWidgets import QStyledItemDelegate


class NonEditableDelegate(QStyledItemDelegate):
    def createEditor(self, _parent, _option, _index):
        return None

Then, we apply the custom delegate to the desired column

tree.setItemDelegateForColumn(0, NonEditableDelegate())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文