QTableView/QAbstractTableModel Text disappears after double click



  • I need a table editor for a custom model. As explained in the Qt tutorial I enabled the Qt::ItemIsEditable flag and implemented setData() in the model. Editing works fine so far, but there is one little detail I don't like about it. After double clicking an element the text in the cell is removed (it comes back again if I press escape) and I can enter new text. I would like a more MS Excel like editing behavior where the text is not removed and the cursor is placed at the point where the user double clicked.

    I have been reading the docs about the classes involved a bit and QAbstractItemDelegate caught my attention. The docs show an example where the string in the cell is replaced with a progress bar. I wonder in order to get the desired editing behavior do I need to implement my own ItemDelegate or is there a simple way to do this?



  • Just read that data() is also called when editing, so if I just also return text if the role is Qt::EditRole the text does not disappear after double clicking! However the whole text is selected (I would like to have just the cursor at the right place) and it does not seem to open a multi-line on tables with multiple cells.



  • You will need to create your own delegate to do the cursor positioning. That should not be too hard. I don't understand what you mean by your last phrase. What do you expect to happen exactly?



  • Thx for your quick replay, I am new to Qt and therefore need to learn a few concepts (like delegates) first..

    bq. it does not seem to open a multi-line on tables with multiple cells.

    Ooops I mean a multi-line editor of course. The QTableView displays text with multiple lines, but when editing I can only edit one line. Also pasting a multi-line string from a text editor ends up on one line.



  • The problem is, that the default delegate will be a QLineEdit, which is a single-line editor widget. You will need to make sure that a QTextEdit or QPlainTextEdit is used instead. One way to do that is by creating your own delegate.



  • My solution so far:

    @// views is a of type QTableView*
    QAbstractItemDelegate *itemDelegate = view->itemDelegate();

    // Not sure why this is QStyledItemDelegate and not just QItemDelegate.
    // But QStyledItemDelegate also offers setItemEditorFactory(..) so this
    // is fine.
    assert(typeid(QStyledItemDelegate) == typeid(*itemDelegate));

    QStyledItemDelegate *styledItemDelegate
    = dynamic_cast<QStyledItemDelegate *>(itemDelegate);

    QItemEditorFactory *editorFactory = new QItemEditorFactory;

    // "plainText" is the name of the property of the QPlainTextEdit which
    // contains the editing data.
    QItemEditorCreatorBase *creator =
    new QItemEditorCreator<QPlainTextEdit>("plainText");

    editorFactory->registerEditor(QVariant::String, creator);

    styledItemDelegate->setItemEditorFactory(editorFactory);@

    Now I also need to figure out how to place the cursor correctly, right now it is always before the beginning of the string.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.