5

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?

Maxim Makhun
  • 2,197
  • 1
  • 22
  • 26
Drise
  • 4,310
  • 5
  • 41
  • 66
  • So far I can confirm this. I did a small example on my Mac using Qt 4.8 and I also get "edit: editing failed" on the stderr. Have to further investigate, did you already search the Qt source for this string? – Nils Aug 28 '12 at 20:37
  • It seems to be connected somehow to the flags. If I set them again in validate, before calling editItem(..) the warning keeps popping up. – Nils Aug 28 '12 at 20:56
  • @Nils I searched Google 5-6 pages deep on a number of search strings, nothing useful. – Drise Aug 29 '12 at 14:04

4 Answers4

9

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.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
Nils
  • 13,319
  • 19
  • 86
  • 108
  • The primary reason I use the `QTreeWidget` is for the simplicity, especially since I have a number of them scattered throughout the application. Switching to `QTreeView` really isn't much of an option. I'd rather just have a "Edit Item" button that popped up a small dialog, or something to that effect instead. – Drise Aug 29 '12 at 14:02
  • Is there a way I can tell the item to no longer be in edit mode? What about letting the application `processEvents()`? – Drise Aug 29 '12 at 14:05
  • Well, I answered my own question: `processEvents()` is a no. – Drise Aug 29 '12 at 14:18
  • 1
    Well, I've devised a solution. If it's invalid, put the item texts back into the line edits where they came from, remove the item, and force the creation of a new pair, following the text boxes' validator rules. – Drise Aug 29 '12 at 15:23
6

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);
Balázs Édes
  • 13,452
  • 6
  • 54
  • 89
  • What is strange the way flags are set in the example above? – Nils Aug 28 '12 at 20:51
  • 1
    This solution worked for me! Who knew my item wasn't "IsEnabled" enough for it to be editable? Everything else seemed to be working like a normal enabled widget... – K9spud Sep 17 '20 at 02:47
  • I have a python implementation, in which I set the flags when overriding a `QAbstractTableModel` which already does this. This solution did not work for me. – Eduardo Reis Apr 27 '23 at 14:34
  • @EduardoReis if you figure it out, feel free to post a more modern answer, I posted this in 2012, and haven't touched QT in almost a decade :( – Balázs Édes Apr 27 '23 at 15:28
  • 1
    I did a bit of investigation (1 hour or so) trying to get through this. Right now I am postponing figuring this out. I hope to come back to this later at some point. – Eduardo Reis Apr 27 '23 at 16:12
3

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.

user987339
  • 10,519
  • 8
  • 40
  • 45
Kim
  • 728
  • 10
  • 20
  • Did it work? I haven't worked on this project in a while, so I'm not really able to implement/test myself. – Drise Mar 06 '14 at 19:47
  • Yes, this solution worked for me, although I then had to fix other parts of my code which were making bad assumptions about the signal call order. (BTW, thanks for fixing my markup, user987339 - as you can see I'm new to this) – Kim Mar 07 '14 at 12:10
0

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.

shao.lo
  • 4,387
  • 2
  • 33
  • 47