[SOLVED] QTextEdit: stack overflow caused by special key
-
When using a QTextEdit in a QGraphicsView, a stack overflow occurs when pressing keys such as Alt, Ctrl, Shift, Insert, Escape, F1 through F12, etc. The trace indicates that the event system is stuck in a loop.
[SOLUTION] In the code below I set the QGraphicsView as parent of the QDialog, and then added the QDialog to the QGraphicsScene.
Do not set the QGraphicsView as the parent of any widget that will be added to the QGraphicsScene.What happens if you do: It appears to be caused by QEvent::ShortcutOverride in the event() functions of the related classes. This event is sent to widget in focus, then on to the QGraphicsView, the QGraphicsScene, the QGraphicsProxyWidget and then back to the widget in focus (through focusWidget()). This loop causes the overflow.
-Did I do something wrong? Or is this a bug in the framework? Is it solvable and if so: how?-
I use the following code. A stack trace (or the last few calls of it) is given below the code.
The purpose of the code was to try out rendering a graphicsview to a FramebufferObject and save it on disk to see the results. This worked as expected.
@
#include <QTGui>
#include <QGLFramebufferObject>class TestGraphicsView : public QGraphicsView
{
Q_OBJECTpublic:
TestGraphicsView(QWidget* parent = nullptr)
: QGraphicsView(parent),
fbo_(nullptr)
{
}public slots:
void render()
{
if (!fbo_ || (fbo_->size() != viewport()->size()))
fbo_ = new QGLFramebufferObject(viewport()->size(), QGLFramebufferObject::CombinedDepthStencil);QPainter p(fbo_); QGraphicsView::render(&p); QImage image = fbo_->toImage(); image.save("render.bmp", "BMP"); }
private:
QGLFramebufferObject* fbo_;
};int main(int argc, char *argv[]) {
QApplication application(argc, argv);QGraphicsView* view = new TestGraphicsView; view->setScene(new QGraphicsScene(view)); view->setViewport(new QGLWidget(view)); view->resize(800, 600); view->setSceneRect(QRect(QPoint(), view->viewport()->size())); QDialog* dialog = new QDialog(view); auto dialogProxy = view->scene()->addWidget(dialog, Qt::Dialog); dialogProxy->setPos(100, 100); QVBoxLayout* vLayout = new QVBoxLayout; dialog->setLayout(vLayout); vLayout->addWidget(new QLabel("Render them!", dialog), 0, Qt::AlignHCenter); vLayout->addWidget(new QTextEdit("Render us!", dialog)); QHBoxLayout* hLayout1 = new QHBoxLayout; vLayout->addLayout(hLayout1); hLayout1->addWidget(new QLabel("Render him!", dialog)); QPushButton* button = new QPushButton("Render me!", dialog); hLayout1->addWidget(button, 1); QObject::connect(button, SIGNAL(pressed()), view, SLOT(render())); view->show(); return application.exec();
}
@Stack trace:
@QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3818 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 915 C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 C++
QtGuid4.dll!QGraphicsScenePrivate::sendEvent(QGraphicsItem * item, QEvent * event) Line 1217 C++
QtGuid4.dll!QGraphicsScene::event(QEvent * event) Line 3441 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4551 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3933 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 915 C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 C++
QtGuid4.dll!QGraphicsView::event(QEvent * event) Line 2713 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4551 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3992 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 915 C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 C++
QtGuid4.dll!QGraphicsProxyWidget::event(QEvent * event) Line 875 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4551 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3933 C++... // (the above block is repeated till the overflow occurs)
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3975 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 915 C++
QtCored4.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 234 C++
QtGuid4.dll!QETWidget::sendSpontaneousEvent(QObject * r, QEvent * e) Line 571 C++
QtGuid4.dll!QKeyMapper::sendKeyEvent(QWidget * widget, bool grab, QEvent::Type type, int code, QFlags<enum Qt::KeyboardModifier> modifiers, const QString & text, bool autorepeat, int count, unsigned int nativeScanCode, unsigned int nativeVirtualKey, unsigned int nativeModifiers, bool * __formal) Line 1195 C++
QtGuid4.dll!QKeyMapperPrivate::translateKeyEvent(QWidget * widget, const tagMSG & msg, bool grab) Line 1094 C++@