Custom Widget not showing in layout
-
Feels a bit weird to ask something like this, but for the sake of QWidgets, I cant get my from scratch created, custom widget (
QAbstractButton
base class, but own additional pImpl, which shouldn't matter) to show up in aQHBoxLayout
on a plainQWidget
.Example
#include <QApplication> #include "mywidget.h" #include <QDebug> #include <QHBoxLayout> #include <QPushButton> int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; w.setGeometry(200, 200, 500, 300); // dummy placeholder QPushButton* pb1 = new QPushButton("Click Me"); QPushButton* pb2 = new QPushButton("Click Me"); myWidget btn1; btn1.setObjectName("Btn1"); // myWidget* btn1 = new myWidget; QHBoxLayout* hbox = new QHBoxLayout(&w); w.setLayout(hbox); hbox->addWidget(pb1); // regular QPushButton hbox->addWidget(&btn1); // my widget hbox->addWidget(pb2); // regular QPushButton w.show(); // btn1.show(); return a.exec(); }
Produces:
You can clearly see that there is some reserved space between the two default
QPushButtons
(where I would expect to see my widget)The widget's
paintEvent
looks like this and there nothing special since it's in an early stage and doesn't do that much at all for now, except being drawn.void myWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event) QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(Qt::transparent); painter.setBrush(QColor("#CCCCCC")); painter.drawRect(rect()); }
The widget itself works... I can connect the
clicked
signal and it shows up, when you callshow()
directly.Maybe I'm missing the obvious, but I already tried everything I could think of.
btn1.show(); btn1.setVisible(true); // ... // ...
When widgets are shown in layouts, the
paintEvent
is called, right?! No other representation likeQActionWidget
I am missing and forgot to implement for my widget, right?
I know the answer that there isn't such thing for widgets, but I really don't know what (and why) this is happening...Hopefully somebody can enlighten me ;-)
-
@Pl45m4 Your custom widget has no size/sizeHint.
-
@Christian-Ehrlicher said in Custom Widget not showing in layout:
Your custom widget has no size/sizeHint.
Aren't such things inherited from
QAbstractButton
?
setGeometry(0, 0, 100, 100)
for example, made no differenceAdded
QSize myWidget::sizeHint() const { return QSize(width(), height()); }
I actually dont know if this is correct, but now I can see something at least ;-)
Is there any recommended way of implementing this? I think I just need the default behavior (like
QPushButtons
also have)@JoeCFD said in Custom Widget not showing in layout:
btn1.setObjectName("Btn1"); ==> this is object name, not display name of your button.
Does your button have a name?I know that ;-)
You can call him "Bob, the button", if you want ;-)
Just kidding, but why do you think this is relevant? -
@Pl45m4 said in Custom Widget not showing in layout:
Aren't such things inherited from QAbstractButton?
QWidget::sizeHint() says
The default implementation of sizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise.
To subclass QAbstractButton, you must reimplement at least paintEvent() to draw the button's outline and its text or pixmap. It is generally advisable to reimplement sizeHint() as well
so I think this corresponds to what you see till you add
sizeHint()
. I guessQPushButton
does this. https://codebrowser.dev/qt5/qtbase/src/widgets/widgets/qpushbutton.cpp.html#_ZNK11QPushButton8sizeHintEv (all I have access to) shows this implementation is non-trivial! -
@JonB said in Custom Widget not showing in layout:
shows this implementation is non-trivial
Ok, but reasonable... It's the sum of the text (incl. font size) and the icon size if any.
To subclass QAbstractButton, you must reimplement at least paintEvent() to draw the button's outline and its text or pixmap. It is generally advisable to reimplement sizeHint() as well
Will see, maybe I move to
QPushButton
subclass later, since I might want to show some text and don't need the radio or tri-state functionality. -
@Pl45m4 said in Custom Widget not showing in layout:
setGeometry(0, 0, 100, 100) for example, made no difference
This does not do anything since the widget is in a layout.
-
@Christian-Ehrlicher said in Custom Widget not showing in layout:
This does not do anything since the widget is in a layout.
Yep. Have seen that.
Need some fine-tuning to find the best setup for my widget, because for obvious reasons always returningQSize(width(), height());
doesn't feel like the best solution ;-)Thanks again :)
-
-
@Pl45m4 said in Custom Widget not showing in layout:
always returning QSize(width(), height()); doesn't feel like the best solution ;-)
I guess that QPushButton uses the actual text displayed (plus some padding) to calculate the size hint. QFontMetrics might help here.