我有一个包含两列数据的QTreeWidgetItem
,有没有办法只让第二列可编辑?当我进行以下操作时:
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
所有列都变成可编辑状态。
我有一个包含两列数据的QTreeWidgetItem
,有没有办法只让第二列可编辑?当我进行以下操作时:
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
所有列都变成可编辑状态。
您可以通过以下方法仅使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。
最近我遇到同样的问题,并发现了一个适用于所有EditTriggers(而不仅仅是DoubleClicked)且不需要连接双击信号的解决方案。
创建一个代理,为编辑器返回一个空指针:
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));
index.column()
是否为阻止列来进行检查。您还可以通过将 index.internalPointer()
重新转换为 QTreeWidgetItem*
来访问 QTreeWidgetItem 本身,以便更多地控制何时阻止编辑,例如仅在该项具有子项时阻止编辑(如我的情况)。 - Phlucious看起来你需要放弃使用 QTreeWidget
和 QTreeWidgetItem
,并使用 QTreeView
和 QAbstractItemModel
。 "Widget" 类是便利类,是更抽象但更灵活的版本的具体实现。QAbstractItemModel
有一个调用 flags(QModelIndex index)
的方法,在这个方法中,你需要返回适合你列的适当值。
似乎标准的QTreeWidget不允许这样做。我认为有两种方法可以解决这个问题:
使用一个继承自QAbstractItemModel类并重写flags函数的自定义类来使用QTreeView
使用一个QStandardItemModel的QTreeView。然后当您添加项目时,只需设置适当的列以允许编辑:
以下是第二个选项的一些代码:
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);
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()
内编写“编辑还是不编辑”的决策。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);
}
nullptr
,可能作为else
的一部分。对于应该被编辑的项目,将项目标志设置为Qt::ItemIsEditable
,否则委托将不会被调用。 - CJCombrinkvoid 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)
flags | Qt::ItemIsEditable
void treeItemSubclassed::setData(int column, int role, const QVariant &value) {
if (role == Qt::ItemIsEditable && column != 0){
return;
}
QTreeWidgetItem::setData(column, role, value);
}
我对PySide和Python一般都很陌生,但是我通过在QTreeWidget中注册itemClicked回调函数来使其工作。在回调函数内部,检查列并且只有当它是你想允许编辑的列时才调用'editItem'。
class Foo(QtGui.QMainWindow):
...
def itemClicked(self, item, column):
if column > 0:
self.qtree.editItem(item, column)
如果不为列0调用editItem,则该事件基本上被丢弃了。
根据行和列,设置树状小部件的子项(树的项目)是否可编辑。
QTreeWidgetItem::setFlags
不接受列作为参数。如果是在QTreeWidget
中进行操作,那么应该使用哪种方法? - Andreas Brinck
createEditor
中创建的编辑器连接到你的QRegExpValidator
。请参见此处获取Qt关于如何子类化项目委托的讨论和示例。 - d11QTreeWidget::itemChanged
并在那里实现您的验证。为了防止意外验证其他项目,您可以在调用我回答中的editItem
之前将指向正在编辑的项目的指针添加到QSet<QTreeWidgetItem *>
集合中。在连接到QTreeWidget::itemChanged
的槽中,检查更改的项目是否在此集合中。如果是,则执行验证并从集合中删除它。如果您需要更完整的示例代码,请提出一个新问题并在此处发布该问题的链接。 - d11