Frage

I have a QTreeWidgetItem added to a QTreeWidget:

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

If the item is edited, I want to do a few checks on the new value:

Pairs::Pairs(QWidget *parent) :
QWidget(parent),
  ui(new Ui::Pairs)
{
  ui->setupUi(this);
  connect(this->ui->trwPairs, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(Validate(QTreeWidgetItem*,int)));
}

void Pairs::Validate(QTreeWidgetItem* item, int column)
{
  if (item->text(column).toInt() < 1)
  {
    QMessageBox::critical(this, "Error", QString("Node ID ") + item->text(column) +  " is invalid.");
    ui->trwPairs->editItem(item, column);
  }
}

Naturally, if it's less than 1, it catches it, and gives me the message box. However, printed to cerr is edit: editing failed and the item is not in edit mode. What am I missing?

War es hilfreich?

Lösung

Stepping through it in the debugger reveals the following:

In quabstractitemview.cpp line false is returned on line 3953. Somehow it looks like your item is still in editing state and you are trying to edit it again or something.

bool QAbstractItemViewPrivate::shouldEdit(QAbstractItemView::EditTrigger trigger,
                                          const QModelIndex &index) const
{
// ..
    if (state == QAbstractItemView::EditingState)
      return false;
}

IIRC I had a similar problem with tables with multiple lines per cell. Check out the classes QAbstractItemDelegate views have item delegates which allow you to control which editor is used and how it behaves. I believe by default the QLineEdit is used. Editors like QLineEdit can have validators which control how the data is validated, in your case reject it if the numerical value is < 0. But I think you have to use the model / view classes and implement your own model for that. The Qt documentation for QTreeWidget::setItemWidget(..) says:

This function should only be used to display static content in the place of a tree widget item. If you want to display custom dynamic content or implement a custom editor widget, use QTreeView and subclass QItemDelegate instead.

I am not sure however if there is a simpler way to do this using the widget classes.

Andere Tipps

The problem could be, that you are setting the flags for your items in a very strange way. Simply enable both item-selection, and edit:

item->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);

I had a similar issue where I was attempting to edit the subsequent column upon receiving the itemChanged signal. Based on Nils' analysis that the item was still in the edit state, I changed the signal connection type to QueuedConnection, which allowed the item to leave the state before re-entering it.

I had a similar problem where I'd get the 'edit: editing failed' error when invoking edit() via a shortcut key. I was passing currentIndex() to edit(), but I wasn't checking that the correct column of the selected row was current. I only had the first column editable, so if I had clicked the row (but in any other column) and then invoked my edit key I'd get the error.

I was able to solve my problem by passing the result of sibling(currentIndex().row(), 0) to edit() instead.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top