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. Simulating an editable QLabel: cannot clean-up redundant widget.
Forum Updated to NodeBB v4.3 + New Features

Simulating an editable QLabel: cannot clean-up redundant widget.

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 537 Views 3 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.
  • B Offline
    B Offline
    BwvB
    wrote on last edited by
    #1

    In the application I'm developing it is sometimes desired that the user can modify the text in a QLabel.
    The problem of how to do this has been posed several times, but I have seen only suggestions to an answer, not working code. The following approach has been suggested:

    1. create a QLineEdit widget and display it instead of the QLabel..
    2. The user enters a new text in the QLineEdit widget.
    3. when done (on Return), the new text is copied from the QLineEdit to the QLabel widget.
    4. The QLineEdit widget can be eliminated, the QLabel is made visible again.

    I have implemented the scheme above, and it works, but the implementation is not 'clean' in that I cannot delete the auxiliary QLineWidget after it has been used. When I delete lineEdit, memory is corrupted. How should I do this instead?

    I have trimmed my code to get a minimal example showing the issue. All, I think, is contained in the slot function MyWidget::mousePressEvent(), given below. MyWidget is a Q_OBJECT demo-class, directly derived from QWidget, with only one data member: QLabel* _qlabel;

    On a mouse-click, a new QLineEdit instance lineEdit is allocated and initialised with the text of the QLabel. In the layout, the new QLineEdit is swapped with the QLabel. Next, a lambda-expression is defined that is used as a slot when the user presses Return.
    The lambda expression copies the text back from QLineEdit to the QLabel, and it swaps the widgets again.

    Her is my problem: if I just delete the auxiliary QLineEdit widget, as it is no longer needed, the memory is corrupted (as valgrind clearly shows). If I only hide the lineEdit, memory stays good, everything looks ok, but the memory allocated to lineEdit will only be cleared when the whole widget goes (as QLabel* _qlabel is the parent). Even worse, when I don't set qlable as the parent (i.e. no parent), I still cannot delete lineEdit. This would leave me with a memory leak.
    How should I handle such a case? I would like to delete the intermediary lineEdit entirely, leaving no traces that the qlabel text has been edited.

    void MyWidget::mousePressEvent( QMouseEvent* )
    {
       // Create a lineEdit, initialize with qlabel's text
       auto lineEdit = new QLineEdit( _qlabel );
       lineEdit->setText( _qlabel->text() );
       lineEdit->setFocus();
    
       // exchange widgets in layout; delete old layout item.
       delete layout()->replaceWidget( _qlabel, lineEdit );
    
       // lambda for refreshing the label.
       auto doUpdate =
          [this,lineEdit]()
          {
             delete layout()->replaceWidget( lineEdit, _qlabel );
    
             _qlabel->setText( lineEdit->text() );
    #if 0
             lineEdit->hide();        // works, but memory not timely cleaned.
    #else
             disconnect( lineEdit );
             lineEdit->setParent(nullptr);
             delete lineEdit;         // crash, or at least memory corruption!
    #endif
          };
       connect( lineEdit, &QLineEdit::returnPressed, doUpdate );
    }
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      You are over-engineering it. Create the QLineEdit once and just show/hide it as required. There's no reason to delete and re-create it all the time.

      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
      1
      • B Offline
        B Offline
        BwvB
        wrote on last edited by
        #3

        Thanks for responding. But this was precisely my question! Throwing away an object that is no longer needed is not bad engineering, I would say. But throwing it away somehow screws-up the qt-internals,
        even when I explicitly disconnect and set the parent to nil. I don't understand. I fear the connect(lineEdit,....) statement somehow puts lineEdit in Qt-s belly where it cannot be undone easily.

        Furthermore, I made the QLabel instance the parent of the QLineEdit so that Qt take care of deallocation. Instead, I could also create the QLineEdit without setting its parent. In that case I would have a memory leak if I don't delete the object myself. But the memory corruption is still present.

        Below I post a typical output of valgrind after changing the text and pressing the return key,

        ==9178== Memcheck, a memory error detector
        ==9178== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
        ==9178== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
        ==9178== Command: ./Linux-5.3/bin/editablelabel
        ==9178== 
        ==9178== Invalid read of size 8
        ==9178==    at 0x7E60404: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D05834: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA9DA: QLineEdit::keyPressEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C07C86: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD1126: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C213CC: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7402D31: QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==    by 0x73DE33B: QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==  Address 0x18a11418 is 8 bytes inside a block of size 248 free'd
        ==9178==    at 0x4C2FBEB: operator delete(void*, unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x7E5470D: QObjectPrivate::deleteChildren() (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C02FF5: QWidget::~QWidget() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA7E8: QLineEdit::~QLineEdit() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x4037D8: MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}::operator()() const (MyWidget.cpp:38)
        ==9178==    by 0x403BB3: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}>::call({lambda()#1}&, void**) (qobjectdefs_impl.h:146)
        ==9178==    by 0x403B94: void QtPrivate::Functor<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0>::call<QtPrivate::List<>, void>({lambda()#1}&, void*, {lambda()#1}&*) (qobjectdefs_impl.h:256)
        ==9178==    by 0x403B63: QtPrivate::QFunctorSlotObject<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:443)
        ==9178==    by 0x7E608B2: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7E608E4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D0582C: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA9DA: QLineEdit::keyPressEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==  Block was alloc'd at
        ==9178==    at 0x4C2E94F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x6CF840F: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFC130: QLineEdit::QLineEdit(QWidget*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x403830: MyWidget::mousePressEvent(QMouseEvent*) (MyWidget.cpp:19)
        ==9178==    by 0x6C06E1D: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD0D75: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6BCFE42: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C1E286: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C2135D: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178== 
        ==9178== Invalid read of size 1
        ==9178==    at 0x7E6040C: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D05834: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA9DA: QLineEdit::keyPressEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C07C86: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD1126: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C213CC: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7402D31: QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==    by 0x73DE33B: QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==  Address 0x147cb380 is 32 bytes inside a block of size 88 free'd
        ==9178==    at 0x4C2FBEB: operator delete(void*, unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x6D071D4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E5470D: QObjectPrivate::deleteChildren() (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C02FF5: QWidget::~QWidget() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA7E8: QLineEdit::~QLineEdit() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x4037D8: MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}::operator()() const (MyWidget.cpp:38)
        ==9178==    by 0x403BB3: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}>::call({lambda()#1}&, void**) (qobjectdefs_impl.h:146)
        ==9178==    by 0x403B94: void QtPrivate::Functor<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0>::call<QtPrivate::List<>, void>({lambda()#1}&, void*, {lambda()#1}&*) (qobjectdefs_impl.h:256)
        ==9178==    by 0x403B63: QtPrivate::QFunctorSlotObject<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:443)
        ==9178==    by 0x7E608B2: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7E608E4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D0582C: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==  Block was alloc'd at
        ==9178==    at 0x4C2E94F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x7E5F174: QObject::QObject(QObject*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7583182: QInputControl::QInputControl(QInputControl::Type, QObject*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==    by 0x6CF841E: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFC130: QLineEdit::QLineEdit(QWidget*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x403830: MyWidget::mousePressEvent(QMouseEvent*) (MyWidget.cpp:19)
        ==9178==    by 0x6C06E1D: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD0D75: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6BCFE42: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C1E286: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178== 
        ==9178== Invalid read of size 8
        ==9178==    at 0x7E60416: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D05834: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA9DA: QLineEdit::keyPressEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C07C86: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD1126: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C213CC: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7402D31: QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==    by 0x73DE33B: QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==  Address 0x147cb3a8 is 72 bytes inside a block of size 88 free'd
        ==9178==    at 0x4C2FBEB: operator delete(void*, unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x6D071D4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E5470D: QObjectPrivate::deleteChildren() (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C02FF5: QWidget::~QWidget() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA7E8: QLineEdit::~QLineEdit() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x4037D8: MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}::operator()() const (MyWidget.cpp:38)
        ==9178==    by 0x403BB3: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}>::call({lambda()#1}&, void**) (qobjectdefs_impl.h:146)
        ==9178==    by 0x403B94: void QtPrivate::Functor<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0>::call<QtPrivate::List<>, void>({lambda()#1}&, void*, {lambda()#1}&*) (qobjectdefs_impl.h:256)
        ==9178==    by 0x403B63: QtPrivate::QFunctorSlotObject<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:443)
        ==9178==    by 0x7E608B2: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7E608E4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D0582C: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==  Block was alloc'd at
        ==9178==    at 0x4C2E94F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x7E5F174: QObject::QObject(QObject*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7583182: QInputControl::QInputControl(QInputControl::Type, QObject*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==    by 0x6CF841E: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFC130: QLineEdit::QLineEdit(QWidget*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x403830: MyWidget::mousePressEvent(QMouseEvent*) (MyWidget.cpp:19)
        ==9178==    by 0x6C06E1D: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD0D75: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6BCFE42: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C1E286: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178== 
        ==9178== Invalid read of size 8
        ==9178==    at 0x7E53B70: QObjectPrivate::maybeSignalConnected(unsigned int) const (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7E60485: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D05834: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA9DA: QLineEdit::keyPressEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C07C86: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD1126: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C213CC: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7402D31: QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==  Address 0x147cb3a0 is 64 bytes inside a block of size 88 free'd
        ==9178==    at 0x4C2FBEB: operator delete(void*, unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x6D071D4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E5470D: QObjectPrivate::deleteChildren() (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6C02FF5: QWidget::~QWidget() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFA7E8: QLineEdit::~QLineEdit() (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x4037D8: MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}::operator()() const (MyWidget.cpp:38)
        ==9178==    by 0x403BB3: QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}>::call({lambda()#1}&, void**) (qobjectdefs_impl.h:146)
        ==9178==    by 0x403B94: void QtPrivate::Functor<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0>::call<QtPrivate::List<>, void>({lambda()#1}&, void*, {lambda()#1}&*) (qobjectdefs_impl.h:256)
        ==9178==    by 0x403B63: QtPrivate::QFunctorSlotObject<MyWidget::mousePressEvent(QMouseEvent*)::{lambda()#1}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (qobjectdefs_impl.h:443)
        ==9178==    by 0x7E608B2: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7E608E4: ??? (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6D0582C: QWidgetLineControl::processKeyEvent(QKeyEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==  Block was alloc'd at
        ==9178==    at 0x4C2E94F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
        ==9178==    by 0x7E5F174: QObject::QObject(QObject*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x7583182: QInputControl::QInputControl(QInputControl::Type, QObject*) (in /usr/local/qt-5.15.2/lib/libQt5Gui.so.5.15.2)
        ==9178==    by 0x6CF841E: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6CFC130: QLineEdit::QLineEdit(QWidget*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x403830: MyWidget::mousePressEvent(QMouseEvent*) (MyWidget.cpp:19)
        ==9178==    by 0x6C06E1D: QWidget::event(QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BCA5BE: QApplicationPrivate::notify_helper(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6BD0D75: QApplication::notify(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x7E2C3E9: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /usr/local/qt-5.15.2/lib/libQt5Core.so.5.15.2)
        ==9178==    by 0x6BCFE42: QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool, bool) (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178==    by 0x6C1E286: ??? (in /usr/local/qt-5.15.2/lib/libQt5Widgets.so.5.15.2)
        ==9178== 
        
        
        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by Christian Ehrlicher
          #4

          Please provide a minimal, compilable example so we can reproduce your issue. Deleting a widget will not crash Qt - you must be doing something wrong. For instance you must not delete a widget inside a slot which is called due to a signal of this widget but use deleteLater() as you do in your example.

          /moved to General Qt since it's a general Qt usage question.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          B 1 Reply Last reply
          1
          • mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by mrjj
            #5

            Hi
            Just as a note:
            You can have an editable Qlabel

            ui->label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextEditable);
                QTextDocument *td = ui->label->findChild<QTextDocument *>();
                if (td) {
                    connect( td, &QTextDocument::contentsChanged, this, [td]() {
                        qDebug() << td->toRawText();
                    });
                }
            
            B 1 Reply Last reply
            0
            • mrjjM mrjj

              Hi
              Just as a note:
              You can have an editable Qlabel

              ui->label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextEditable);
                  QTextDocument *td = ui->label->findChild<QTextDocument *>();
                  if (td) {
                      connect( td, &QTextDocument::contentsChanged, this, [td]() {
                          qDebug() << td->toRawText();
                      });
                  }
              
              B Offline
              B Offline
              BwvB
              wrote on last edited by
              #6

              @mrjj Thanks! I was not aware of this possibility. Maybe I should follow this route.
              I will still post my original code, as suggested earlier, as something must be wrong there, and I don't see the culprit
              (meaning I still don't fully understand Qt)..
              .

              1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                Please provide a minimal, compilable example so we can reproduce your issue. Deleting a widget will not crash Qt - you must be doing something wrong. For instance you must not delete a widget inside a slot which is called due to a signal of this widget but use deleteLater() as you do in your example.

                /moved to General Qt since it's a general Qt usage question.

                B Offline
                B Offline
                BwvB
                wrote on last edited by
                #7

                @Christian-Ehrlicher

                Here is a small example.
                In succession I post a header file and two .cpp files + qmake .pro.

                header file: MyWidget.h:

                #include <QtWidgets/QWidget>
                #include <QtWidgets/QLabel>
                
                class MyWidget : public QWidget
                {
                   Q_OBJECT
                private:
                   QLabel* _qlabel;
                public:
                   MyWidget();
                protected:
                   void mousePressEvent(QMouseEvent*) override;
                };
                

                Implementation file MyWidget.cpp:

                #include "MyWidget.h"
                
                #include <QtWidgets/QHBoxLayout>
                #include <QtWidgets/QLineEdit>
                
                MyWidget::MyWidget()
                {
                   _qlabel = new QLabel( "Click to edit text.");
                
                   QHBoxLayout *layout = new QHBoxLayout(this);
                   layout->addWidget( _qlabel );
                
                   show();
                }
                void MyWidget::mousePressEvent( QMouseEvent* )
                {
                   // Create a lineEdit, initialize with qlabel's text
                   auto lineEdit = new QLineEdit( _qlabel );
                   lineEdit->setText( _qlabel->text() );
                   lineEdit->setFocus();
                
                   // exchange widgets in layout; delete old layout item.
                   delete layout()->replaceWidget( _qlabel, lineEdit );
                
                   // lambda for refreshing the label.
                   auto doUpdate =
                      [this,lineEdit]()
                      {
                         delete layout()->replaceWidget( lineEdit, _qlabel );
                         _qlabel->setText( lineEdit->text() );
                #if 0
                         lineEdit->hide();        // works, but memory leaked or not timely cleaned.
                #else
                         disconnect( lineEdit );
                         lineEdit->setParent(nullptr);
                         delete lineEdit;         // crash, or at least memory corruption!
                #endif
                      };  
                   connect( lineEdit, &QLineEdit::returnPressed, doUpdate );
                }
                

                main.cpp:

                #include "MyWidget.h"
                #include <QtWidgets/QApplication>
                int main(int argc, char *argv[])
                {
                    QApplication app( argc, argv );
                    auto widget = std::unique_ptr<MyWidget>(new MyWidget);
                    return app.exec();
                }
                

                and finally a qmake .pro file: qmake -o Makefile MyWidget.pro

                TEMPLATE = app
                QT += widgets
                CONFIG += qt
                SOURCES += MyWidget.cpp main.cpp
                HEADERS += MyWidget.h
                TARGET = MyWidget  
                
                
                mrjjM Christian EhrlicherC 2 Replies Last reply
                0
                • B BwvB

                  @Christian-Ehrlicher

                  Here is a small example.
                  In succession I post a header file and two .cpp files + qmake .pro.

                  header file: MyWidget.h:

                  #include <QtWidgets/QWidget>
                  #include <QtWidgets/QLabel>
                  
                  class MyWidget : public QWidget
                  {
                     Q_OBJECT
                  private:
                     QLabel* _qlabel;
                  public:
                     MyWidget();
                  protected:
                     void mousePressEvent(QMouseEvent*) override;
                  };
                  

                  Implementation file MyWidget.cpp:

                  #include "MyWidget.h"
                  
                  #include <QtWidgets/QHBoxLayout>
                  #include <QtWidgets/QLineEdit>
                  
                  MyWidget::MyWidget()
                  {
                     _qlabel = new QLabel( "Click to edit text.");
                  
                     QHBoxLayout *layout = new QHBoxLayout(this);
                     layout->addWidget( _qlabel );
                  
                     show();
                  }
                  void MyWidget::mousePressEvent( QMouseEvent* )
                  {
                     // Create a lineEdit, initialize with qlabel's text
                     auto lineEdit = new QLineEdit( _qlabel );
                     lineEdit->setText( _qlabel->text() );
                     lineEdit->setFocus();
                  
                     // exchange widgets in layout; delete old layout item.
                     delete layout()->replaceWidget( _qlabel, lineEdit );
                  
                     // lambda for refreshing the label.
                     auto doUpdate =
                        [this,lineEdit]()
                        {
                           delete layout()->replaceWidget( lineEdit, _qlabel );
                           _qlabel->setText( lineEdit->text() );
                  #if 0
                           lineEdit->hide();        // works, but memory leaked or not timely cleaned.
                  #else
                           disconnect( lineEdit );
                           lineEdit->setParent(nullptr);
                           delete lineEdit;         // crash, or at least memory corruption!
                  #endif
                        };  
                     connect( lineEdit, &QLineEdit::returnPressed, doUpdate );
                  }
                  

                  main.cpp:

                  #include "MyWidget.h"
                  #include <QtWidgets/QApplication>
                  int main(int argc, char *argv[])
                  {
                      QApplication app( argc, argv );
                      auto widget = std::unique_ptr<MyWidget>(new MyWidget);
                      return app.exec();
                  }
                  

                  and finally a qmake .pro file: qmake -o Makefile MyWidget.pro

                  TEMPLATE = app
                  QT += widgets
                  CONFIG += qt
                  SOURCES += MyWidget.cpp main.cpp
                  HEADERS += MyWidget.h
                  TARGET = MyWidget  
                  
                  
                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Hi
                  did you try

                  delete lineEdit;

                  to

                  lineEdit-deleteLater();

                  1 Reply Last reply
                  0
                  • B BwvB

                    @Christian-Ehrlicher

                    Here is a small example.
                    In succession I post a header file and two .cpp files + qmake .pro.

                    header file: MyWidget.h:

                    #include <QtWidgets/QWidget>
                    #include <QtWidgets/QLabel>
                    
                    class MyWidget : public QWidget
                    {
                       Q_OBJECT
                    private:
                       QLabel* _qlabel;
                    public:
                       MyWidget();
                    protected:
                       void mousePressEvent(QMouseEvent*) override;
                    };
                    

                    Implementation file MyWidget.cpp:

                    #include "MyWidget.h"
                    
                    #include <QtWidgets/QHBoxLayout>
                    #include <QtWidgets/QLineEdit>
                    
                    MyWidget::MyWidget()
                    {
                       _qlabel = new QLabel( "Click to edit text.");
                    
                       QHBoxLayout *layout = new QHBoxLayout(this);
                       layout->addWidget( _qlabel );
                    
                       show();
                    }
                    void MyWidget::mousePressEvent( QMouseEvent* )
                    {
                       // Create a lineEdit, initialize with qlabel's text
                       auto lineEdit = new QLineEdit( _qlabel );
                       lineEdit->setText( _qlabel->text() );
                       lineEdit->setFocus();
                    
                       // exchange widgets in layout; delete old layout item.
                       delete layout()->replaceWidget( _qlabel, lineEdit );
                    
                       // lambda for refreshing the label.
                       auto doUpdate =
                          [this,lineEdit]()
                          {
                             delete layout()->replaceWidget( lineEdit, _qlabel );
                             _qlabel->setText( lineEdit->text() );
                    #if 0
                             lineEdit->hide();        // works, but memory leaked or not timely cleaned.
                    #else
                             disconnect( lineEdit );
                             lineEdit->setParent(nullptr);
                             delete lineEdit;         // crash, or at least memory corruption!
                    #endif
                          };  
                       connect( lineEdit, &QLineEdit::returnPressed, doUpdate );
                    }
                    

                    main.cpp:

                    #include "MyWidget.h"
                    #include <QtWidgets/QApplication>
                    int main(int argc, char *argv[])
                    {
                        QApplication app( argc, argv );
                        auto widget = std::unique_ptr<MyWidget>(new MyWidget);
                        return app.exec();
                    }
                    

                    and finally a qmake .pro file: qmake -o Makefile MyWidget.pro

                    TEMPLATE = app
                    QT += widgets
                    CONFIG += qt
                    SOURCES += MyWidget.cpp main.cpp
                    HEADERS += MyWidget.h
                    TARGET = MyWidget  
                    
                    
                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @BwvB You created an example but did not read my post:

                    For instance you must not delete a widget inside a slot which is called due to a signal of this widget but use deleteLater() as you do in your example.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    B 1 Reply Last reply
                    2
                    • Christian EhrlicherC Christian Ehrlicher

                      @BwvB You created an example but did not read my post:

                      For instance you must not delete a widget inside a slot which is called due to a signal of this widget but use deleteLater() as you do in your example.

                      B Offline
                      B Offline
                      BwvB
                      wrote on last edited by
                      #10

                      @Christian-Ehrlicher
                      Christian, you were quit right. In my eagerness to post a minimal example, I forgot to follow-up on your suggestion...

                      Indeed, changing

                      delete lineEdit
                      

                      into

                      lineEdit->deleteLater()
                      

                      resolved the issue. valgrind is happy and so am I.
                      Thanks for your help!

                      Regards,
                      Bertwim

                      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