Linwood
8th March 2017, 19:32
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.
onchosen
doSignal
Exiting doSignal
after aSignal
The program has unexpectedly finished.
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?
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTableWidget>
#include <QDebug>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QTableWidget* qt;
private slots:
void onchosen(int, int);
void doSignal();
signals:
void aSignal();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
qt = new QTableWidget(2,1,this);
qt->setItem(0,0,new QTableWidgetItem("stuff00"));
qt->setItem(1,0,new QTableWidgetItem("stuff10"));
qt->setFixedSize(600,600);
this->setFixedSize(900,900);
qt->show();
connect(qt,SIGNAL(cellClicked(int,int)),this,SLOT( onchosen(int,int)));
connect(this,SIGNAL(aSignal()),this,SLOT(doSignal( )));
}
void MainWindow::onchosen(int r, int c)
{
qDebug() << "onchosen";
emit aSignal();
qDebug() << "after aSignal";
}
void MainWindow::doSignal()
{
qDebug()<<"doSignal";
delete qt; // If not present the program will not fail
qDebug()<<"Exiting doSignal";
}
MainWindow::~MainWindow()
{
}
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.
onchosen
doSignal
Exiting doSignal
after aSignal
The program has unexpectedly finished.
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?
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTableWidget>
#include <QDebug>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QTableWidget* qt;
private slots:
void onchosen(int, int);
void doSignal();
signals:
void aSignal();
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
qt = new QTableWidget(2,1,this);
qt->setItem(0,0,new QTableWidgetItem("stuff00"));
qt->setItem(1,0,new QTableWidgetItem("stuff10"));
qt->setFixedSize(600,600);
this->setFixedSize(900,900);
qt->show();
connect(qt,SIGNAL(cellClicked(int,int)),this,SLOT( onchosen(int,int)));
connect(this,SIGNAL(aSignal()),this,SLOT(doSignal( )));
}
void MainWindow::onchosen(int r, int c)
{
qDebug() << "onchosen";
emit aSignal();
qDebug() << "after aSignal";
}
void MainWindow::doSignal()
{
qDebug()<<"doSignal";
delete qt; // If not present the program will not fail
qDebug()<<"Exiting doSignal";
}
MainWindow::~MainWindow()
{
}