crash at QLabel::setText
-
Hi,
I want to get into that signal/slot thingi and so I created a little prototype with a simple form containing varios labels and entryfields.
I created a model class with a signal "valueChanged" and an adapterclass, that takes a label pointer and adds a public slot called "setValue". Implementation of setValue transforms a given value to String and then calls QLabel::setText with that String.
Modelclass as well as Adapterclass are subclasses of QObject and contain the Q_Object macro.I debugged the app with qtcreator and stepped until the call of setText. Everything is fine and the String contains the expected value. Connection between Model and Adapter works so far.
Then at setText the app crashes.What am I doing wrong?
-
Hi,
I want to get into that signal/slot thingi and so I created a little prototype with a simple form containing varios labels and entryfields.
I created a model class with a signal "valueChanged" and an adapterclass, that takes a label pointer and adds a public slot called "setValue". Implementation of setValue transforms a given value to String and then calls QLabel::setText with that String.
Modelclass as well as Adapterclass are subclasses of QObject and contain the Q_Object macro.I debugged the app with qtcreator and stepped until the call of setText. Everything is fine and the String contains the expected value. Connection between Model and Adapter works so far.
Then at setText the app crashes.What am I doing wrong?
-
Hi
My best guess would be the label pointer is invalid.
Are you storing it in a member variable for later use ? -
How is your QLabel created? What is it called... are you using the designer or do you create the QLabel and other GUI elements yourself?
-
How is your QLabel created? What is it called... are you using the designer or do you create the QLabel and other GUI elements yourself?
@stretchthebits please provide a minimal and verifiable example.
-
@artwaw said in crash at QLabel::setText:
can you show your code please? The part you suspect of failing.
The point is, I don't have any suspicion.
@mrjj said in crash at QLabel::setText:
My best guess would be the label pointer is invalid.
Are you storing it in a member variable for later use ?That sounds interesting!
Yes, your right - I store the pointer in a member var.
Could you please explain, what's wrong with that?#include <QObject> #include <QLabel> #include <QVariant> class LabelAdapter : public QObject { Q_OBJECT public: explicit LabelAdapter(QLabel* label, int realDigits = 3); public slots: void setValue(QVariant value); private: QLabel* lbl; int digits; };#include "mainwindow.h" #include "ui_mainwindow.h" #include <QTimer> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , counter(0) , la0(ui->label_0) , la1(ui->label_1) , la2(ui->label_2) , la3(ui->label_3) , la4(ui->label_4) , la5(ui->label_5) { ui->setupUi(this); connect(&counter, &ValueModel::valueChanged, &la0, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la1, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la2, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la3, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la4, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la5, &LabelAdapter::setValue); QTimer* t = new QTimer(this); connect(t, &QTimer::timeout, this, &MainWindow::count); t->start(1000); }#include "labeladapter.h" #include <QTextStream> LabelAdapter::LabelAdapter(QLabel* label, int realDigits) : QObject(nullptr) , lbl(label) , digits(realDigits) { } void LabelAdapter::setValue(QVariant value) { if (!lbl) return; QString tv; QTextStream ts(&tv); ts.setRealNumberPrecision(digits); ts.setRealNumberNotation(QTextStream::FixedNotation); ts << value.toDouble(); lbl->setText(tv); } -
@artwaw said in crash at QLabel::setText:
can you show your code please? The part you suspect of failing.
The point is, I don't have any suspicion.
@mrjj said in crash at QLabel::setText:
My best guess would be the label pointer is invalid.
Are you storing it in a member variable for later use ?That sounds interesting!
Yes, your right - I store the pointer in a member var.
Could you please explain, what's wrong with that?#include <QObject> #include <QLabel> #include <QVariant> class LabelAdapter : public QObject { Q_OBJECT public: explicit LabelAdapter(QLabel* label, int realDigits = 3); public slots: void setValue(QVariant value); private: QLabel* lbl; int digits; };#include "mainwindow.h" #include "ui_mainwindow.h" #include <QTimer> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , counter(0) , la0(ui->label_0) , la1(ui->label_1) , la2(ui->label_2) , la3(ui->label_3) , la4(ui->label_4) , la5(ui->label_5) { ui->setupUi(this); connect(&counter, &ValueModel::valueChanged, &la0, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la1, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la2, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la3, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la4, &LabelAdapter::setValue); connect(&counter, &ValueModel::valueChanged, &la5, &LabelAdapter::setValue); QTimer* t = new QTimer(this); connect(t, &QTimer::timeout, this, &MainWindow::count); t->start(1000); }#include "labeladapter.h" #include <QTextStream> LabelAdapter::LabelAdapter(QLabel* label, int realDigits) : QObject(nullptr) , lbl(label) , digits(realDigits) { } void LabelAdapter::setValue(QVariant value) { if (!lbl) return; QString tv; QTextStream ts(&tv); ts.setRealNumberPrecision(digits); ts.setRealNumberNotation(QTextStream::FixedNotation); ts << value.toDouble(); lbl->setText(tv); } -
@mrjj - Thank you very much for your questions. They leaded me to the right solution.
@eyllanesc said in crash at QLabel::setText:
all the QWidget implemented by QtDesigner are null until setupUI is invoked
That's wrong!
I verified the pointer are not null - during debug session.
If they where null, I had a path to follow ...@eyllanesc said in crash at QLabel::setText:
The solution is to initialize laX after setupUi.
That's right. Thank you.
I changed Adapter instances to member pointers instead of member vars and so I had to initialise them after setupUI.
Now all is working.Thank you all for your attention
-
@mrjj - Thank you very much for your questions. They leaded me to the right solution.
@eyllanesc said in crash at QLabel::setText:
all the QWidget implemented by QtDesigner are null until setupUI is invoked
That's wrong!
I verified the pointer are not null - during debug session.
If they where null, I had a path to follow ...@eyllanesc said in crash at QLabel::setText:
The solution is to initialize laX after setupUi.
That's right. Thank you.
I changed Adapter instances to member pointers instead of member vars and so I had to initialise them after setupUI.
Now all is working.Thank you all for your attention
@django-Reinhard I think I was wrong, what I should have said is that it is not initialized, you are right that it is not null. In conclusion in your code you are accessing uninitialized pointers, the logic is something like:
// before setupUI QLabel *label; // after setupUi label = new QLabel;