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
Forum Updated to NodeBB v4.3 + New Features

Remove QTextFrame from QTextDocument

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 2 Posters 2.5k 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.
  • 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