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. Custom Widget not showing in layout

Custom Widget not showing in layout

Scheduled Pinned Locked Moved Solved General and Desktop
qwidgetqlayoutcustom widget
9 Posts 5 Posters 1.7k 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.
  • P Offline
    P Offline
    Pl45m4
    wrote on 2 Jan 2024, 18:21 last edited by
    #1

    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 a QHBoxLayout on a plain QWidget.

    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:
    CustomWidgetLayout.png

    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 call show() directly.

    CustomWidgetLayout2.png

    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 like QActionWidget 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 ;-)


    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

    ~E. W. Dijkstra

    C J 2 Replies Last reply 2 Jan 2024, 18:24
    0
    • P Pl45m4
      2 Jan 2024, 18:21

      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 a QHBoxLayout on a plain QWidget.

      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:
      CustomWidgetLayout.png

      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 call show() directly.

      CustomWidgetLayout2.png

      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 like QActionWidget 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 ;-)

      C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 2 Jan 2024, 18:24 last edited by
      #2

      @Pl45m4 Your custom widget has no size/sizeHint.

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

      P 1 Reply Last reply 2 Jan 2024, 18:51
      3
      • P Pl45m4
        2 Jan 2024, 18:21

        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 a QHBoxLayout on a plain QWidget.

        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:
        CustomWidgetLayout.png

        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 call show() directly.

        CustomWidgetLayout2.png

        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 like QActionWidget 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 ;-)

        J Online
        J Online
        JoeCFD
        wrote on 2 Jan 2024, 18:29 last edited by
        #3

        @Pl45m4 said in Custom Widget not showing in layout:

        btn1.setObjectName("Btn1");

        btn1.setObjectName("Btn1"); ==> this is object name, not display name of your button.
        Does your button have a name?

        1 Reply Last reply
        0
        • C Christian Ehrlicher
          2 Jan 2024, 18:24

          @Pl45m4 Your custom widget has no size/sizeHint.

          P Offline
          P Offline
          Pl45m4
          wrote on 2 Jan 2024, 18:51 last edited by
          #4

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

          Added

          QSize myWidget::sizeHint() const
          {
               return QSize(width(), height());
          }
          

          I actually dont know if this is correct, but now I can see something at least ;-)

          CustomWidgetLayout3.png

          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?


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          J C 2 Replies Last reply 2 Jan 2024, 19:09
          0
          • P Pl45m4
            2 Jan 2024, 18:51

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

            Added

            QSize myWidget::sizeHint() const
            {
                 return QSize(width(), height());
            }
            

            I actually dont know if this is correct, but now I can see something at least ;-)

            CustomWidgetLayout3.png

            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?

            J Offline
            J Offline
            JonB
            wrote on 2 Jan 2024, 19:09 last edited by JonB 1 Feb 2024, 19:12
            #5

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

            and QAbstractButton says

            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 guess QPushButton 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!

            P 1 Reply Last reply 2 Jan 2024, 19:20
            3
            • J JonB
              2 Jan 2024, 19:09

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

              and QAbstractButton says

              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 guess QPushButton 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!

              P Offline
              P Offline
              Pl45m4
              wrote on 2 Jan 2024, 19:20 last edited by
              #6

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


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              1 Reply Last reply
              1
              • P Pl45m4
                2 Jan 2024, 18:51

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

                Added

                QSize myWidget::sizeHint() const
                {
                     return QSize(width(), height());
                }
                

                I actually dont know if this is correct, but now I can see something at least ;-)

                CustomWidgetLayout3.png

                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?

                C Offline
                C Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 2 Jan 2024, 19:41 last edited by
                #7

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

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

                P 1 Reply Last reply 2 Jan 2024, 19:57
                2
                • C Christian Ehrlicher
                  2 Jan 2024, 19:41

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

                  P Offline
                  P Offline
                  Pl45m4
                  wrote on 2 Jan 2024, 19:57 last edited by
                  #8

                  @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 returning QSize(width(), height()); doesn't feel like the best solution ;-)

                  Thanks again :)


                  If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                  ~E. W. Dijkstra

                  S 1 Reply Last reply 8 Jan 2024, 08:43
                  0
                  • P Pl45m4 has marked this topic as solved on 2 Jan 2024, 19:57
                  • P Pl45m4
                    2 Jan 2024, 19:57

                    @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 returning QSize(width(), height()); doesn't feel like the best solution ;-)

                    Thanks again :)

                    S Offline
                    S Offline
                    SimonSchroeder
                    wrote on 8 Jan 2024, 08:43 last edited by
                    #9

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

                    1 Reply Last reply
                    0

                    3/9

                    2 Jan 2024, 18:29

                    6 unread
                    • Login

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