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. need help to design an extensible widget

need help to design an extensible widget

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 404 Views 1 Watching
  • 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.
  • L Offline
    L Offline
    lano1106
    wrote on last edited by
    #1

    I have a MDI window. When a subwindow is opened, I set a widget as the subwindow

        auto *w{new MyWidget};
        auto *subWindow{m_mdiArea->addSubWindow(w)};
        subWindow->setWindowTitle("my window");
        subWindow->setFixedSize(subWindow->sizeHint());
        subWindow->show();
    

    This widget contains itself another widget. What I would like to achieve is adding a second widget inside MyWidget layed out horizontally with the already existing widget and placed to the right of it. Its initial state would be to be hidden and I would like to toggle its visibility on and off in a way that takes as little as possible space from MyWidget space.

    I have seen in a tutorial how this is something very common in extensible dialog design where you have a 'more' button and clicking on it, toggles the visibility on and off of some extra dialog components.

    However, I want my widget design to remain very slick. I wish that I could connect the windows right border as if it was some sort of QSizeGrip but this does not seem to be an option...

    Perhaps the best that can be done would be to add a flat textured QPushButton that would be very thin and be of the same height as its containing parent that would act as some sort of clickable border to toggle the visibility of my second widget...

    Does that sound like a good idea?
    Is this something that has been done before publicly available that could look at how they have solved this challenge?

    M 1 Reply Last reply
    0
    • L lano1106

      I have a MDI window. When a subwindow is opened, I set a widget as the subwindow

          auto *w{new MyWidget};
          auto *subWindow{m_mdiArea->addSubWindow(w)};
          subWindow->setWindowTitle("my window");
          subWindow->setFixedSize(subWindow->sizeHint());
          subWindow->show();
      

      This widget contains itself another widget. What I would like to achieve is adding a second widget inside MyWidget layed out horizontally with the already existing widget and placed to the right of it. Its initial state would be to be hidden and I would like to toggle its visibility on and off in a way that takes as little as possible space from MyWidget space.

      I have seen in a tutorial how this is something very common in extensible dialog design where you have a 'more' button and clicking on it, toggles the visibility on and off of some extra dialog components.

      However, I want my widget design to remain very slick. I wish that I could connect the windows right border as if it was some sort of QSizeGrip but this does not seem to be an option...

      Perhaps the best that can be done would be to add a flat textured QPushButton that would be very thin and be of the same height as its containing parent that would act as some sort of clickable border to toggle the visibility of my second widget...

      Does that sound like a good idea?
      Is this something that has been done before publicly available that could look at how they have solved this challenge?

      M Offline
      M Offline
      mpergand
      wrote on last edited by mpergand
      #2

      @lano1106 said in need help to design an extensible widget:

      Perhaps the best that can be done would be to add a flat textured QPushButton that would be very thin and be of the same height as its containing parent that would act as some sort of clickable border to toggle the visibility of my second widget

      Furiously makes me think of a QSplitter ;)

      L 1 Reply Last reply
      0
      • M mpergand

        @lano1106 said in need help to design an extensible widget:

        Perhaps the best that can be done would be to add a flat textured QPushButton that would be very thin and be of the same height as its containing parent that would act as some sort of clickable border to toggle the visibility of my second widget

        Furiously makes me think of a QSplitter ;)

        L Offline
        L Offline
        lano1106
        wrote on last edited by lano1106
        #3

        @mpergand yes. I have thought about QSplitter

        but can it be configured in such a way that by simply clicking it, one of the widgets is going to appear/be hidden?

        I do not want users to be able to slide the control and have to complexify my code to figure out how to be displayed in an intermediate width... I am really looking for an on/off solution...

        Pretty much like an extensible dialog box... (with a QSplitter type of button)

        I have returned to QSplitter documentation. It seems like if I play with its property opaqueResize and the method setCollapsible(), I could get very close to what I want to achieve... I just need to figure out how to have the second widget collapsed at the initial state... Is a QSplitter child collapsed means its visibility is set to false?

        Maybe a user will tell... or else the source code will tell for sure...

        M 1 Reply Last reply
        0
        • L lano1106

          @mpergand yes. I have thought about QSplitter

          but can it be configured in such a way that by simply clicking it, one of the widgets is going to appear/be hidden?

          I do not want users to be able to slide the control and have to complexify my code to figure out how to be displayed in an intermediate width... I am really looking for an on/off solution...

          Pretty much like an extensible dialog box... (with a QSplitter type of button)

          I have returned to QSplitter documentation. It seems like if I play with its property opaqueResize and the method setCollapsible(), I could get very close to what I want to achieve... I just need to figure out how to have the second widget collapsed at the initial state... Is a QSplitter child collapsed means its visibility is set to false?

          Maybe a user will tell... or else the source code will tell for sure...

          M Offline
          M Offline
          mpergand
          wrote on last edited by mpergand
          #4

          @lano1106

          maybe by subclassing QSplitterHandle:

          class Splitter : public QSplitterHandle
          {
              public:
          
                  Splitter(QSplitter* parent=nullptr) : QSplitterHandle(Qt::Horizontal, parent) {}
          
              protected:
          
                  void mouseReleaseEvent(QMouseEvent *) override
                  {
                      int width2=200; // 2nd panel
                      int splitWidth=splitter()->width();
                      if(splitter()->widget(1)->width()==0)
                          splitter()->setSizes({splitWidth-width2,width2});
                      else
                          splitter()->setSizes({splitWidth,00});
                  }
          
                  void mouseMoveEvent(QMouseEvent *) override
                  {
                  }
          };
          

          you have to subclass QSplitter as well and implemente createHandle()

          L 1 Reply Last reply
          1
          • M mpergand

            @lano1106

            maybe by subclassing QSplitterHandle:

            class Splitter : public QSplitterHandle
            {
                public:
            
                    Splitter(QSplitter* parent=nullptr) : QSplitterHandle(Qt::Horizontal, parent) {}
            
                protected:
            
                    void mouseReleaseEvent(QMouseEvent *) override
                    {
                        int width2=200; // 2nd panel
                        int splitWidth=splitter()->width();
                        if(splitter()->widget(1)->width()==0)
                            splitter()->setSizes({splitWidth-width2,width2});
                        else
                            splitter()->setSizes({splitWidth,00});
                    }
            
                    void mouseMoveEvent(QMouseEvent *) override
                    {
                    }
            };
            

            you have to subclass QSplitter as well and implemente createHandle()

            L Offline
            L Offline
            lano1106
            wrote on last edited by
            #5

            @mpergand yes createHandle() is a factory method...

            ok thx a lot for your help. I should have the time play with it over the week-end and report back this question as resolved!

            M 1 Reply Last reply
            0
            • L lano1106

              @mpergand yes createHandle() is a factory method...

              ok thx a lot for your help. I should have the time play with it over the week-end and report back this question as resolved!

              M Offline
              M Offline
              mpergand
              wrote on last edited by
              #6

              @lano1106
              A little more elaborated version:

              class SplitterHandle : public QSplitterHandle
              {
                      void mouseReleaseEvent(QMouseEvent *event) override
                      {
                          if(!rect().contains(event->localPos().toPoint())) return;
              
                          int width2=splitter()->widget(1)->maximumWidth(); // 2nd panel max width
                          int splitWidth=splitter()->width();
                          
                          if(splitter()->widget(1)->width()==0)
                              splitter()->setSizes({splitWidth-width2,width2});
                          else
                              splitter()->setSizes({splitWidth,0});
                      }
              
                      void paintEvent(QPaintEvent *) override
                      {
                          QPainter painter(this);
                          painter.setRenderHint(QPainter::Antialiasing);
              
                          QFont font=this->font();
                          font.setBold(true);
                          painter.setFont(font);
              
                          if(splitter()->widget(1)->width()==0)
                              {
                              painter.drawText(rect(),Qt::AlignCenter,"<");
                              }
                          else
                              painter.drawText(rect(),Qt::AlignCenter,">");
                      }
              
                      void mouseMoveEvent(QMouseEvent *) override
                      {
                          // block mouse move
                      }
              
                      void enterEvent(QEvent *) override
                      {
                          setCursor(Qt::ArrowCursor);
                      }
              
                  public:
              
                      SplitterHandle(QSplitter* parent=nullptr) : QSplitterHandle(Qt::Horizontal, parent) {}
              };
              


              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