setMaximumWidth acts like setFixedWidth for a custom widget
-
UPD: I want to create a message that, once constructed, has a fixed size but can't be larger than some limit.
I subclassed
QWidget
- implementedpaintEvent()
,sizeHint()
. But setting its maximum width works as if set fixed width - horizontal size policy which was set to fixed and, thus, must always be equal to the one of size hint, is ignored. What to do?// main.cpp #include "messagewidget.h" #include <QApplication> #include <QVBoxLayout> #include <QWidget> int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget wgt; auto *messageWidget = new MessageWidget("kenticent", "Hello, World"); auto *vBoxLayout = new QVBoxLayout; vBoxLayout->addWidget(messageWidget); wgt.setLayout(vBoxLayout); wgt.show(); return a.exec(); }
// messagewidget.h #ifndef MESSAGEWIDGET_H #define MESSAGEWIDGET_H #include <QWidget> class QLabel; class MessageWidget : public QWidget { Q_OBJECT public: explicit MessageWidget(const QString &username, const QString &bodyContents); virtual QSize sizeHint() const override; private: QLabel *usernameLabel_; QLabel *bodyContentsLabel_; }; #endif // MESSAGEWIDGET_H
// messagewidget.cpp #include "messagewidget.h" #include <QDebug> #include <QLabel> #include <QPainter> #include <QStyleOption> #include <QVBoxLayout> MessageWidget::MessageWidget(const QString &username, const QString &bodyContents ) : QWidget(nullptr) { usernameLabel_ = new QLabel(username); bodyContentsLabel_ = new QLabel(bodyContents); auto *vBoxLayout = new QVBoxLayout; vBoxLayout->addWidget(usernameLabel_); vBoxLayout->addWidget(bodyContentsLabel_); setLayout(vBoxLayout); setMaximumWidth(430); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } QSize MessageWidget::sizeHint() const { int left, top, right, bottom; layout()->getContentsMargins(&left, &top, &right, &bottom); int w = left + qMax(usernameLabel_->sizeHint().width(), bodyContentsLabel_->sizeHint().width()) + right; int h = top + usernameLabel_->sizeHint().height() + layout()->spacing() + bodyContentsLabel_->sizeHint().height() + bottom; QSize sh = QWidget::sizeHint(); sh.setWidth(w); sh.setHeight(h); return sh; }
-
@Kenticent said in setMaximumWidth acts like setFixedWidth for a custom widget:
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
You set a fixed size policy so why should it be resizable?
-
@Christian-Ehrlicher Doesn't fixed size policy mean that widget's size should always be equal to its size hint? Because in this case they are certainly different. Plus everything works just fine without the
setMaximumWidth()
line. -
When you set a min/max size this is used by the size hint to determine the size: https://code.woboq.org/qt5/qtbase/src/widgets/kernel/qlayoutitem.cpp.html#_ZNK11QWidgetItem8sizeHintEv
-
@Christian-Ehrlicher Thank you! I'll remember. But why is min/max size is still taken into account if
sizeHint()
is explicitly overridden? I've just debugged it, andQSize
returned by it is the same no matter whether the maximum width is set. -
I would guess it's indirectly from usernameLabel_->sizeHint() which looks at it's parent layout? Don't know.
-
@Christian-Ehrlicher I want to create a message that, once constructed, has a fixed size but can't be larger than some limit. I came up with the following solution.
bodyContentsLabel_->setMaximumWidth(430); bodyContentsLabel_->setWordWrap(true);
The maximum width is set in
bodyContentsLabel_
instead now. MessageWidget's size policy is still fixed. The result looks like this.Is this a good solution? And anyway, I still would like to know the reason why
setMaximumWidth()
acts like this. -
- let the size policy to Preferred (default)
- resize your widget to your preferred size, will be used by sizeHint()
- set the max width you want
[EDIT] I'm talking about the window
For the labels, put them in a vertical layout and add a horizontal strech for each of them.
Work well with Spacer sizetype set to Preferred