QT program crashing when using the extern keyword on a global object
-
I'm trying to use a global object for different classes using the extern keyword but this somehow doesn't work in QT.
Basically I wanted to create a common GraphicsScene Object to draw rectangles in the same scene but in different classes. That's why I thought a global object "scene_" would be a good choice here.
manwindow.cpp :
QGraphicsScene *scene_ = new QGraphicsScene(); MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); scene_->setSceneRect(-300,-300,600,600); ui->graphicsView->setScene(scene_); QGraphicsRectItem *rectItem = new QGraphicsRectItem(); rectItem->setRect(0,0,200,200); scene_->addItem(rectItem); } MainWindow::~MainWindow() { delete ui; }
mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QGraphicsScene> #include <QMainWindow> extern QGraphicsScene *scene_; QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
Here I wanted to retrieve the same object pointer _scene from mainwindow.h and add a second rectangle to it.
A.c :
#include "a.h" #include "mainwindow.h" #include <QGraphicsRectItem> A::A() { QGraphicsRectItem *rectItem2 = new QGraphicsRectItem(); rectItem2->setRect(0,0,200,200); scene_->addItem(rectItem2); }
main.cpp :
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
The program crashes immediately when running it. (Due to the keyword implementation)
10:17:26: The program has unexpectedly finished. 10:17:26: The process was ended forcefully. Desktop_Qt_6_2_1_MinGW_64_bit-Debug\debug\test.exe crashed.
How do I fix this issue or is there another way to implement this?
-
@GastonDjam said in QT program crashing when using the extern keyword on a global object:
How do I fix this issue or is there another way to implement this?
Make sure scene_ is initialised before you use it.
Also, do you need to access scene_ outside of MainWindow, looks like bad design? -
In the first line of mainwindow.cpp I initialised scene_
QGraphicsScene *scene_ = new QGraphicsScene();
Shouldn't this work ?
Regarding the design; I agree with you but I'm somehow blocked and don't know how to redesign it. Is there a better way/design that allows me to modify the same scene instantiated in a class and could modify the same one in other classes without using the global pointer.
-
@GastonDjam said in QT program crashing when using the extern keyword on a global object:
Is there a better way/design that allows me to modify the same scene instantiated in a class and could modify the same one in other classes without using the global pointer.
The question is: why should other classes modify it?
There should be one class responsible for modifying it. Other classes then simply tell it that something needs to be changed.Regarding the crash: did you actually run through debugger to see where exactly it crashes and what kind of crash it is?
-
I get this error below when debugging
THE INFERIOR STOPPED BECAUSE IT RECEIVED A SIGNAL FROM THE OPERATING SYSTEM. SIGNAL NAME :SIGSEGV SIGNAL
It doesn't show which line exactly was affected but I know that it works, when I remove the global declaration and make scene object private and initialize it in the constructor (Ignore A.h and A.c )
-
@GastonDjam said in QT program crashing when using the extern keyword on a global object:
It doesn't show which line exactly was affected
It certainly should. When you run this under a debugger and get the SIGSEGV the debugger should "jump in" and break. Look at the stack trace pane (or gcc
bt
command) to see where the crash is happening from. -
Hi
QGraphicsScene *scene_ = new QGraphicsScene();
seems like you make a local variable.
if you mean to use the global one, should it not be
scene_ = new QGraphicsScene();
-
@GastonDjam said in QT program crashing when using the extern keyword on a global object:
QGraphicsScene *scene_ = new QGraphicsScene();
Ignoring for a moment whether any of this is a good idea, when do you think that standalone, global, non-class statement, sitting in
manwindow.cpp
, will be executed? And don't forget, you must do any Qt things like widgets beforeQApplication
has been created....If you really feel you must do this, think about where to put the initialization statement....
-
Hi,
As already stated by my fellows, static QObject are not to be used.
Your current architecture is going to trigger a lot of other problems so you should really think about redoing it properly.
-
So this is my design :
I'm trying to implement a smart home simulation in qt. I basically have 2 windows, one for the app and the other for the home simulation. These 2 windows should communicate with each other
The goal here is when I click on the first button for example, a dialog window pops up with "Add lights" when clicking on that button a light icon will add up to the home simulation window
I want scene object to be global / unique so that I can add lights and other stuff to the same window
-
If I understand your desing correctly
The Simulation Window should have the QGraphicScene variable
To add lights to the scene, just create a method like:addLight() { QGraphicsRectItem *rectItem2 = new QGraphicsRectItem(); rectItem2->setRect(0,0,200,200); scene_->addItem(rectItem2); }
That's just the idea, not working code.
-
@mpergand That's what I thought as well but the pattern here is the following : When clicking on that first button of the app , a dialog window will pop up therefore a new class (called dialog for example). So I should create an object in that dialog class that calls addLight method from home simulation window/class. But that would instantiate a new Scene which is not the behavior that I want. I want to modify the same scene object that was instantiated at the beginning in home_simulation class
-
@GastonDjam
I will throw one more thing in. This may or may not be a good way to design your software --- and certainly as per @mpergand it sounds like you should be using signals & slots, maybe then this will not be necessary --- but, to answer your original question correctly: I did not say you cannot have a globalQGraphicsScene
object, I said the way/place you initialised it is unacceptable. The following is OK:QGraphicsScene *g_scene; // global declaration in .cpp file of pointer variable, *but not instantiated here*, value is `nullptr` // if this is declared in some other file and you want to be able to access it elsewhere you can have the .h file go: extern QGraphicsScene *g_scene; int main(int argc, char *argv[]) { QApplication a(argc, argv); // create QApplication *first* g_scene = new QGraphicsScene(); // *now* it is OK to create a widget, or you can do this in `MainWindow` or wherever }
-
@JonB said in QT program crashing when using the extern keyword on a global object:
This may or may not be a good way to design your software
This is no question - the design is bad (the nicest word I could find for it, sorry)