使只有一个列的QTreeWidgetItem编辑
-
25-09-2019 - |
题
我有一个 QTreeWidgetItem
有两列的数据,是否有任何方式使只有第二列中的可编辑?当我做到以下几点:
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setFlags(item->flags() | Qt::ItemIsEditable);
所有列成为编辑。
解决方案
看起来你有使用QTreeWidget
和QTreeWidgetItem
放弃与QTreeView
和QAbstractItemModel
去。 “微件”类是便利类是更抽象的,但更灵活的版本的具体实现。 QAbstractItemModel
具有呼叫flags(QModelIndex index)
,你将返回相应值的列。
其他提示
可以使用一种变通方法使只有某些列在QTreeWidget编辑:
1)将QTreeWidget到NoEditTriggers的editTriggers属性
2)在插入项目中,设置了Qt:所述QTreeWidgetItem对象的ItemIsEditable标志
3)连接的下一个槽的 “itemDoubleClicked” 的QTreeWidget对象的信号:
void MainWindow::onTreeWidgetItemDoubleClicked(QTreeWidgetItem * item, int column)
{
if (isEditable(column)) {
ui.treeWidget->editItem(item, column);
}
}
,其中“isEditable”是你写的,则返回true为可编辑的列和假非可编辑栏的功能。
我最近有同样的问题,并发现其与所有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));
似乎喜欢的标准QTreeWidget不允许这样做。我认为有两种方式来这样做:
使用QTreeView与自己的类源自QAbstractItemModel和复盖标志的功能
使用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);
我找到的第二种办法更简单,但这取决于有多少灵活性,您想要与你的模型。
,我发现的最简单的方法是使用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()
的决定里面
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);
}
也许有点晚,但可以帮助:
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而不管前一标记。
我一般是新来的PySide和Python,但我可以通过与QTreeWidget注册为itemClicked回调得到这个工作。在回调,检查列,只称之为“editItem”如果是为了要允许编辑列。
class Foo(QtGui.QMainWindow):
...
def itemClicked(self, item, column):
if column > 0:
self.qtree.editItem(item, column)
通过不调用editItem用于列0,该事件被基本上丢弃。
我发现下面很适合我的需要的代码,也“有点”停止 用户编辑列的某些部分:
我基本检查角色,然后列。我只允许在第0列所以编辑如果在任何其他列用户编辑它,然后我停止使用setData编辑和没有改变正在取得。
void treeItemSubclassed::setData(int column, int role, const QVariant &value) {
if (role == Qt::ItemIsEditable && column != 0){
return;
}
QTreeWidgetItem::setData(column, role, value);
}
集的子树的小部件可编辑与否(树的次),基于该行和列。