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. Create customized Container-Widget
Forum Updated to NodeBB v4.3 + New Features

Create customized Container-Widget

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 3 Posters 2.5k 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.
  • J Offline
    J Offline
    justStartedQt
    wrote on last edited by
    #1

    Hi everyone,
    I am trying to archieve something like the following using Qt:

    0_1512663829627_TabFrame.png

    The idea is to have a customized Frame with an extended title-area on top. Therefore I want to subclass QWidget or a derived class like QFrame. And of course rewrite the paintEvent.
    The Challenge in this case is, that the Widget should be used as a container for other widgets, similar to QFrame:

    0_1512663894030_TabFrameAreas.png

    So the differnce to a QFrame would be, that it will have two different Areas (black lines):

    • the Outer-Frame, which has to interacts with its neighbors/Splitters/Layouts
    • the Inner-Frame, which contains other widgets (red, blue, green)

    I found a lot of documents and tutorials about basic Widget-Subclassing out there, but not about using it as a container.

    I know about the possibility of writing plugins, but I don‘t need an integration in the Qt Designer-interface. So that is maybe (?) not necessary.

    I am just looking for a general idea like: „Simply subclass QFrame and …(some useful operation here).“
    Every hint or link to a useful doc is welcome!

    Thank you so much,
    your justStartedQt

    VRoninV 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi and welcome.
      for the inner-frame I think you can just use layouts to have them
      arranged like that
      http://doc.qt.io/qt-5/layout.html
      The http://doc.qt.io/qt-5/qgridlayout.html seems like a good match

      alt text

      And you can just use the promotion feature to use your custom widget.
      a full plugin is not needed.

      Regarding Containers.
      If you add a layout to any widget , it can be a container. (most anyway)

      J 1 Reply Last reply
      3
      • J justStartedQt

        Hi everyone,
        I am trying to archieve something like the following using Qt:

        0_1512663829627_TabFrame.png

        The idea is to have a customized Frame with an extended title-area on top. Therefore I want to subclass QWidget or a derived class like QFrame. And of course rewrite the paintEvent.
        The Challenge in this case is, that the Widget should be used as a container for other widgets, similar to QFrame:

        0_1512663894030_TabFrameAreas.png

        So the differnce to a QFrame would be, that it will have two different Areas (black lines):

        • the Outer-Frame, which has to interacts with its neighbors/Splitters/Layouts
        • the Inner-Frame, which contains other widgets (red, blue, green)

        I found a lot of documents and tutorials about basic Widget-Subclassing out there, but not about using it as a container.

        I know about the possibility of writing plugins, but I don‘t need an integration in the Qt Designer-interface. So that is maybe (?) not necessary.

        I am just looking for a general idea like: „Simply subclass QFrame and …(some useful operation here).“
        Every hint or link to a useful doc is welcome!

        Thank you so much,
        your justStartedQt

        VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #3

        @justStartedQt said in Create customized Container-Widget:

        Hi everyone,
        I am trying to archieve something like the following using Qt:

        0_1512663829627_TabFrame.png

        Isn't that just a QTabWidget with a bit of stylesheet on top?

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        3
        • mrjjM mrjj

          Hi and welcome.
          for the inner-frame I think you can just use layouts to have them
          arranged like that
          http://doc.qt.io/qt-5/layout.html
          The http://doc.qt.io/qt-5/qgridlayout.html seems like a good match

          alt text

          And you can just use the promotion feature to use your custom widget.
          a full plugin is not needed.

          Regarding Containers.
          If you add a layout to any widget , it can be a container. (most anyway)

          J Offline
          J Offline
          justStartedQt
          wrote on last edited by
          #4

          @mrjj
          First of all: thank you for this fast answer.
          So the "Outer-Frame" would be my Subclassed QFrame / QWidget. But how would Widgets, which I place inside my Frame (examples in red, blue, green) then now, that they have to use only the area i called "Inner-Frame"?
          Maybe a stupid Question, but thank you very much anyway.

          mrjjM 1 Reply Last reply
          0
          • J justStartedQt

            @mrjj
            First of all: thank you for this fast answer.
            So the "Outer-Frame" would be my Subclassed QFrame / QWidget. But how would Widgets, which I place inside my Frame (examples in red, blue, green) then now, that they have to use only the area i called "Inner-Frame"?
            Maybe a stupid Question, but thank you very much anyway.

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by mrjj
            #5

            @justStartedQt
            Im not sure excactly what you mean.
            The Color widgets would be in a layout and stay inside the area defined by the
            owner of the layout.And you just insert the widgets into the layout and they can only use the the space assigned.
            The layout have margins and you can just raise the top margin to have some "air" above it.

            Also as @VRonin says, you could style QTabWidget
            to make it look like that and then use layout in its "page" to have
            one or more QFrame with the color widgets. And the color widget
            would stay inside the QFrame.

            http://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtabwidget-and-qtabbar

            If i understand you correctly i think you can just nest QFrame or widgets and use layout to get the feature you want.

            alt text

            1 Reply Last reply
            1
            • J Offline
              J Offline
              justStartedQt
              wrote on last edited by
              #6

              Hi again and thanks that you are trying to help me.
              I maybe haven't really expressed clearly what I mean.

              Its Maybe not really about Tabs, because the widget will always have only 1 Title and therefore only 1 Content. Also there is no extra functionality like moving it. It is more like a decorated Frame, which holds content/other widgets.

              0_1512674392569_TabFrame2.png

              Besides I want to reuse that widget like in the Image. Or even subclass it again for something else. In your Example (I'm sorry, if I missunderstood that) it looks like you rather used multiple Widgets placed together than creating a single new one?

              Possibility 1: I create the Widget MyTitleFrame by subclassing QFrame. But if I now parent fx. a Pushbutton to it, how would the Pushbutton then know, that there is a special area for the Child-Widgets? All Widgets would just use all the space in the "MainFrame".

              0_1512675064396_TabFrameArea2.png

              Possibility 2: I create the Widget MyTitleFrame by subclassing QFrame, which holds another Frame. This "Inner-Frame" could be used to place other Widgets correctly. But if I now parent a Pushbutton to a MyTitleFrame, how does the Pushbutton know, that it should not use the "Mainframe", but the "Inner-Frame".

              I try my best to communicate my problem, but I see that I am not as good in it.

              Thank you anyway for your repeated efforts, mrjj.

              1 Reply Last reply
              0
              • mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi
                Yes my sample is made of multiple widgets The tab Width has an inner QFrame with layout
                and that inner QFrame has the gridlayout ( like your Possibility 2, but i used a tab to get the caption thing easy)
                You can easy use such construct by dragging it to the left side widget list and get a "template"
                than you can drag into any form again.

                Possibility 1:
                One way would to use a layout and set topmargin as then the button would obey that.
                You would still be able to draw on the widget (outside layout) but any widget you insert would
                respect the layout. You can then draw the inner black frame in paint event, using the layouts margins as offset.
                Using stylesheets, a widgets can have border too. It dont have to be QFrame. Also your frame seems
                pretty simple so subclassing widget would also work fine and simply draw it.

                Possibility 2:
                You insert the Pushbutton to the correct frame/layout. like Inner-Frame->layout()->AddWidget(QPushButton)
                And then it stays there. You would not insert into MyTitleFrame layout/parent to MyTitleFrame

                When inserting widgets into other widgets, you use layout most of the time as else the inner widget will be free floating
                and not scale with parent. (which is often desired)
                So a child widget stays inside the parent and if parent have layout it will be handled by the layout.

                But if you rather make a custom widget, its also quite feasible but if you dont use a layout,
                you will manually have to make sure any child are moved down. You could use stylesheet and
                make use of the http://doc.qt.io/qt-5/stylesheet-customizing.html to make sure its moved but mixing
                custom drawing and stylesheet is more involving that simply using a layout with top margin set to what ever offset you want.
                (so it dont start up in the caption area)
                The simply draw the inner frame with info from the layout and also draw Title and outerframe.

                1 Reply Last reply
                1
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  Hi
                  for learning, here is a fast implementation of a drawn version.
                  Its not perfect but demostrates how it can be done with painting +layout.

                  #ifndef TITLEFRAMEWIDGET_H
                  #define TITLEFRAMEWIDGET_H
                  
                  #include <QGridLayout>
                  #include <QPainter>
                  #include <QPushButton>
                  #include <QWidget>
                  
                  class TitleFrameWidget : public QWidget {
                    Q_OBJECT
                    QGridLayout* gridLayout;
                    const int TitleHeightBox = 22;
                    const int TopMargin = 20; // air to widget area
                    const int pad = 4;
                    const int innerpad = 2;
                  public:
                    explicit TitleFrameWidget(QWidget* parent = nullptr) : QWidget(parent) {
                      gridLayout = new QGridLayout(this);
                      gridLayout->setObjectName(QStringLiteral("gridLayout"));
                     gridLayout->setContentsMargins(pad, TopMargin+TitleHeightBox, pad + (innerpad * 2), pad );
                      // for test
                      gridLayout->addWidget( new QPushButton("tester"));
                    }
                  signals:
                  public slots:
                  protected:
                    virtual void paintEvent(QPaintEvent* event) override {
                      QPainter p(this);
                      QString Title = "Title"; // Title text should be a property or at least be set via ctor
                      // get Title size
                      QFontMetrics fm( font() );
                      int tw = fm.width(Title);
                      int th = fm.height();
                      // draw title bg
                      QRect outerframe  (0, TitleHeightBox, width() - 1 - pad, height() - TitleHeightBox - 1); // -1 is long story..
                      p.drawRect(outerframe);
                      // title rect
                      p.setBrush(QBrush(QColor(96, 96, 96)));
                      p.setPen(Qt::NoPen);
                      p.drawRect(pad, 0, width() - (  width() * 0.30), TitleHeightBox ); // 30 % width
                      // draw Title
                      p.setPen(Qt::white); // used for text color
                      p.drawText(pad * 2, tw, Title);
                      // inner frame
                      QRect innerframe = outerframe;
                      innerframe -= QMargins(2, TopMargin, 2, 2);
                      p.setPen(QColor(96, 96, 96));
                      p.setBrush(Qt::NoBrush);
                      p.drawRect(innerframe);
                    }
                  };
                  #endif // TITLEFRAMEWIDGET_H
                  
                  

                  alt text

                  Using layout we prevent it from covering the title area/have what ever offset we want.
                  alt text

                  That shown. I would say just using some widgets inside each other to gain same effect is less work as you get adjustable margins and and settable titel for free. Directly in Designer.
                  However it is indeed possible to handcraft one :)

                  1 Reply Last reply
                  5

                  • Login

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