Qt singleton twice destructor call - c++

I've to use Singleton pattern for widget in my app.
So I've made implementation for this.
testwidget.h
class TestWidget;
class TstWidgetHolder
{
static TestWidget* wobj;
public:
static const TestWidget* instance();
static void setParent(QWidget*);
};
class TestWidget : public QWidget
{
Q_OBJECT
friend class TstWidgetHolder;
private:
Ui::TestWidget ui;
explicit TestWidget(QWidget *parent = 0);
~TestWidget();
};
testwidget.cpp
TestWidget::TestWidget(QWidget *parent) :
QWidget(parent)
{
ui.setupUi(this);
}
TestWidget::~TestWidget()
{}
TestWidget* TstWidgetHolder::wobj = NULL;
void TstWidgetHolder::setParent(QWidget* obj)
{
static TestWidget tst(obj);
TstWidgetHolder::wobj = &tst;
}
const TestWidget* TstWidgetHolder::instance()
{
return wobj;
}
As simple as this.
Then is main program I'm setting up parent to this singleton.
TstWidgetHolder::setParent(this);
And there the real problem comes.
When main widget closes, application crashes.
According to debugger, the destructor of singleton widget is being called twice.
And that's of course is the cause of crash.
What's the problem?
Is it bug in Qt or mine logic?
HERE SOURCE CODE

When you make TstWidgetHolder::setParent(this) you are delegating ownership (in other words, responsability to destruct) of the TestWidget instance to this. So, right before the object pointed to by this is destructed, it tries to delete tst, which is an static object... and that is what makes your application crash. Either you don't use setParent or you should change TstWidgetHolder::setParent to:
void TstWidgetHolder::setParent(QWidget* obj)
{
TstWidgetHolder::wobj = new TestWidget(obj);
}

Related

Is it possible to use dependency injection with Qt Designer (for .ui files)?

We are developing in C++ (and Qt) using Visual Studio 2015 and the Qt Designer for our UI (via Form / .ui files).
We now need to share some Common Data between our UI elements (e.g. most recently used paths etc.) and I would like to do this via dependency injection (i.e. providing the UI with a Reference to the common object during construction) instead of e.g. (ab)using the singleton pattern.
Has someone faced (and solved) similar problems, and is there a sensible way to do this?
Update (to elaborate):
For example I have a custom FooWidget which I wish to use in my FooDialog.ui form file.
// My custom Widget
class FooWidget : public QWidget {
Q_OBJECT
public:
FooWidget(QWidget* parent);
//...
}
// The FooDialog class (scaffolding created by Qt Designer)
class FooDialog : public QDialog {
Q_OBJECT
public:
FooDialog(QWidget* parent) : QDialog(parent), ui (new Ui::FooDialog()) {
ui->setupUp(this);
//...
}
private:
Ui::FooDialog* ui;
}
// The Ui::FooDialog class autogenerated(!) by Qt Designer
// I cannot (must not) change this code, as it will be regenerated every time
class Ui_FooDialog {
public:
FooWidget* widget;
void setupUi(QWidget *fooDialog) {
//...
widget = new FooWidget(fooDialog);
//...
}
}
namespace Ui { class ScannerStatus: public Ui_ScannerStatus {}; }
I would like to provide the FooWidget with a common data object (e.g. text size and colours shared across all my Ui classes), but I can't do so in the constructor (since the autogenerated Ui_FooDialog treats FooWidget as a generic QWidget, which only needs/takes a QWidget* parent in the constructor - I cannot provide a pointer or reference to my shared TextColourAndSize object.
I am aware I could create a second ui->widget->setupTextColourAndSize(...) step in FooDialog (after the initial ui->setupUi(this)) which provides that common data object, but having two init() type functions seems like a rather bad code smell (one is bad enough).
FooWidget needs two constructors, and a setter for the dependency:
explicit FooWidget(QObject *parent = nullptr) : QWidget(parent), … {
…
}
FooWidget(Dependency *dep, QObject *parent = nullptr) : FooWidget(parent) {
setDependency(dep);
}
void setDependency(Dependency *dep) {
…
}
Then you’d set the dependency after the widget is constructed:
FooDialog(Dependency *dep, …) … {
setupUi(this);
ui->fooWidget->setDependency(dep);
}
This could be automated: the parent widget can have a property that holds the pointer to the dependency, and the child widgets can find it automatically:
FooDialog(Dependency *, …) : … {
setProperty("dependency", dep);
setupUi(this);
}
FooWidget(QWidget *parent) : … {
auto *dep = parent() ? parent()->property("dependency").value<Dependency*>() : nullptr;
if (dep) setDependency(dep);
}
This will work with no extra effort if Dependency derives from QObject. Otherwise, you’ll need to have the following in a suitable header file:
class Dependency { … };
Q_DECLARE_METATYPE(Dependency*)
In all circumstances, you do need to promote the fooWidget object to FooWidget class within Qt Designer.
Ok from what I'm seeing you do not need "dependency injection". Question was incorrectly stated.
You can use this custom widget directly from Qt designer.
When you create your FooDialog place regular widget QWidget in place where you need to have a FooWidget.
Then "promote" regular this widget to FooWidget (possibly you have to add some simple information about that type) - (I did that long time ago and do not remember all details).
For detailed instruction just google: qt promote widget qt designer, you will find lots of examples how to do it.
These were good solutions, but talking about dependency injections, there is also an option to have some fun with C++. It's not a wise solution at all, of course I know it, but nevertheless...
foowidget.h
#ifndef FOOWIDGET_H
#define FOOWIDGET_H
#include <QWidget>
class Something
{
public:
QString getHello() const
{ return "Hello world!"; }
};
/***************************************************/
template<typename T>
class Injector
{
public:
QString getHello() const
{ return m_dataContainer.getHello(); }
private:
T m_dataContainer;
};
/***************************************************/
class FooWidget : public QWidget, public Injector<Something>
{
Q_OBJECT
public:
explicit FooWidget(QWidget* parent = nullptr);
protected:
virtual void mousePressEvent(QMouseEvent*) override;
};
#endif // FOOWIDGET_H
foowidget.cpp
#include "foowidget.h"
#include <QMessageBox>
FooWidget::FooWidget(QWidget *parent)
: QWidget(parent)
{ }
void FooWidget::mousePressEvent(QMouseEvent*)
{
QMessageBox::information(nullptr, "Test", getHello());
}
foodialog.h
#ifndef FOODIALOG_H
#define FOODIALOG_H
#include <QDialog>
class SomethingElse
{
public:
QString getHello() const
{ return "OMG! OMG"; }
};
#include "foowidget.h"
namespace Ui {
class FooDialog;
}
class FooDialog : public QDialog, public Injector<SomethingElse>
{
Q_OBJECT
public:
explicit FooDialog(QWidget *parent = nullptr);
~FooDialog();
protected:
void showEvent(QShowEvent *) override;
private:
QScopedPointer<Ui::FooDialog> ui;
};
#endif // FOODIALOG_H
foodialog.cpp
#include "foodialog.h"
#include "ui_foodialog.h"
#include <QMessageBox>
FooDialog::FooDialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::FooDialog)
{
ui->setupUi(this);
}
FooDialog::~FooDialog()
{ }
void FooDialog::showEvent(QShowEvent *)
{
QMessageBox::information(nullptr, "Test", getHello());
}
Multiple inheritance + deriving widgets from some small template proxy class works for both custom widgets and those, having UI forms. I've put a FooWidget on a FooDialog (via propagation mechanizm) in the sketch above and got two message boxes.
The idea itself can be implemented better, with smarter template usage, just tried to reduce sample code, anyway it's an unnessesary complication. But technically it works without any additional initializations =)

QT Signal from static method

I need to send a signal from static callback function. I do the following:
.h
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow (QWidget* parent=0);
~MainWindow();
static MainWindow* getInstance();
private:
void emitSignal();
static MainWindow* m_instance;
signals:
void mysignal();
slots:
void print();
...
}
.cpp
MainWindow* MainWindow::m_instance = 0;
MainWindow::MainWindow(QWidget* parent):
QMainWindow(parent) {
...
}
MainWindow* MainWindow::getInstance() {
if (m_instance == 0)
m_instance = new MainWindow;
return m_instance;
}
void MainWindow::emitSignal() {
emit mysignal();
}
inside of callback function:
getInstance()->emitSignal();
and somewhere in code:
connect(MainWindow::getInstance(), SIGNAL(mysignal()), this, SLOT(print()));
But the slot print() is not executed. And no errors are printed. Where am I wrong?
The callback uses getInstance() and thus can definitely create a new widget if one doesn't exist yet. Then it's a matter of how well you understand the code that executes the callback. If the callback is made before you make the connection, then the slot won't be invoked. That's likely your problem. It is invalid to invoke the callback without an instance already in place, and you should assert that it is so.
Most likely, you do not need to create an instance of the main window on the fly. You're likely facing an XY problem where you think you need to do something, but you're so invested in a solution that doesn't work that you don't see the bigger problem you're trying to solve. Please clearly expose what exactly is your application - why are you creating the window on the fly?
It is also unnecessary to create a method that forwards to the signal, unless you really somehow need the signal to be private. I doubt that you do - don't make it private.
The code below demonstrates that what you're trying to do definitely works if you do it correctly:
// https://github.com/KubaO/stackoverflown/tree/master/questions/static-signal-48540601
#include <QtCore>
class Main : public QObject {
Q_OBJECT
static Main * m_instance;
public:
Main(QObject * parent = {}) : QObject(parent) {
Q_ASSERT(! hasInstance());
m_instance = this;
}
static Main * instance() {
if (! m_instance) m_instance = new Main;
return m_instance;
}
static bool hasInstance() { return m_instance; }
Q_SIGNAL void theSignal();
};
Main * Main::m_instance;
void callback() {
Q_ASSERT(Main::hasInstance());
// If the instance didn't exist here, nothing can receive the signal.
Main::instance()->theSignal();
}
int main()
{
int slotCalls = {};
Main object;
QObject::connect(&object, &Main::theSignal, [&]{ slotCalls ++; });
Q_ASSERT(slotCalls == 0);
callback();
Q_ASSERT(slotCalls == 1);
}
#include "main.moc"
Are you sure the signal connected to the slot?
To avoid typos you could use this syntax (as long as you dont overload signals/slots you are fine with that ):
connect(MainWindow::getInstance(), &MainWindow::mysignal, this, &MainWindow::print);
another hint/styleguide: name your signals like signal_mySignal and slots like slot_print to avoid typos and clear things up.
You can also call this->dumpObjectInfo(); from somewhere in your main (after the connects of course) and take a look at the output

Qt: passing objects to every window

Im a beginner at C++ since I'm a Java-Dev. I'm learning Qt right now.
Now I want in my widget application on central object for holding special functionality (for example a bunch of methods for sending different network-command or something like that). In my mainwindow.cpp I've got this
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//...
BusinessLogic* bl = new BusinessLogic;
bl->setMyValue(44);
this->setBusinessLogic(bl);
this->getBusinessLogic();
//...
}
BusinessLogic* MainWindow::getBusinessLogic()
{
return this->bl;
}
void MainWindow::setBusinessLogic(BusinessLogic* newbl)
{
this->bl = newbl;
}
Where BusinessLogic.cpp is the class which I want to access from all windows in my application. So in my Dialog which get opend when the pushButton is clicked, I try to use the businesslogic instance like this in the constructor
Dialog::Dialog(QDialog *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
//...
((MainWindow*)parent)->getBusinessLogic();
}
Unfortunately the program crashes everytime the dialog get instanciated (the line with ((MainWindow*)parent)->getBusinessLogic(); get called.
What can I do?
There are several methods for achieving your goal(all depends on your requirements) but one approach is you can create Singleton class of your BusinessLogic and then access it anywhere. have a look here. OR you can also pass object of class one class to another. OR you can use signal slot mechanism.
For you best Solution can be
Class BLogic{
public:
static BLogic* instance(){
static BLogic ins;
return &ins;
}
void setVal(int v){
val = v;
}
private:
BLogic(){}
int val;
};
Now you can call functions of BLogic from any class like
BLogic::instance()->setVal(10);
OR Example of passing objects can be
class ClassA
{
public:
void setClassB(ClassB *ob){
m_classB = ob;
}
ClassB* getClassB(){
return m_classB;
}
private:
ClassB* m_classB;
};
class ClassB
{
public:
void setClassA(ClassA *ob){
m_classA = ob;
}
ClassA* getClassA(){
return m_classA;
}
private:
ClassA* m_classA;
};
Now from main.cpp
ClassA* obA = new ClassA;
ClassB* obB = new ClassB;
obA->setClassB(obB);
obB->setClassA(obA);
Don't pass a zero parent or a dangling pointer to the dialog.
But more seriously, verify your assumptions:
qDebug() << "the parent object is" << parent;
auto p = qobject_cast<MainWindow*>(parent);
if (p)
p->getBusinessLogic();
Debug output will give you some idea of whether a parent is set, and of what type it is at the moment. Remember that during the construction of a MainWindow instance, it goes through being different types (quite literally). So depending on when you construct the child, you might get a parent of type QWidget* or QMainWindow* or MainWindow*. During the destruction you could even get a QObject* parent!

Qt/VTK: Access functions in custom interactor class

I have a Qt GUI called MainWindow.
I am rendering some 3D objects in the constructor of the MainWindow.
Moreover I declared a custom class of the vtkInteractorStyleTrackballCamera in MainWindow.cpp like in this example.
Now I would like to call a function from the MainWindow class in the function OnLeftButtonDown() from my custom class of the Interactor.
I tried to inherit the MainWindow class to the custom Interactor class like this:
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera, MainWindow
But this doesn't work.
How can I access the functions of the MainWindow there?
The function is automatically called when pressing the left button of the mouse.
// Define interaction style
class customMouseInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static customMouseInteractorStyle* New();
vtkTypeMacro(customMouseInteractorStyle, vtkInteractorStyleTrackballCamera);
virtual void OnRightButtonDown()
{
MainWindowfunction(); // <- I want to call this
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
};
vtkStandardNewMacro(customMouseInteractorStyle);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// Rendering some things
}
void MainWindow::MainWindowfunction
{
// Do something
}
To answer your specific question, so you say you have this constructor:
customMouseInteractorStyle(MainWindow *ptr) { ptr->MainWindowfunction(); }
To make this work, first add a member variable:
private:
MainWindow *mainWin;
Then change the constructor to initialize it:
customMouseInteractorStyle(MainWindow *ptr) : mainWin(ptr) {}
Then your OnRightButtonDown becomes:
virtual void OnRightButtonDown()
{
mainWin->MainWindowfunction();
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}

c++ destructors

consider this scenario:
I need to create a ui for some settings. As, data and ui should be separated in theory, I defined a separate class which takes care of the configuration data. The question I have is how to instantiate the data class inside the settings class.
One way is to create the data class in the caller object, I mean the object that calls the settings menu class.
The other way, which my question is involved with, is to create a DATA class variable inside the settings class. I doubt what happens when the settings class gets destroyed then! would the data class object inside settings class also get destroyed? what about if it is defined as a static member of settings class?
#ifndef SETTINGSWINDOW_H
#define SETTINGSWINDOW_H
#include <QMainWindow>
#include <QModelIndex>
#include <QSignalMapper>
#include <QRadioButton>
#include <QSpinBox>
#include <QTimer>
#include "cameracommands.h"
struct Config
{
/* General Options */
QString general_key_lock;
QString general_back_light;
};
//class IConfigSource
//{
//public:
// virtual Config config() const;
// virtual void setConfig(const Config& cfg);
//};
class ConfigSource /* : public IConfigSource*/
{
public:
ConfigSource() {
config_.general_back_light = "OFF";
config_.general_key_lock = "OFF";
}
Config config() const {return config_;}
void setConfig(const Config& cfg) {config_ = cfg;}
private:
Config config_;
};
class ConfigUpdater : public QObject
{
Q_OBJECT
public:
ConfigUpdater(ConfigSource& src) : src_(src) {}
public slots:
void apply () {src_.setConfig(tempConfig_);}
void cancel() {tempConfig_ = src_.config();}
public:
void updateGeneralBackLight(QString s) {tempConfig_.general_back_light = s; qDebug() << "BackLight updated :)";}
void updateGeneralKeyLock(QString s) {tempConfig_.general_key_lock = s; qDebug() << "KeyLock updated :)";}
Config tempConfig_;
ConfigSource& src_;
};
//----------------------------
namespace Ui {
class SettingsWindow;
}
class SettingsWindow : public QMainWindow
{
Q_OBJECT
public:
explicit SettingsWindow(QWidget *parent = 0);
~SettingsWindow();
signals:
void clicked(const QString &text);
void sendToPLC(QByteArray );
public slots:
void updateGeneralBackLight();
void updateGeneralKeyLock();
void getRow(QModelIndex);
void MySlot(QString);
private slots:
void on_pushButton_5_clicked();
void on_pushButton_3_clicked();
private:
void set_mappings();
Ui::SettingsWindow *ui;
ConfigUpdater *config_updater;
QSignalMapper *mapper;
};
#endif // SETTINGSWINDOW_H
and this is the source:
QMainWindow(parent),
ui(new Ui::SettingsWindow)
{
/* initializations */
ui->setupUi(this);
ConfigSource src;
config_updater = new ConfigUpdater(src);
That depends on how do you need to use it.
Scenario 1. The settings need to be held in memory when the program is working.
Scenario 2. The settings need to be saved to the disc immediately, and then will be read on-demand.
In scenario 1, you need to be able to always access the data in the memory. So it is better to separate the settingsUI class and the settingsData class, so you will have access to the latter.
class settingsUI
{
<...>
private:
settingsData * data;//pointer to the data object
}
class settingsData
{
}
In scenario 2, you can aggregate settingsData into the settingsUI, and save the data to a file when the UI is destroyed.
class settingsUI
{
public:
<...>
~settingsUI();
private:
class settingsData
{
<..>
}data;
<...>
}
class settingsUI::~settingsUI()
{
data.saveToFile();
}
And yes, uf you aggregate settings into the UI, it will be destroyed when the UI is destroyed. Holding data as a static member is not the best idea, it is better to separate the data from the visual representation (which is in your case the UI class).
UPD:
If you want to hold it just until the program exits, I would suggest you to hold a static pointer to the data in the UI class. Here is an example with raw pointers, but you can use smart pointers too, ofc.
class data
{
}
class UI
{
private:
static data * data_;
}
data* UI::data_;
When your program starts, allocate memory for the data: UI::data_ = new data(), and when your program ends (or if you don't need the data anymore), free the memory: delete UI::data_. Once again, it is better to use smart pointers, so this is just an example.
If the settings class is used by only the UI then it makes sense to keep it within the UI class:
class Settings {
int a;
int b;
};
class Ui {
private:
Settings settings;
};
settings will be destroyed during the destruction of Ui.
If you are using the Settings object in many places, it makes more sense to keep a shared pointer to it:
class Ui {
public:
Ui(std::shared_ptr<Settings> someSettings)
: settings(someSettings)
{}
private:
std::shared_ptr<Settings> settings;
};
This Settings object will be destroyed when the last owner of the shared_ptr is destroyed.
Yes the data object would get destroyed when the settings object is destroyed. If you make it a static member then it would not. But that's probably not such a good idea. A better way would be to persist the data object to a file (say). You can read the file in the settings object constructor and write the file in the settings object destructor.
EDIT
class SettingsWindow : public QMainWindow
{
Q_OBJECT
public:
explicit SettingsWindow(ConfigSource& src , QWidget *parent = 0);
...
}
SettingsWindow::SettingsWindow(ConfigSource& src , QWidget *parent)
QMainWindow(parent),
ui(new Ui::SettingsWindow)
{
ui->setupUi(this);
config_updater = new ConfigUpdater(src);
...
}
thanks, it is correct. The program terminates when I attempt to pass the below variable to the user-defined function:
(inside header)
void print_config(Config cfg);
Ui::SettingsWindow *ui;
ConfigUpdater *config_updater;
inside cpp:
void SettingsWindow::print_config(Config config)
{
qDebug() << config.general_back_light;
qDebug() << config.general_key_lock;
}
void SettingsWindow::on_sendToMainButton_clicked() /* cancel */
{
print_config(config_updater->tempConfig_);
print_config(config_updater->src_.config());
}
the first, print_config instruciton works fine, as for tempConfig_, but the when I pass src_ in the second statement, it jump outta program.
//------------
I know where the problem comes from, but I cannot solve it, i hope this can help:
class ConfigUpdater : public QObject
{
Q_OBJECT
public:
ConfigUpdater(ConfigSource& src) : src_(src) {}
public slots:
void apply () {src_.setConfig(tempConfig_);}
void cancel() {tempConfig_ = src_.config();}
public:
Config tempConfig_;
ConfigSource& src_;
};
Here, src_ is passed by reference, everywhere, even in the constructor of Settings window.
the program fails when I attemp to access it inside memory, for example:
config_updater->cancel();
which does:
void cancel() {tempConfig_ = src_.config();}