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. Adding & Deleting Rows to/from QGridLayout
Forum Updated to NodeBB v4.3 + New Features

Adding & Deleting Rows to/from QGridLayout

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 3 Posters 10.4k Views 2 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.
  • ModelTechM Offline
    ModelTechM Offline
    ModelTech
    wrote on last edited by ModelTech
    #1

    I have a QWidget that includes a QGridLayout, Layout. This QGridLayout has on each row two QLineEdit's and one QPushButton, which are part of an Object of MyClass. The Layout has one header row at the top (row 0) and all Objects are stored in the ObjectList (a QList).

    I have written the following code to remove a row regarding a specific Object.

    // Deleting an Object
    Layout->removeWidget(Object->LineEdit1());
    Layout->removeWidget(Object->LineEdit2());
    Layout->removeWidget(Object->PushButton());
    ObjectList.removeOne(Object);
    delete Object;                                     // Deletes its LineEdit1, LineEdit2 and PushButton
    

    To add a row for a new Object, I have the following code.

    // Adding a new Object
    MyClass *Object = new MyClass;     // Creates its LineEdit1, LineEdit2 and PushButton
    ObjectList.append(Object);
    Layout->addWidget(Object->LineEdit1(), ObjectList.size() + 1, 0);
    Layout->addWidget(Object->LineEdit2(), ObjectList.size() + 1, 1);
    Layout->addWidget(Object->PushButton(), ObjectList.size() + 1, 2);
    

    For some reason this code does not always work according to my expectation. In some situations the new Object does become visible and in other situations not, or at least no new row becomes visible (while the new Object is actually created). It seems that an existing row is basically overwritten with a row for the new Object.

    Anyone a clue of what I am doing wrongly?

    1 Reply Last reply
    0
    • ModelTechM Offline
      ModelTechM Offline
      ModelTech
      wrote on last edited by
      #2

      I may have clarified the symptom a bit: It seems that if not the last row in the QGridLayout deleted but any other row, a subsequent addition of a new row overwrites a row that remained to exist. How to enforce QGridLayout to delete rows that do not contain any Widgets anymore?

      kshegunovK 1 Reply Last reply
      0
      • ModelTechM ModelTech

        I may have clarified the symptom a bit: It seems that if not the last row in the QGridLayout deleted but any other row, a subsequent addition of a new row overwrites a row that remained to exist. How to enforce QGridLayout to delete rows that do not contain any Widgets anymore?

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #3

        @ModelTech said:

        How to enforce QGridLayout to delete rows that do not contain any Widgets anymore?

        You can't, you have to manually shift up (left) all cells below (right).

        Read and abide by the Qt Code of Conduct

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

          @ModelTech said:

          delete Object;

          does this delete the widgets also?
          Object will delete its widgets. ?

          removeWidget only removes from grid management.
          They are still drawing.

          works for me in this mini sample based on ur code
          https://www.dropbox.com/s/1y693yg1w409vr1/mygridlayout.zip?dl=0

          update:
          Oh, you want to remove random rows ?
          I assumed u removed last.

          well then @kshegunov beat me to it :)

          1 Reply Last reply
          0
          • ModelTechM Offline
            ModelTechM Offline
            ModelTech
            wrote on last edited by ModelTech
            #5

            Ok, I found a solution, but I am not sure whether I like it... I changed the code to add an Object to:

            // Adding a new Object
            MyClass *Object = new MyClass;     // Creates its LineEdit1, LineEdit2 and PushButton
            ObjectList.append(Object);
            int Count = Layout->rowCount();
            Layout->addWidget(Object->LineEdit1(), Count, 0);
            Layout->addWidget(Object->LineEdit2(), Count, 1);
            Layout->addWidget(Object->PushButton(), Count, 2);
            

            Is this really the way it should be done? I would expect that this creates a lot of empty rows / cells in the QGridLayout that only consume memory (although probably not much).

            And yes, I want to delete random rows, not necessarily the last one.

            1 Reply Last reply
            0
            • kshegunovK kshegunov

              @ModelTech said:

              How to enforce QGridLayout to delete rows that do not contain any Widgets anymore?

              You can't, you have to manually shift up (left) all cells below (right).

              ModelTechM Offline
              ModelTechM Offline
              ModelTech
              wrote on last edited by
              #6

              @mrjj said:

              does this delete the widgets also?

              Yes, it does...

              @kshegunov said:

              @ModelTech said:

              How to enforce QGridLayout to delete rows that do not contain any Widgets anymore?

              You can't, you have to manually shift up (left) all cells below (right).

              How can I implement a shift up / down?

              kshegunovK 1 Reply Last reply
              0
              • ModelTechM ModelTech

                @mrjj said:

                does this delete the widgets also?

                Yes, it does...

                @kshegunov said:

                @ModelTech said:

                How to enforce QGridLayout to delete rows that do not contain any Widgets anymore?

                You can't, you have to manually shift up (left) all cells below (right).

                How can I implement a shift up / down?

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #7

                @ModelTech

                You can use QLayout::takeAt() and QLayout::count() to get the layout items back from the layout. Some time ago I needed a dial widget that managed tool buttons from QAction instances, here's the code if you'd want to take a look. There's item removal when actions are added/removed, so you can draw some inspiration from it.

                Edit: Specifically, look here and here.

                Kind regards.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                0
                • ModelTechM Offline
                  ModelTechM Offline
                  ModelTech
                  wrote on last edited by
                  #8

                  Thanks for that @kshegunov. If I understand your code correctly, then you seem to rely on count() for QStackLayout. As it turns out rowCount() for QGridLayout does not reduce when deleting all widgets of some row...

                  kshegunovK 1 Reply Last reply
                  0
                  • ModelTechM ModelTech

                    Thanks for that @kshegunov. If I understand your code correctly, then you seem to rely on count() for QStackLayout. As it turns out rowCount() for QGridLayout does not reduce when deleting all widgets of some row...

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #9

                    @ModelTech
                    No, there are QWidgets stacked in a QStackWidget (the createPage method) but each "page" uses a QGridLayout in which it puts buttons. The pages are organized in a tree, where each page gets a return button in the beginning. When there's a QAction instance added, a new button is appended to the corresponding page's layout and when a QAction is removed the button is removed. The interesting part, at least for you, is how the layout is "recreated" in AgDialPrivate::invalidateLayout when a button is added or removed.
                    Basically the idea is this:

                    • everything after button index from have to be moved to its proper position, because after removing a button (layout item) there's a hole left in the layout.
                    • every layout item that's after index from is taken out of the layout (line 58) and put into a stack for reinsertion.
                    • for each of the extracted items a new position is calculated based on the total number of items in the grid (line 62)
                    • the item is reinserted in the layout at its new and correct position (line 63)

                    The function uses the internal index of the items which is independent of their position (row, column) in the layout for extraction, and then based on the number of items the row and column is calculated, and finally the item is reinserted in the correct cell.

                    Read and abide by the Qt Code of Conduct

                    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