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. How to achieve Qt card based layout
Forum Updated to NodeBB v4.3 + New Features

How to achieve Qt card based layout

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 2 Posters 5.2k 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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #2

    Hi
    If you create a custom widget with UI form you can easy just design it and then reuse from code.
    However, how many do you need to have ?
    Many of them say in a scroll view would get heavy on small boards etc but could handle 1000 on a
    Desktop class pc.

    The normal way would be to use a list view + a delegate to draw the card.

    U 1 Reply Last reply
    2
    • mrjjM mrjj

      Hi
      If you create a custom widget with UI form you can easy just design it and then reuse from code.
      However, how many do you need to have ?
      Many of them say in a scroll view would get heavy on small boards etc but could handle 1000 on a
      Desktop class pc.

      The normal way would be to use a list view + a delegate to draw the card.

      U Offline
      U Offline
      Ucn_
      wrote on last edited by
      #3

      @mrjj Do you have any resource on how to start creating the custom widget? The listview you mentioned is it from Ui or QML? Thanks

      mrjjM 1 Reply Last reply
      0
      • U Ucn_

        @mrjj Do you have any resource on how to start creating the custom widget? The listview you mentioned is it from Ui or QML? Thanks

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

        @Ucn_
        Its pure Widgets i was talking about but QML could also be used.

        I was bored so drinking some coffee and making sample. You can have it in a moment for reference.

        alt text

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

          Hi
          Here is custom Widget example.
          https://www.dropbox.com/s/pgf1mippucf36nb/cardTest.zip?dl=0
          Note its fast made so the like and comments are just labels with image.
          You need to use a button instead or
          https://wiki.qt.io/Clickable_QLabel

          Also, to the Card class, you should add access methods like
          setIcon
          SetText
          to be able to set the data from outside without touching the inner UI elements directly.
          Then its completely encapsulated and you can easily reuse it.

          Regarding the listview.
          Reading here will be a start.
          https://doc.qt.io/qt-5/model-view-programming.html
          You would then make a delegate to draw the Card and allow the needed editing, clicking.
          Its a system so some reading is required to understand it.

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

            Hi
            To Create a custom Widget is no more than selecting

            alt text
            (if you want with UI form so u can use designer)

            alt text

            Then you get a cpp , h and ui file with a Widget you can then customize.

            1 Reply Last reply
            1
            • mrjjM mrjj

              Hi
              Here is custom Widget example.
              https://www.dropbox.com/s/pgf1mippucf36nb/cardTest.zip?dl=0
              Note its fast made so the like and comments are just labels with image.
              You need to use a button instead or
              https://wiki.qt.io/Clickable_QLabel

              Also, to the Card class, you should add access methods like
              setIcon
              SetText
              to be able to set the data from outside without touching the inner UI elements directly.
              Then its completely encapsulated and you can easily reuse it.

              Regarding the listview.
              Reading here will be a start.
              https://doc.qt.io/qt-5/model-view-programming.html
              You would then make a delegate to draw the Card and allow the needed editing, clicking.
              Its a system so some reading is required to understand it.

              U Offline
              U Offline
              Ucn_
              wrote on last edited by
              #7

              @mrjj Thanks for the reference. I think my issue was that layouts were creating extra space when adding widgets. I'll stick with pure widgets, I'm not familiar with QML, but I'll have a look

              mrjjM 1 Reply Last reply
              0
              • U Offline
                U Offline
                Ucn_
                wrote on last edited by
                #8

                Sorry, maybe a silly question, but where is ui->CardsLayout? I can't find it in the ui. Or no where except where you mentioned in the mainwindow.cpp

                mrjjM 1 Reply Last reply
                0
                • U Ucn_

                  @mrjj Thanks for the reference. I think my issue was that layouts were creating extra space when adding widgets. I'll stick with pure widgets, I'm not familiar with QML, but I'll have a look

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

                  @Ucn_
                  well the scrollarea/layout will try to compress the widget etc so unless you set fixed size (a max height) on it - it will alter look a lot.

                  Its in forms
                  alt text

                  1 Reply Last reply
                  0
                  • U Ucn_

                    Sorry, maybe a silly question, but where is ui->CardsLayout? I can't find it in the ui. Or no where except where you mentioned in the mainwindow.cpp

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

                    @Ucn_

                    sorry misread.
                    The layout is in
                    scrollAreaWidgetContents
                    alt text

                    U 1 Reply Last reply
                    1
                    • mrjjM mrjj

                      @Ucn_

                      sorry misread.
                      The layout is in
                      scrollAreaWidgetContents
                      alt text

                      U Offline
                      U Offline
                      Ucn_
                      wrote on last edited by
                      #11

                      @mrjj I was looking for it. Thanks. I will play with it and try to implement based on what I want to achieve. I will not mark as the correct answer for now because I may have question regarding the example. So I can come back, I wouldn't like to create another post. I will mark after everything. Thanks for the help

                      1 Reply Last reply
                      0
                      • U Offline
                        U Offline
                        Ucn_
                        wrote on last edited by
                        #12

                        @mrjj when creating Card instance "card":

                            Card * card = new Card;
                            ui->CardsLayout->addWidget(card);
                        

                        Is it possible to give different name each time it's clicked? maybe from a function parameter value or QString value. I'm asking this because later on I may want to removeWidget by name.

                            ui->CardsLayout->removeWidget(card);
                        

                        It may remove all "card". So I would like to have different name for the instance every time is created. Thanks

                        mrjjM 1 Reply Last reply
                        0
                        • U Ucn_

                          @mrjj when creating Card instance "card":

                              Card * card = new Card;
                              ui->CardsLayout->addWidget(card);
                          

                          Is it possible to give different name each time it's clicked? maybe from a function parameter value or QString value. I'm asking this because later on I may want to removeWidget by name.

                              ui->CardsLayout->removeWidget(card);
                          

                          It may remove all "card". So I would like to have different name for the instance every time is created. Thanks

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

                          @Ucn_
                          Hi
                          You can call card->setObjectName("card1");
                          Then have a std::map with names, and widget pointer.

                          Is it just to be able to close it / delete it ?

                          We could close it using only signals
                          and slot but if you need other operations then using names might be easier.

                          U 1 Reply Last reply
                          2
                          • mrjjM mrjj

                            @Ucn_
                            Hi
                            You can call card->setObjectName("card1");
                            Then have a std::map with names, and widget pointer.

                            Is it just to be able to close it / delete it ?

                            We could close it using only signals
                            and slot but if you need other operations then using names might be easier.

                            U Offline
                            U Offline
                            Ucn_
                            wrote on last edited by
                            #14

                            @mrjj Yes I want to be able to replace the info or remove the widget by name if something changes. I will be giving the names dynamically. Also could you tell me how to make the widget appear on top when clicking add? It adds in the middle, I set the CardsLayout VerticalPolicy to fixed. It appears on top, but the height is not adjusting. It squeezes the picture. Thanks

                            mrjjM 1 Reply Last reply
                            0
                            • U Ucn_

                              @mrjj Yes I want to be able to replace the info or remove the widget by name if something changes. I will be giving the names dynamically. Also could you tell me how to make the widget appear on top when clicking add? It adds in the middle, I set the CardsLayout VerticalPolicy to fixed. It appears on top, but the height is not adjusting. It squeezes the picture. Thanks

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

                              @Ucn_
                              Ok, if it has to be by name, the objectname should work good.

                              to have be at top.
                              Add a vertical spacer to the ScroallArea widget
                              alt text

                              alt text

                              and change addWidget to insertWidget
                              ui->CardsLayout->insertWidget(0,card);

                              to have it add to index zero so it comes before the spacer
                              then it will push them up

                              U 1 Reply Last reply
                              1
                              • mrjjM mrjj

                                @Ucn_
                                Ok, if it has to be by name, the objectname should work good.

                                to have be at top.
                                Add a vertical spacer to the ScroallArea widget
                                alt text

                                alt text

                                and change addWidget to insertWidget
                                ui->CardsLayout->insertWidget(0,card);

                                to have it add to index zero so it comes before the spacer
                                then it will push them up

                                U Offline
                                U Offline
                                Ucn_
                                wrote on last edited by Ucn_
                                #16

                                @mrjj Thanks. It does the job. However, the card doesn't expand its height, it squeezes the rest if a new layout with widgets is added And ui->CardsLayout->removeWidget() won't take QString in the parameter. I came up with this solution, I created QVector-QWidget-cards*. And every time I add a widget to the layout I also append to cards. Then for deleting I do this:

                                for (int i = 0; i < cards.size(); ++i) {
                                if (cards.at(i)->objectName() == ui->lineEdit->text()){

                                        qDebug () << "widget found at " << i << cards.at(i) << cards.at(i)->objectName();
                                        delete cards.at(i);
                                        cards.removeAt(i);
                                    }
                                }
                                
                                mrjjM 1 Reply Last reply
                                1
                                • U Ucn_

                                  @mrjj Thanks. It does the job. However, the card doesn't expand its height, it squeezes the rest if a new layout with widgets is added And ui->CardsLayout->removeWidget() won't take QString in the parameter. I came up with this solution, I created QVector-QWidget-cards*. And every time I add a widget to the layout I also append to cards. Then for deleting I do this:

                                  for (int i = 0; i < cards.size(); ++i) {
                                  if (cards.at(i)->objectName() == ui->lineEdit->text()){

                                          qDebug () << "widget found at " << i << cards.at(i) << cards.at(i)->objectName();
                                          delete cards.at(i);
                                          cards.removeAt(i);
                                      }
                                  }
                                  
                                  mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #17

                                  @Ucn_
                                  Hi
                                  The card has a fixed size set to prevent it from being compressed below the design size.
                                  You can just make it bigger if you need more room.

                                  The QVector is a fine idea, however, if you had many Cards to manage , i think i would have used
                                  std::map<QString, Card *> CardsMap;
                                  To avoid having to loop a list to find the one i want. std::map supports direct lookup
                                  but for a small set of Cards, it really dont matter.

                                  U 1 Reply Last reply
                                  1
                                  • mrjjM mrjj

                                    @Ucn_
                                    Hi
                                    The card has a fixed size set to prevent it from being compressed below the design size.
                                    You can just make it bigger if you need more room.

                                    The QVector is a fine idea, however, if you had many Cards to manage , i think i would have used
                                    std::map<QString, Card *> CardsMap;
                                    To avoid having to loop a list to find the one i want. std::map supports direct lookup
                                    but for a small set of Cards, it really dont matter.

                                    U Offline
                                    U Offline
                                    Ucn_
                                    wrote on last edited by
                                    #18

                                    @mrjj Thanks, I will give a try with map. About the size, I set the card sizePolicy to Expanding still squeezing.

                                    mrjjM 1 Reply Last reply
                                    0
                                    • U Ucn_

                                      @mrjj Thanks, I will give a try with map. About the size, I set the card sizePolicy to Expanding still squeezing.

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

                                      @Ucn_ said in How to achieve Qt card based layout:

                                      Expanding still squeezing.

                                      Yeah, it will be squeezed if many cards are added. You have to set a minimum Height to avoid that.
                                      On the Top Card in UI. So the laytout wont make it smaller if it can.
                                      Even when set to Expanding, its only when there are left over space , however, we add them next to each other so it tries to fit as many as possible and unless we say Not smaller than this, it might not look like we want to.

                                      U 1 Reply Last reply
                                      0
                                      • mrjjM mrjj

                                        @Ucn_ said in How to achieve Qt card based layout:

                                        Expanding still squeezing.

                                        Yeah, it will be squeezed if many cards are added. You have to set a minimum Height to avoid that.
                                        On the Top Card in UI. So the laytout wont make it smaller if it can.
                                        Even when set to Expanding, its only when there are left over space , however, we add them next to each other so it tries to fit as many as possible and unless we say Not smaller than this, it might not look like we want to.

                                        U Offline
                                        U Offline
                                        Ucn_
                                        wrote on last edited by
                                        #20

                                        @mrjj This is what I'm trying to achieve:
                                        hover.gif

                                        mrjjM 1 Reply Last reply
                                        0
                                        • U Ucn_

                                          @mrjj This is what I'm trying to achieve:
                                          hover.gif

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

                                          @Ucn_
                                          Hi
                                          Well pictures help so much. :)
                                          You have to alter the Maximum Height to allow for the popup lineEdit.
                                          It seems its not allow to alter Card size so it will compress the other elements to
                                          make room.

                                          Ps. its looking good :)

                                          1 Reply Last reply
                                          0

                                          • Login

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