Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. setMaximumWidth acts like setFixedWidth for a custom widget

setMaximumWidth acts like setFixedWidth for a custom widget

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 679 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    deleted475
    wrote on last edited by deleted475
    #1

    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 - implemented paintEvent(), 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;
    }
    

    Screenshot

    Christian EhrlicherC 1 Reply Last reply
    0
    • D deleted475

      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 - implemented paintEvent(), 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;
      }
      

      Screenshot

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @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?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      D 1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        @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?

        D Offline
        D Offline
        deleted475
        wrote on last edited by deleted475
        #3

        @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.

        860f750b-a410-4ffe-ab30-8364124a6a88-image.png

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          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

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          D 1 Reply Last reply
          1
          • Christian EhrlicherC Christian Ehrlicher

            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

            D Offline
            D Offline
            deleted475
            wrote on last edited by deleted475
            #5

            @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, and QSize returned by it is the same no matter whether the maximum width is set.

            1 Reply Last reply
            0
            • Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              I would guess it's indirectly from usernameLabel_->sizeHint() which looks at it's parent layout? Don't know.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              D 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                I would guess it's indirectly from usernameLabel_->sizeHint() which looks at it's parent layout? Don't know.

                D Offline
                D Offline
                deleted475
                wrote on last edited by
                #7

                @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.

                bd0a62c8-4d95-4deb-8b79-05c30778a39f-image.png

                Is this a good solution? And anyway, I still would like to know the reason why setMaximumWidth() acts like this.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mpergand
                  wrote on last edited by mpergand
                  #8
                  • 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

                  1 Reply Last reply
                  1

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved