objectName() is empty in constructor for a promoted widget
-
I have created a iSplitter class that inherits from QSplitter
I promoted the QSlitter widgets in my form using QTCreator gui.
Now when i check objectName() in my iSplitter::iSplitter() i get empty value.
The widget has the name set in gui designer.iSplitter::iSplitter(QWidget *parent)
{
qDebug()<<"isplitter init of "<<objectName();
} -
I have created a iSplitter class that inherits from QSplitter
I promoted the QSlitter widgets in my form using QTCreator gui.
Now when i check objectName() in my iSplitter::iSplitter() i get empty value.
The widget has the name set in gui designer.iSplitter::iSplitter(QWidget *parent)
{
qDebug()<<"isplitter init of "<<objectName();
}That's to be expected. QObjects don't have a constructor that take a name, so it's not available there. It's a property set via
setObjectName()
method. If you look at the generated header you'll find something along the lines ofsplitter = new iSplitter(someParent); splitter->setObjectName("someName");
It's the same whether you use a promoted or a built in widget. Generated code is exactly the same in both cases. Only the class name is substituted for the promoted one.
Btw. In your subclass you should really pass the parent parameter to the base class constructor, otherwise you might see some unexpected behavior.
-
That's to be expected. QObjects don't have a constructor that take a name, so it's not available there. It's a property set via
setObjectName()
method. If you look at the generated header you'll find something along the lines ofsplitter = new iSplitter(someParent); splitter->setObjectName("someName");
It's the same whether you use a promoted or a built in widget. Generated code is exactly the same in both cases. Only the class name is substituted for the promoted one.
Btw. In your subclass you should really pass the parent parameter to the base class constructor, otherwise you might see some unexpected behavior.
@Chris-Kawa
Thanksthe goal was to load the state from QSettings on next startup - I basically left decided to do it in showEvent - at this state the objectName() is already known.
with the parent - point taken.
-
@Chris-Kawa
Thanksthe goal was to load the state from QSettings on next startup - I basically left decided to do it in showEvent - at this state the objectName() is already known.
with the parent - point taken.
@Seb-Tur said:
I basically left decided to do it in showEvent
While this might work in case of designer created widget it's not a general solution. When you take your widget in isolation there's no guarantee
setObjectName
will be called beforeshowEvent
. If your widget is never shown you also won't get to handle it.If you want the earliest place where name is available connect in your constructor to the
QObject::objectNameChanged
signal and you'll be notified when the name is actually set, whenever that happens and independently from whether widget is visible or not. You can disconnect that in the slot if whatever you're doing should be just one time and ignore further renames. -
@Chris-Kawa
Thanksthe goal was to load the state from QSettings on next startup - I basically left decided to do it in showEvent - at this state the objectName() is already known.
with the parent - point taken.
@Seb-Tur said in objectName() is empty in constructor for a promoted widget:
the goal was to load the state from QSettings on next startup
There're a lot of situations were you can't initialize properly an object in the constructor because it is too early.
For that purpose I create a macro that call a slot in queued mode:InvokeLater(slot) QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection)
This way, in your constructor you can do:
InvokeLater(initialize);
and access to Qsettings in that slot.
-
@Seb-Tur said in objectName() is empty in constructor for a promoted widget:
the goal was to load the state from QSettings on next startup
There're a lot of situations were you can't initialize properly an object in the constructor because it is too early.
For that purpose I create a macro that call a slot in queued mode:InvokeLater(slot) QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection)
This way, in your constructor you can do:
InvokeLater(initialize);
and access to Qsettings in that slot.
@mpergand You don't need a macro for that.
QTimer::singleShot
with 0 time does the same without string based connection and macros. It still has the same problem though - it works for designer stuff, but there's no guarantee in general thatsetObjectName
would be already called by that time. -
@mpergand You don't need a macro for that.
QTimer::singleShot
with 0 time does the same without string based connection and macros. It still has the same problem though - it works for designer stuff, but there's no guarantee in general thatsetObjectName
would be already called by that time.@Chris-Kawa said in objectName() is empty in constructor for a promoted widget:
QTimer::singleShot with 0 time does the same
I have another macro for that ;)
#define InvokeAfterDelay(slot,delay) QTimer::singleShot((delay), this, SLOT(slot())) -
S Seb Tur has marked this topic as solved on
-
@Chris-Kawa said in objectName() is empty in constructor for a promoted widget:
QTimer::singleShot with 0 time does the same
I have another macro for that ;)
#define InvokeAfterDelay(slot,delay) QTimer::singleShot((delay), this, SLOT(slot()))@mpergand I don't always hate the project, the compiler, the debugger, my coworkers or my future self, but when I do I too carpet bomb entire code base with nested obfuscating preprocessor substitutions ;)