[SOLVED] Extending widgets
-
I'm trying to figure out what's the best way to extend a widget.
I want to have a QLabel with a hover behavior, and as it seems from my research so far, the only way to do that is to extend the QLabel widget and and override the HoverEnter, HoverMove and HoverLeave methods.
My question though is how do I then use my extended widget instead of the QLabel in the design view of Qt Creator?
Do I actually need to go through all of this to do that?
Is it enough to promote my widget?
This isn't very clear how to do something that seems to be very basic..Thanks.
-
Hi
The promote feature is an easy way to use a custom widget in Designer.
The full plugin road is for widgets where you want to be able to alter
properties design time. -
Hi
The promote feature is an easy way to use a custom widget in Designer.
The full plugin road is for widgets where you want to be able to alter
properties design time. -
Ok, then promoting sounds like the option for me.
What do I need to provide for that? cpp and h files? -
@nitzan
Yes, just a normal cpp and h file.
Just make sure you type ClassName (of your widget) correctly as it don't validate it :)thanks!
that worked well, except for one problem.
calling thesetTest
method seems to have no effect at all..
I'm doing this:MyWidget::MyWidget(QWidget* parent) : QLabel(parent) { qDebug() << "MyWidget ctor"; this->setText("hey there"); this->setAttribute(Qt::WA_Hover); } bool MyWidget::event(QEvent* event) { switch (event->type()) { case QEvent::HoverEnter: this->setStyleSheet("color: rgb(255, 0, 0)"); break; case QEvent::HoverLeave: this->setStyleSheet("color: rgb(0, 0, 0)"); break; default: return QLabel::event(event); } return true; }
And the label has no text in it.
Any idea why? -
@nitzan said:
this->setText(..)
Have you tried SetText from outside, like via a button ?
Sometimes I get fooled by stuff overwritten by the ui->setup which is run after
your constructor. -
@mrjj
but that creates coupling i would prefer to avoid..
is there anyway to have that in the same class in a way that will be called after the ui->setup? -
@nitzan
It was just for testing.Have you tried to set it on the label you promote. ?
And not call SetText at all in constructor.I get the text here. (from designer)
@mrjj
callingsetText
from outside the class works well, even if I do it from theevent
method it works, but not in the ctor.I can't set the text from the designer as the actual text I'm trying to put there is from font awesome (using QtAwesome), and so the actual code is:
UserWidget::UserWidget(QWidget* parent) : QLabel(parent) { qDebug() << "UserWidget ctor"; this->setText(QString(QChar(fa::user)).append(" login")); this->setAttribute(Qt::WA_Hover); }
-
If you don't want the text overwritten by the text from designer then instead of promoting QLabel to your class promote a plain QWidget. It won't have the
Text
property in the editor so the generatedsetupUi
code won't callsetText
and the value set in your constructor will be preserved. -
If you don't want the text overwritten by the text from designer then instead of promoting QLabel to your class promote a plain QWidget. It won't have the
Text
property in the editor so the generatedsetupUi
code won't callsetText
and the value set in your constructor will be preserved.@Chris-Kawa
Sounds like a workaround, but I would like to understand why it's needed.As the ctor of
QLabel
is called before the code in my widget is executed, then thesetupUi
code should be executed before my code as well.
Unless I'm missing something? -
Well its the setupui for the mainform/dialog.
It creates the Qlabel and set its text.
So calls setText after the constructor. -
It's not a workaround. You should always promote from the "lowest" widget of which functionality you want to preserve. In this case you don't want to have the label's ability to edit text in the designer so you promote from a widget, not label.
As the ctor of QLabel is called before the code in my widget is executed, then the setupUi code should be executed before my code as well. Unless I'm missing something?
The code of the window widget's constructor usually looks something like this:
Foo::Foo(QWidget* parent) : QWidget(parent) { ui->setupUi(this); }
which "expands" to something like this:
Foo::Foo(QWidget* parent) : QWidget(parent) { ... ui->someLabel = new YourLabel(this); ui->someLabel->setText(whateverWasSetinTheDesigner); ... }
so as you can see whatever you set in the constructor is immediately overwritten by what was set in the designer.
If you promote from a QWidget the designer doesn't "know" it's a label and it won't generate thesetText()
call. -
It's not a workaround. You should always promote from the "lowest" widget of which functionality you want to preserve. In this case you don't want to have the label's ability to edit text in the designer so you promote from a widget, not label.
As the ctor of QLabel is called before the code in my widget is executed, then the setupUi code should be executed before my code as well. Unless I'm missing something?
The code of the window widget's constructor usually looks something like this:
Foo::Foo(QWidget* parent) : QWidget(parent) { ui->setupUi(this); }
which "expands" to something like this:
Foo::Foo(QWidget* parent) : QWidget(parent) { ... ui->someLabel = new YourLabel(this); ui->someLabel->setText(whateverWasSetinTheDesigner); ... }
so as you can see whatever you set in the constructor is immediately overwritten by what was set in the designer.
If you promote from a QWidget the designer doesn't "know" it's a label and it won't generate thesetText()
call.