QTableWidgetItem doesn't have multiline edit mode?
-
Hi,
Create a custom QStyledItemDelegate and provide a QTextEdit as editor in place of QLineEdit.
-
This post is deleted!
-
Hi,
Create a custom QStyledItemDelegate and provide a QTextEdit as editor in place of QLineEdit.
@SGaist OK that basically works. However the user can't tap Return to exit the multiline editing mode. What could I do to enable that? I prefer to have multiple lines that wrap, and maybe a Shift-Return for a line break, but the Return key still has to exit editing mode.
-
@SGaist OK that basically works. However the user can't tap Return to exit the multiline editing mode. What could I do to enable that? I prefer to have multiple lines that wrap, and maybe a Shift-Return for a line break, but the Return key still has to exit editing mode.
@Publicnamer
Then subclass and override e.g. QTextEdit::keyPressEvent(QKeyEvent *e). Or write an eventFiilter(). -
@Publicnamer
Then subclass and override e.g. QTextEdit::keyPressEvent(QKeyEvent *e). Or write an eventFiilter().@JonB said in QTableWidgetItem doesn't have multiline edit mode?:
@Publicnamer
Then subclass and override e.g. QTextEdit::keyPressEvent(QKeyEvent *e). Or write an eventFiilter().I tried the first option, but it appears subclassing QPlainTextEdit isn't a matter of just subclassing. It wants me to implement some things like createEditor etc.
As for adding an event filter, isn't there a simple way to inject a closure into the text editor to intercept events? Why is subclassing always the solution? Seems like the wrong way.
-
Because it's C++ not an interpreted language like Python.
As @JonB suggested, you can implement an event filter in place of subclassing in this case.
@SGaist Who's using Python? In many modern compiled languages like Objective-C and Swift, you can do some useful amount of injection of closures.
Anyway, it seemed to me that the eventFilter required subclassing as well. Not so?
-
@SGaist Who's using Python? In many modern compiled languages like Objective-C and Swift, you can do some useful amount of injection of closures.
Anyway, it seemed to me that the eventFilter required subclassing as well. Not so?
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
I tried the first option, but it appears subclassing QPlainTextEdit isn't a matter of just subclassing. It wants me to implement some things like createEditor etc.
You do not have to supply
createEditor()etc. You should be able to subclass and only override whatever you need to. However, you are going down theeventFilter()route anyway.Anyway, it seemed to me that the eventFilter required subclassing as well. Not so?
No. Or at least it is only the container/parent which needs to subclassed, not the
QTextEdit. ItseventFilter()is effectively monitoring events sent to its children. -
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
I tried the first option, but it appears subclassing QPlainTextEdit isn't a matter of just subclassing. It wants me to implement some things like createEditor etc.
You do not have to supply
createEditor()etc. You should be able to subclass and only override whatever you need to. However, you are going down theeventFilter()route anyway.Anyway, it seemed to me that the eventFilter required subclassing as well. Not so?
No. Or at least it is only the container/parent which needs to subclassed, not the
QTextEdit. ItseventFilter()is effectively monitoring events sent to its children.@JonB Ah well the container is a table widget item, so that's no improvement. I'd still have to subclass. Or does the way that events are processed let me implement the filter in the container of the container of the container? That would be my window class.
-
@JonB Ah well the container is a table widget item, so that's no improvement. I'd still have to subclass. Or does the way that events are processed let me implement the filter in the container of the container of the container? That would be my window class.
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
Ah well the container is a table widget item, so that's no improvement.
I don't think
QTableWidgetItemcounts for this anyway, since it's not aQWidget/QObject. And I think even if it were the top-level widget likeQMainWindowor whatever still sees events before children do.One way or another, try it on your "window class" and see for yourself before proceeding.
-
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
Ah well the container is a table widget item, so that's no improvement.
I don't think
QTableWidgetItemcounts for this anyway, since it's not aQWidget/QObject. And I think even if it were the top-level widget likeQMainWindowor whatever still sees events before children do.One way or another, try it on your "window class" and see for yourself before proceeding.
This post is deleted! -
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
Ah well the container is a table widget item, so that's no improvement.
I don't think
QTableWidgetItemcounts for this anyway, since it's not aQWidget/QObject. And I think even if it were the top-level widget likeQMainWindowor whatever still sees events before children do.One way or another, try it on your "window class" and see for yourself before proceeding.
@JonB
I find that the event filter is being called but there is something strange:
I am receiving QEvent::KeyRelease but not QEvent::KeyPress.
The example code says to use the latter.
Also, even though I'm intercepting Return (returning true from the filter), the key is still being received by the text editor. -
@JonB
I find that the event filter is being called but there is something strange:
I am receiving QEvent::KeyRelease but not QEvent::KeyPress.
The example code says to use the latter.
Also, even though I'm intercepting Return (returning true from the filter), the key is still being received by the text editor.@Publicnamer
In the end I overrode the keypress/keyrelease methods and now it works. The eventFilter was not a good solution. -
@JonB said in QTableWidgetItem doesn't have multiline edit mode?:
@Publicnamer
Then subclass and override e.g. QTextEdit::keyPressEvent(QKeyEvent *e). Or write an eventFiilter().I tried the first option, but it appears subclassing QPlainTextEdit isn't a matter of just subclassing. It wants me to implement some things like createEditor etc.
As for adding an event filter, isn't there a simple way to inject a closure into the text editor to intercept events? Why is subclassing always the solution? Seems like the wrong way.
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
Why is subclassing always the solution?
In C++ it always is ;)
The eventFilter was not a good solution.
That should be THE solution, it's also explained in the docs
Super easy:
bool eventFilter(QObject *object, QEvent *event) override{ QWidget *editor = qobject_cast<QWidget*>(object); if (!editor) return false; if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->matches(QKeySequence::Cancel)) { // don't commit data emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache); return true; } switch (keyEvent->key()) { case Qt::Key_Tab: emit commitData(editor); emit closeEditor(editor, QAbstractItemDelegate::EditNextItem); return true; case Qt::Key_Backtab: emit commitData(editor); emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem); return true; case Qt::Key_Enter: case Qt::Key_Return: QMetaObject::invokeMethod(this, [editor,this](){commitData(editor); closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);},Qt::QueuedConnection); return false; default: return false; } } return QStyledItemDelegate::eventFilter(QObject *editor, QEvent *event) }Note: most of this code is copy-pasted from QAbstractItemDelegatePrivate::editorEventFilter
-
@Publicnamer said in QTableWidgetItem doesn't have multiline edit mode?:
Why is subclassing always the solution?
In C++ it always is ;)
The eventFilter was not a good solution.
That should be THE solution, it's also explained in the docs
Super easy:
bool eventFilter(QObject *object, QEvent *event) override{ QWidget *editor = qobject_cast<QWidget*>(object); if (!editor) return false; if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->matches(QKeySequence::Cancel)) { // don't commit data emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache); return true; } switch (keyEvent->key()) { case Qt::Key_Tab: emit commitData(editor); emit closeEditor(editor, QAbstractItemDelegate::EditNextItem); return true; case Qt::Key_Backtab: emit commitData(editor); emit closeEditor(editor, QAbstractItemDelegate::EditPreviousItem); return true; case Qt::Key_Enter: case Qt::Key_Return: QMetaObject::invokeMethod(this, [editor,this](){commitData(editor); closeEditor(editor, QAbstractItemDelegate::SubmitModelCache);},Qt::QueuedConnection); return false; default: return false; } } return QStyledItemDelegate::eventFilter(QObject *editor, QEvent *event) }Note: most of this code is copy-pasted from QAbstractItemDelegatePrivate::editorEventFilter
@VRonin said in QTableWidgetItem doesn't have multiline edit mode?:
That should be THE solution
if (event->type() == QEvent::KeyPress) {I agree with you. The trouble is the OP wrote earlier
I am receiving QEvent::KeyRelease but not QEvent::KeyPress.
but I didn't pursue it with him....
-
@VRonin said in QTableWidgetItem doesn't have multiline edit mode?:
That should be THE solution
if (event->type() == QEvent::KeyPress) {I agree with you. The trouble is the OP wrote earlier
I am receiving QEvent::KeyRelease but not QEvent::KeyPress.
but I didn't pursue it with him....