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
QtWS25 Last Chance

Remove QTextFrame from QTextDocument

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 2 Posters 2.5k Views
  • 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.
  • wolpersW Offline
    wolpersW Offline
    wolpers
    wrote on last edited by
    #1

    Hi, I cannot see how to remove a QTextFrame from a QTextDocument. Can anyone point me into the right direction?

    1 Reply Last reply
    0
    • 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