QTableView with QStandardItemModel: How to perform

2019-09-19 20:27发布

Recently, I made the switch to QT. It has taken some time, but I am starting to find my way around. However, one issue remains:

I want to port a program, that responds to every key press while editing a cell in a table view (QTableView with QStandardItemModel). The idea is to show and update a list of possibilities on a separate form while the user is entering a text in a table view's cell. After every key stroke, the list needs to be updated according to the current text in the edit field of some cell.

Using QTableView::installEventFilter and QEvent::KeyPress, I can get every key press while the table view is in focus, but the cell text / model is only updated after editing, which prohibits live updates of the list.

The model's dataChanged signal is only emitted after editing has finished and not during the user's input.

Any ideas on how to solve this? Should I use a QItemDelegate? Or should a QLineEdit be connected to a cell somehow and can this be done without it visually being apparent, so the user still appears to be working directly inside a cell?

Thank you for any help

2条回答
Root(大扎)
2楼-- · 2019-09-19 20:42

It works (that is, until the main window is resized...)

Perhaps not the best solution, but at least i found a way to make it work. I put the slot in the source file that contains the main window, because that is what I have always been used to (C++ Builder)...

GLiveEdit.H - Subclass QStyledItemDelegate

#ifndef GLIVEEDIT_H
#define GLIVEEDIT_H

#include <QStyledItemDelegate>


class GLiveEdit : public QStyledItemDelegate {

  public:
    GLiveEdit (QObject *_ParentWindow = 0, const char *_Slot = 0);

  protected:
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;


  protected:
    mutable QLineEdit *Editor;
    const char *Slot;
    QWidget *ParentWindow;
};

#endif // GLIVEEDIT_H

GLiveEdit.CPP

#include "gliveedit.h"
#include <QLineEdit>

GLiveEdit::GLiveEdit (QObject *_ParentWindow, const char *_Slot)
  : QStyledItemDelegate (_ParentWindow)

{
  Editor = 0;
  Slot = _Slot;
  ParentWindow = (QWidget *) _ParentWindow;
}


QWidget *GLiveEdit::createEditor(QWidget *parent,
                                    const QStyleOptionViewItem &option,
                                    const QModelIndex &index) const
{
  Editor = (QLineEdit *) QStyledItemDelegate::createEditor (parent, option, index);
  connect (Editor, SIGNAL (textChanged (const QString &)), ParentWindow, Slot);
  return Editor;
}

MainWindow.CPP - Install Subclassed QStyledItemDelegate ("GLiveEdit")

void MainWindow::SetUp()

{
  // Instantiate subclassed QStyledItemDelegate "GLiveEdit" as "Live"
  // Also pass the slot "OnEditChanged" that is to be called during editing
  Live = new GLiveEdit (this, SLOT (OnEditChanged (const QString &)));

  // Tell the table about the instantiated subclassed delegate "Live"
  ui->tvOverview->setItemDelegate (Live);
}


void MainWindow::OnEditChanged (const QString &NewText)

{
  // NewText contains the up to date text that is currently being edited
}

Anyone any ideas on having it also work after the window has been resized? Calling the SetUp function from within QMainWindow::resizeEvent does not seem to work, unfortunately.

Also, I suppose QTableView deletes the item delegate from memory itself?

Edit: The item delegate only stops working if the window is resized during the editing... It keeps functioning if the edit is finished first.

查看更多
叼着烟拽天下
3楼-- · 2019-09-19 20:43

It works! Problems after resizing were due to a bug of mine :-) (located elsewhere in the source code) Any suggestions for improvement still welcome!

查看更多
登录 后发表回答