Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Remove QTextFrame from QTextDocument
Qt 6.11 is out! See what's new in the release blog

Remove QTextFrame from QTextDocument

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 2 Posters 5.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi and welcome to devnet,

    IIRC, calling delete on the QTextFrame object should remove it from the document.

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    wolpersW 1 Reply Last reply
    0
    • SGaistS SGaist

      Hi and welcome to devnet,

      IIRC, calling delete on the QTextFrame object should remove it from the document.

      wolpersW Offline
      wolpersW Offline
      wolpers
      wrote on last edited by
      #3

      @SGaist I think you are correct. I followed your hint and finally found a note in the QTextFrame's destructor documentation: Destroys the frame, and removes it from the document's layout.

      Unfortunately this causes the application to crash with a segmentation fault, but I am still looking into this.

      Thanks for your help!

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #4

        You're welcome !

        What does the debugger say ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        wolpersW 1 Reply Last reply
        0
        • SGaistS SGaist

          You're welcome !

          What does the debugger say ?

          wolpersW Offline
          wolpersW Offline
          wolpers
          wrote on last edited by
          #5

          @SGaist

          I called myframe->deleteLater() within a method overriding virtual void QTextEdit::keyPressEvent(QKeyEvent *e)

          Calling delete myframe has the same effect.

          Here is the call stack NetBeans provides me with:

          QMetaObject::cast(QObject*) const ()
          QTextFrame::iterator::operator++() ()
          ?? ()
          ?? ()
          QTextDocumentLayout::draw(QPainter*, QAbstractTextDocumentLayout::PaintContext const&) ()
          QWidgetTextControl::drawContents(QPainter*, QRectF const&, QWidget*) ()
          ?? ()
          QTextEdit::paintEvent(QPaintEvent*) ()
          QWidget::event(QEvent*) ()
          QFrame::event(QEvent*) ()
          QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) ()
          QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
          QApplication::notify(QObject*, QEvent*) ()
          QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
          QWidgetPrivate::sendPaintEvent(QRegion const&) ()
          QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
          ?? ()
          ?? ()
          QWidgetPrivate::syncBackingStore() ()
          QWidget::event(QEvent*) ()
          QMainWindow::event(QEvent*) ()
          QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
          QApplication::notify(QObject*, QEvent*) ()
          QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
          QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
          ?? ()
          g_main_context_dispatch ()
          ?? ()
          g_main_context_iteration ()
          QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) ()
          QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) ()
          QCoreApplication::exec() ()
          main (argc=1, argv=0x7fffffffe658)

          wolpersW 1 Reply Last reply
          0
          • wolpersW wolpers

            @SGaist

            I called myframe->deleteLater() within a method overriding virtual void QTextEdit::keyPressEvent(QKeyEvent *e)

            Calling delete myframe has the same effect.

            Here is the call stack NetBeans provides me with:

            QMetaObject::cast(QObject*) const ()
            QTextFrame::iterator::operator++() ()
            ?? ()
            ?? ()
            QTextDocumentLayout::draw(QPainter*, QAbstractTextDocumentLayout::PaintContext const&) ()
            QWidgetTextControl::drawContents(QPainter*, QRectF const&, QWidget*) ()
            ?? ()
            QTextEdit::paintEvent(QPaintEvent*) ()
            QWidget::event(QEvent*) ()
            QFrame::event(QEvent*) ()
            QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) ()
            QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
            QApplication::notify(QObject*, QEvent*) ()
            QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
            QWidgetPrivate::sendPaintEvent(QRegion const&) ()
            QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
            ?? ()
            ?? ()
            QWidgetPrivate::syncBackingStore() ()
            QWidget::event(QEvent*) ()
            QMainWindow::event(QEvent*) ()
            QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
            QApplication::notify(QObject*, QEvent*) ()
            QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
            QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
            ?? ()
            g_main_context_dispatch ()
            ?? ()
            g_main_context_iteration ()
            QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) ()
            QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) ()
            QCoreApplication::exec() ()
            main (argc=1, argv=0x7fffffffe658)

            wolpersW Offline
            wolpersW Offline
            wolpers
            wrote on last edited by
            #6

            nope, was lying. Calling delete myframe changes the callstack slightly. Still causing segmentation fault, though.

            QTextFrame::lastPosition() const ()
            ?? ()
            ?? ()
            ?? ()
            ?? ()
            QTextDocumentLayout::draw(QPainter*, QAbstractTextDocumentLayout::PaintContext const&) ()
            QWidgetTextControl::drawContents(QPainter*, QRectF const&, QWidget*) ()
            ?? ()
            QTextEdit::paintEvent(QPaintEvent*) ()
            QWidget::event(QEvent*) ()
            QFrame::event(QEvent*) ()
            QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) ()
            QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
            QApplication::notify(QObject*, QEvent*) ()
            QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
            QWidgetPrivate::sendPaintEvent(QRegion const&) ()
            QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
            ?? ()
            ?? ()
            QWidgetPrivate::syncBackingStore() ()
            QWidget::event(QEvent*) ()
            QMainWindow::event(QEvent*) ()
            QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
            QApplication::notify(QObject*, QEvent*) ()
            QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
            QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
            ?? ()
            g_main_context_dispatch ()
            ?? ()
            g_main_context_iteration ()
            QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) ()
            QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) ()
            QCoreApplication::exec() ()
            main (argc=1, argv=0x7fffffffe658)

            wolpersW 1 Reply Last reply
            0
            • wolpersW wolpers

              nope, was lying. Calling delete myframe changes the callstack slightly. Still causing segmentation fault, though.

              QTextFrame::lastPosition() const ()
              ?? ()
              ?? ()
              ?? ()
              ?? ()
              QTextDocumentLayout::draw(QPainter*, QAbstractTextDocumentLayout::PaintContext const&) ()
              QWidgetTextControl::drawContents(QPainter*, QRectF const&, QWidget*) ()
              ?? ()
              QTextEdit::paintEvent(QPaintEvent*) ()
              QWidget::event(QEvent*) ()
              QFrame::event(QEvent*) ()
              QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) ()
              QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
              QApplication::notify(QObject*, QEvent*) ()
              QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
              QWidgetPrivate::sendPaintEvent(QRegion const&) ()
              QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
              ?? ()
              ?? ()
              QWidgetPrivate::syncBackingStore() ()
              QWidget::event(QEvent*) ()
              QMainWindow::event(QEvent*) ()
              QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
              QApplication::notify(QObject*, QEvent*) ()
              QCoreApplication::notifyInternal2(QObject*, QEvent*) ()
              QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
              ?? ()
              g_main_context_dispatch ()
              ?? ()
              g_main_context_iteration ()
              QEventDispatcherGlib::processEvents(QFlagsQEventLoop::ProcessEventsFlag) ()
              QEventLoop::exec(QFlagsQEventLoop::ProcessEventsFlag) ()
              QCoreApplication::exec() ()
              main (argc=1, argv=0x7fffffffe658)

              wolpersW Offline
              wolpersW Offline
              wolpers
              wrote on last edited by
              #7

              I created a small self contained snippet for anyone to try out. Maybe someone can tell me what I am doing wrong when attempting to remove a QTextFrame. Hit 'x' one or more times to add a frame, hit 'y' to remove one. This is where things crash.

              main.cpp

              #include <QApplication>
              #include <QtCore>
              #include <QtGui>
              #include <QtWidgets>
              
              
              namespace {
              
                  class TestEdit : public QTextEdit {
                  protected:
              
                      virtual void keyPressEvent(QKeyEvent *e) {
              
                          if (e->key() == Qt::Key_X) {
                              
                              QTextCursor cursor = this->textCursor();
                              QTextFrameFormat frameFormat;
                              frameFormat.setBackground(QColor(Qt::red));
                              QTextFrame* frame = cursor.insertFrame(frameFormat);
                              
                          } else if (e->key() == Qt::Key_Y) {
                              
                              QTextCursor cursor = this->textCursor();
                              QTextFrame* currentFrame = cursor.currentFrame();
                              if(currentFrame != this->document()->rootFrame()) {
                                  //delete currentFrame;
                                  currentFrame->deleteLater();
                                  return;
                              }
                              
                          }
              
                          QTextEdit::keyPressEvent(e);
                      }
                  };
              }
              
              int main(int argc, char *argv[]) {
                  QApplication app(argc, argv);
                  QMainWindow* w = new QMainWindow();
                  w->setAttribute(Qt::WA_DeleteOnClose);
                  w->setCentralWidget(new TestEdit());
                  w->adjustSize();
                  w->move(QApplication::desktop()->screen()->rect().center() - w->rect().center());
                  w->show();
                  return app.exec();
              }
              
              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #8

                I haven't tested it yet but one thing I see is that you don't test that currentFrame is not null

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                wolpersW 1 Reply Last reply
                0
                • SGaistS SGaist

                  I haven't tested it yet but one thing I see is that you don't test that currentFrame is not null

                  wolpersW Offline
                  wolpersW Offline
                  wolpers
                  wrote on last edited by
                  #9

                  @SGaist Indeed, I missed that check. I added it in my local copy and debugged it. Unfortunately it does not make a difference. The currentFrame pointer is valid and currentFrame->deleteLater(); is called.

                  1 Reply Last reply
                  0
                  • wolpersW Offline
                    wolpersW Offline
                    wolpers
                    wrote on last edited by
                    #10

                    I created a bugreport for this. Looks to me that at least the documentation could need some work in this area. For the record: I found out that removing all child blocks (and frames?) leads to the automatic removal of the frame itself.

                    https://bugreports.qt.io/browse/QTBUG-53082

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #11

                      The documentation has been fixed :)

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved