Results 1 to 5 of 5

Thread: How can a delete a widget after it emits a signal

  1. #1
    Join Date
    Nov 2016
    Location
    Florida, US
    Posts
    27
    Thanks
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default How can a delete a widget after it emits a signal

    This is a bit convoluted. I have sample code but the sample code does not indicate why I am trying to do this, and that perhaps merits a few words.

    I have an application running in a very memory limited Raspberry Pi. It puts up a large table of information for someone to select a row. Once selected, I want to actually delete that QTableWidget to save memory.

    The code that did this was fairly convoluted but fundamentally did this: The click on the table emitted a signal to a containing widget (about 3 layers of parents up), which in turn hide another parent (about 2 layers up), and in the hideEvent of the parent of the QTableWidget I am deleting the QTableWidget.

    It appears what happens is when the slot used for the clicked signal completes, a segfault occurs. The signal is not queued (apparently) but executes immediately like a call.

    I have tried various ways to rearrange the code to no avail (well, short of something like a timer).

    Below is code that removes all the custom widgets and nesting and does results. It looks a bit silly but does demonstrate the segfault. The output from running this is below, and as you can see the signal executes the slot ... in terms of timing... in line, so the delete of the QTableWidget is deleted before exiting the SLOT from the cellClicked.

    Qt Code:
    1. onchosen
    2. doSignal
    3. Exiting doSignal
    4. after aSignal
    5. The program has unexpectedly finished.
    To copy to clipboard, switch view to plain text mode 

    What appears needed is to somehow get the delete out of the onchosen() function's call (or more precisely have it called after onchosen() exits, even though caused by onchosen(). And short of a timer I do not see how (and a timer seems... chancy, might I get race conditions that cause problems).

    Is there a proper approach to having a click on a table (ultimately) result in the table being deleted?

    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include <QTableWidget>
    6. #include <QDebug>
    7.  
    8. class MainWindow : public QMainWindow
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. MainWindow(QWidget *parent = 0);
    14. ~MainWindow();
    15.  
    16. private:
    17.  
    18. private slots:
    19. void onchosen(int, int);
    20. void doSignal();
    21.  
    22. signals:
    23. void aSignal();
    24. };
    25.  
    26. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "mainwindow.h"
    2. #include <QApplication>
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. MainWindow w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "mainwindow.h"
    2.  
    3. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    4. {
    5. qt = new QTableWidget(2,1,this);
    6. qt->setItem(0,0,new QTableWidgetItem("stuff00"));
    7. qt->setItem(1,0,new QTableWidgetItem("stuff10"));
    8. qt->setFixedSize(600,600);
    9. this->setFixedSize(900,900);
    10. qt->show();
    11. connect(qt,SIGNAL(cellClicked(int,int)),this,SLOT(onchosen(int,int)));
    12. connect(this,SIGNAL(aSignal()),this,SLOT(doSignal()));
    13. }
    14.  
    15. void MainWindow::onchosen(int r, int c)
    16. {
    17. qDebug() << "onchosen";
    18. emit aSignal();
    19. qDebug() << "after aSignal";
    20. }
    21.  
    22. void MainWindow::doSignal()
    23. {
    24. qDebug()<<"doSignal";
    25. delete qt; // If not present the program will not fail
    26. qDebug()<<"Exiting doSignal";
    27. }
    28.  
    29. MainWindow::~MainWindow()
    30. {
    31.  
    32. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How can a delete a widget after it emits a signal

    Well it's not generally recommended to delete the signal sender object, but in practice it is sometime very handy to do so, for such cases you should be using deleteLater(). If you want to delete after cellClicked signal than you could do like this, note the sequence is important, and make sure you don't connect any slot to that object after connecting deleteLater()
    Qt Code:
    1. connect(qt,SIGNAL(cellClicked(int,int)),this,SLOT(onchosen(int,int)));
    2. connect(qt,SIGNAL(cellClicked(int,int)),qt,SLOT(deleteLater())); // and no need to delete the qt object in the slot
    3. connect(this,SIGNAL(aSignal()),this,SLOT(doSignal()));
    To copy to clipboard, switch view to plain text mode 

    another alternate

    Qt Code:
    1. void MainWindow::doSignal()
    2. {
    3. qDebug()<<"doSignal";
    4. //delete qt; // If not present the program will not fail
    5. qt.deleteLater();
    6. qDebug()<<"Exiting doSignal";
    7. }
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  3. The following user says thank you to Santosh Reddy for this useful post:

    Linwood (9th March 2017)

  4. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How can a delete a widget after it emits a signal

    Quote Originally Posted by Linwood View Post
    The signal is not queued (apparently) but executes immediately like a call.
    A signal/slot connection is like a direct method call by default in a single threaded context.

    Signal/Slot connections are only "queued" calls if [noparse]Qt::QueuedConnection[/norparse] is explicitly used as the connection type or the signal is emitted by a different thread than the thread responsible for the receiver object's events.

    As Santosh Reddy suggested, just call the object's deleteLater() instead of invoking its delete operator.

    Cheers,
    _

  5. The following user says thank you to anda_skoa for this useful post:

    Linwood (9th March 2017)

  6. #4
    Join Date
    Nov 2016
    Location
    Florida, US
    Posts
    27
    Thanks
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: How can a delete a widget after it emits a signal

    Thank you.

    Sigh.... when I was first reading about QT5 I read about deleteLater(), and then promptly purged it from my memory. Yes, that solves the actual abort issue. And if I had a memory myself wouldn't have troubled you. Thank you for the patience.

    I'm less sure if it helps with memory, as the structure of the program is invoking a new set of widgets that cache images, and it won't return to the event loop until those are all created and the first ones displayed.

    Though, to be fair, I'm still struggling to see how much memory any of this is really using, I think I need to spend some time on that issue before working too hard to fix a problem that might not be significant. What I did (while waiting for this solution) was do a setRowCount(0) on the QTableWidget, and hope that gave back memory, instead of deleting it.

    Are there any good dynamic analysis tools that can instrument QT-specific programs to provide a view at runtime (during development) of object usage, object size, leaks, etc.? I know of some C++ tools for memory leaks of course, but wondered if there is anything more QT specific, that might also do things like indicate widget ownership nesting (or un-owned), sizing, visibility, etc? Or build-time options for QT itself (I am building QT from source) that adds some instrumentation.

    I ask because about half the time when I spend a lot of time doing something manually I find there's an object or method already there I just missed.

    So your signature line, Santosh, is very apt.

  7. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How can a delete a widget after it emits a signal

    Usually the C++ tools are very applicable as the Qt specific things are similar to situations with a shared pointer.

    But you could check if GammaRay has a plugin for that as it knows and tracks an application's QObject instances.
    If it does not it might not be too difficult to write on.

    Cheers,
    _

  8. The following user says thank you to anda_skoa for this useful post:

    Linwood (11th March 2017)

Similar Threads

  1. when QBuffer emits readyRead signal?
    By mastupristi in forum Qt Programming
    Replies: 5
    Last Post: 5th April 2016, 21:09
  2. Replies: 4
    Last Post: 25th September 2014, 15:21
  3. Passing pointer to object that emits a signal
    By Gadgetman53 in forum Qt Programming
    Replies: 2
    Last Post: 17th April 2011, 21:04
  4. Replies: 3
    Last Post: 2nd April 2011, 13:13
  5. Replies: 4
    Last Post: 23rd January 2011, 10:08

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.