PDA

View Full Version : Problems with "destroyed" signal



Alexander111122
11th July 2016, 07:35
Greetings everyone!
I have encountered a issue. I am trying to destroy a widget which was declared as an object in my mainwindow widget. I was hoping to get a "destroyed" signal in the mainwindow widget when the destruction take place - but I don't.
Here is the code:


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QPushButton>
#include <QBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPointF>
#include <QString>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QComboBox>
#include <QByteArray>
#include <QDebug>
#include <QListWidget>
#include <QListWidgetItem>
#include <QFile>
#include <QTimer>
#include <QDateTime>
#include <QDir>
#include <stddef.h>
#include <stdint.h>
#include <QGroupBox>
#include <QMouseEvent>
#include <QTextEdit>
#include <math.h>
#include <QClipboard>
#include <QMimeData>
#include <QApplication>
#include <QDoubleSpinBox>
#include <QSpinBox>
#include "receiver.h"
#include "transmitter.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private:
Ui::MainWindow *ui;
Receiver *rec;
Transmitter *tran;
QPushButton *transmitter_button;
QPushButton *receiver_button;

private slots:
void receiver_slot(void);
void transmitter_slot(void);
void receiver_destroyed(void);

};

#endif // MAINWINDOW_H



#ifndef RECEIVER_H
#define RECEIVER_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QPushButton>
#include <QBoxLayout>
#include <QDebug>

class Receiver : public QWidget
{
Q_OBJECT
public:
explicit Receiver(QWidget *parent = 0);

~Receiver();

private:
QPushButton *close;

signals:
void close_sig(void);

public slots:
void close_rec(void);
//void abvgd(void);
};

#endif // RECEIVER_H



#ifndef TRANSMITTER_H
#define TRANSMITTER_H

#include <QMainWindow>
#include <QObject>
#include <QWidget>

class Transmitter : public QWidget
{
Q_OBJECT
public:
explicit Transmitter(QWidget *parent = 0);
//~Transmitter();

private:
//QPushButton *close;

signals:

public slots:
//void close_tran(void);
};

#endif // TRANSMITTER_H



#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
transmitter_button = new QPushButton("Transmitter");
receiver_button = new QPushButton("Receiver");

QHBoxLayout *horizontal_0 = new QHBoxLayout;
horizontal_0->addWidget(transmitter_button);
horizontal_0->addWidget(receiver_button);

ui->centralWidget->setLayout(horizontal_0);

connect(transmitter_button, SIGNAL(clicked(bool)), this, SLOT(transmitter_slot()));
connect(receiver_button, SIGNAL(clicked(bool)), this, SLOT(receiver_slot()));
connect(rec, SIGNAL(destroyed(QObject*)), this, SLOT(receiver_destroyed()));
}

void MainWindow::transmitter_slot(void)
{
tran = new Transmitter;
transmitter_button->setEnabled(false);
tran->show();
}

void MainWindow::receiver_slot(void)
{
rec = new Receiver;
receiver_button->setEnabled(false);
rec->show();
}

void MainWindow::receiver_destroyed(void)
{
qDebug() << "ok";
receiver_button->setEnabled(true);
}

MainWindow::~MainWindow()
{
delete ui;
}



#include "receiver.h"

Receiver::Receiver(QWidget *parent) : QWidget(parent)
{
close = new QPushButton("Close");

QHBoxLayout *horizontal_0 = new QHBoxLayout;
horizontal_0->addWidget(close);

this->setLayout(horizontal_0);

connect(close, SIGNAL(clicked(bool)), this, SLOT(close_rec()));
}

void Receiver::close_rec(void)
{

this->~Receiver();
}

Receiver::~Receiver()
{

}



#include "transmitter.h"

Transmitter::Transmitter(QWidget *parent) : QWidget(parent)
{

}

anda_skoa
11th July 2016, 09:29
You never connect to any object's destroyed() signal.
You are quite luckly that your program doesn't crash when it accesses the uninitialized "rec" pointer.

If you want to connect to the receiver object, then you have to put the connect() to where you actually have an object.

Cheers,
_

Alexander111122
11th July 2016, 09:51
Thanks, but thats not enough - I have not understand what exactly I should do.
How can I know in one widget that another one (which was created in the first one originally) was destroyed?

anda_skoa
11th July 2016, 10:12
Depends on what you need to do.

If you just need to be aware of the object no longer existing, e.g. to create a new one instead, then you can just track the object with QPointer.

If you need to do something with a window/dialog when it gets closed, i.e. when you still need access to the object itself, then make it emit a custom signal that you connect to.

If you need to do something when the object is destroyed but don't need to access the object itself anymore, then you can connect to the destroyed() signal.

Cheers,
_

Alexander111122
11th July 2016, 10:57
The last two methods, you mentioned - I have done them. I connected a SLOT in my mainwindow to "destroyed" signal and I also tried to connect a SLOT in mainwindow to a custom signal which is generating by the rec widget when getting destroyed. But the slot was never called((
Now I wonder - why)
I will look forward to try the QPointer you advised today though.
Anyway I need to If you have any Idea why my mainwindow do not see the signals from the rec object?
thank you))

ChrisW67
11th July 2016, 11:19
I connected a SLOT in my mainwindow to "destroyed" signal
You connect a "destroyed()" signal from a non-object pointed to by the unintialised rec pointer (Listing 4 line 20). This is unlikely to have any useful outcome, as anda_skoa has already said. rec is not initialised until after someone clicks the receive button. Until then rec is undefined (maybe nullptr, maybe something more dangerous) and cannot be connect()ed to anything.

anda_skoa
11th July 2016, 12:46
The last two methods, you mentioned - I have done them. I connected a SLOT in my mainwindow to "destroyed" signal and I also tried to connect a SLOT in mainwindow to a custom signal which is generating by the rec widget when getting destroyed.

No you did not, at least not in the code that you've posted.


Anyway I need to If you have any Idea why my mainwindow do not see the signals from the rec object?

I already told you in comment #2.

But you claim that you do something that the code you posted does not do, so it is hard to tell if that actually is what your code looks like or if the code you are actually working with does what you claim it does.

Cheers,
_

Alexander111122
11th July 2016, 19:03
Problem solved thanks to anda_skoa!
I have find out that I have not initialised the widget at first as I was told.
Thank you very much my friends for provided help!