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. Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget
Forum Updated to NodeBB v4.3 + New Features

Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 1.4k Views 3 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.
  • R Offline
    R Offline
    rand10cs
    wrote on 30 May 2021, 10:52 last edited by rand10cs
    #1

    The aim is in the subject. I want to be available to add multiple items at the same cell in my table and display this behaviour using a tab. I don't know much about subclassing but I eventually get this compilable solution which does not work though (nothing is displayed).

    Part of my header (the rest is the parent widget (window) class) :

    class CustomItem : public QTableWidgetItem, public QTabWidget
    {
    public:
        explicit CustomItem();
    };
    

    Concerned parts of my cpp

    CustomItem::CustomItem() : QTableWidgetItem(), QTabWidget()
    {
    }
    
    void PlanningWindow::changeDay()
    {
        // clear the QTableView contents
        view->clearContents();
    
        CustomItem* testCustom = new CustomItem();
        testCustom->addTab(new QLabel(), "Works !");
    
        view->setItem(15,0,testCustom); // does not display anything in the corresponding cell of my QTableView
    }
    

    Thank you for your help and/or suggestions.

    J 1 Reply Last reply 30 May 2021, 11:48
    0
    • R rand10cs
      30 May 2021, 10:52

      The aim is in the subject. I want to be available to add multiple items at the same cell in my table and display this behaviour using a tab. I don't know much about subclassing but I eventually get this compilable solution which does not work though (nothing is displayed).

      Part of my header (the rest is the parent widget (window) class) :

      class CustomItem : public QTableWidgetItem, public QTabWidget
      {
      public:
          explicit CustomItem();
      };
      

      Concerned parts of my cpp

      CustomItem::CustomItem() : QTableWidgetItem(), QTabWidget()
      {
      }
      
      void PlanningWindow::changeDay()
      {
          // clear the QTableView contents
          view->clearContents();
      
          CustomItem* testCustom = new CustomItem();
          testCustom->addTab(new QLabel(), "Works !");
      
          view->setItem(15,0,testCustom); // does not display anything in the corresponding cell of my QTableView
      }
      

      Thank you for your help and/or suggestions.

      J Offline
      J Offline
      JonB
      wrote on 30 May 2021, 11:48 last edited by
      #2

      @rand10cs said in Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget:

      I don't know much about subclassing

      :)

      class CustomItem : public QTableWidgetItem, public QTabWidget

      You should keep sub-classes separate. You don't want/can't have a class which is somehow both a table widget item and a tab widget. At least in my opinion. If you need to sub-class both of these, I would do it in two separate sub-classes, one for each.

      I'm not sure how your whole idea is supposed to work. A QTableWidget has an inbuilt model, and each item/cell stores/displays what is one index into the model. I don't know how your individual cell in the model is going to hold data such that it maps to/from your multi-item tab widget.

      1 Reply Last reply
      1
      • M Offline
        M Offline
        mrjj
        Lifetime Qt Champion
        wrote on 30 May 2021, 12:15 last edited by
        #3

        Hi

        • add multiple items at the same cell in my table and display this behavior using a tab.

        Im not really sure how this is supposed to work?

        So inside the cell, there would be 2 tabs and if you click one, it shows value one and if you click tab2 it shows value 2
        or what was the idea with this? It sounds a bit o.O and would take up way to much space in a cell. the cells would have to be huge for this.

        R 1 Reply Last reply 30 May 2021, 12:36
        1
        • M mrjj
          30 May 2021, 12:15

          Hi

          • add multiple items at the same cell in my table and display this behavior using a tab.

          Im not really sure how this is supposed to work?

          So inside the cell, there would be 2 tabs and if you click one, it shows value one and if you click tab2 it shows value 2
          or what was the idea with this? It sounds a bit o.O and would take up way to much space in a cell. the cells would have to be huge for this.

          R Offline
          R Offline
          rand10cs
          wrote on 30 May 2021, 12:36 last edited by
          #4

          @JonB By reading you, I understand in some way that I can't do what I want. I "merged" the inheritance because I want to pass a QTabWidget as item of my QTableWidget but QTableWidget only accepts QTableWidgetItem.

          I thought about another possibility. Is it possible to do something like that while keeping my QTableWidget ? If no, what should I use and how could I do it ?
          Screenshot 2021-05-30 at 14.14.20.png

          Actually, in my project, :

          • the whole blank rectangle in the picture refers to a QTableWidget
          • the hours on the left refer to the vertical header labels of my QTableWidget (along with half hours I added in between each time)
          • each half an hour is a row of my QTableWidget

          The problem is that if I want to do that straighforwardly, I span my cells from Row#1 (8h30) to Row#20 (18h00) and add the green event. But when I add the blue event at 15h00 and I span from Row#14 to Row#18, it is either hidden by the green event or downright not added at all.

          @mrjj Yeah that's the idea. My cells are large enough I think. In my example above, it would create a tab when two events start at the same time (each half hour being a row). The easiest solution would have been to use several columns instead but it is not possible since it could use too many columns when like 5 or 6 events starts at the same time.

          A 1 Reply Last reply 1 Jun 2021, 18:01
          0
          • R Offline
            R Offline
            rand10cs
            wrote on 1 Jun 2021, 17:14 last edited by
            #5

            Can someone kindly help me with that ?

            J 1 Reply Last reply 1 Jun 2021, 17:39
            0
            • R rand10cs
              1 Jun 2021, 17:14

              Can someone kindly help me with that ?

              J Offline
              J Offline
              JonB
              wrote on 1 Jun 2021, 17:39 last edited by
              #6

              @rand10cs
              Whether using a QTableWidget for this is the best or you would be better with something custom I don't know. Someone like @mrjj may see this and comment.

              The problem is that if I want to do that straighforwardly, I span my cells from Row#1 (8h30) to Row#20 (18h00) and add the green event. But when I add the blue event at 15h00 and I span from Row#14 to Row#18, it is either hidden by the green event or downright not added at all.

              I don't imagine QTableWidget spanning allows that. You have "overlapping" rows now from 14--18. I would have thought you would have to "split" the first event into two: 8:30--15:00 and 17:00--18:00. You seem to want something which allows multiple layers/overlaps. Hence why this may not be the best widget to use.

              R 1 Reply Last reply 2 Jun 2021, 16:39
              1
              • R rand10cs
                30 May 2021, 12:36

                @JonB By reading you, I understand in some way that I can't do what I want. I "merged" the inheritance because I want to pass a QTabWidget as item of my QTableWidget but QTableWidget only accepts QTableWidgetItem.

                I thought about another possibility. Is it possible to do something like that while keeping my QTableWidget ? If no, what should I use and how could I do it ?
                Screenshot 2021-05-30 at 14.14.20.png

                Actually, in my project, :

                • the whole blank rectangle in the picture refers to a QTableWidget
                • the hours on the left refer to the vertical header labels of my QTableWidget (along with half hours I added in between each time)
                • each half an hour is a row of my QTableWidget

                The problem is that if I want to do that straighforwardly, I span my cells from Row#1 (8h30) to Row#20 (18h00) and add the green event. But when I add the blue event at 15h00 and I span from Row#14 to Row#18, it is either hidden by the green event or downright not added at all.

                @mrjj Yeah that's the idea. My cells are large enough I think. In my example above, it would create a tab when two events start at the same time (each half hour being a row). The easiest solution would have been to use several columns instead but it is not possible since it could use too many columns when like 5 or 6 events starts at the same time.

                A Offline
                A Offline
                artwaw
                wrote on 1 Jun 2021, 18:01 last edited by
                #7

                @rand10cs I think it's doable but not easy.
                Mind you, I never tried to design something that would work that way but...

                I'd drop TableWidget in favour of TableView/ListView and deploy a model. Can be simple one, doesn't matter. Now, sticking to your calendar example...
                I can see how this can work with a db (can be Sqlite - I work with dbs mostly so it is easier for me to think that way but how you implement the model is absolutely your thing).
                I'd create two tables - one with simple one row per hour design (more on that later) and second table holding just the events - columns id, description, colour and whatever else you need.

                Now, back to first table - I'd give a column for datetime (24 rows per day), id of the event (if any, can be null). If the future day doesn't have the event the day doesn't exist in the table, if future event is created all the days between the end of the table and the event (up to the end of the day on the event day) are created.

                This can probably be simplified somehow, I am writing as I think...

                Now the display can be held as a delegate on per row/hr basis - if the "event id" column has the data the field is painted in corresponding colour, if more events are present (comma separated list?) the display is responding painting over the colours with the shift to right by a few pixels and the newest/latest added on top.

                It's just an idea and with the db approach would probably require either internal sql query from the delegate to the event table (dirty, don't like it) or QSqlRelationalTable and delegate to work.

                Doable I think. (don't shoot if I made some grave errors, it's just a thought experiment)

                For more information please re-read.

                Kind Regards,
                Artur

                R 1 Reply Last reply 2 Jun 2021, 16:21
                1
                • A artwaw
                  1 Jun 2021, 18:01

                  @rand10cs I think it's doable but not easy.
                  Mind you, I never tried to design something that would work that way but...

                  I'd drop TableWidget in favour of TableView/ListView and deploy a model. Can be simple one, doesn't matter. Now, sticking to your calendar example...
                  I can see how this can work with a db (can be Sqlite - I work with dbs mostly so it is easier for me to think that way but how you implement the model is absolutely your thing).
                  I'd create two tables - one with simple one row per hour design (more on that later) and second table holding just the events - columns id, description, colour and whatever else you need.

                  Now, back to first table - I'd give a column for datetime (24 rows per day), id of the event (if any, can be null). If the future day doesn't have the event the day doesn't exist in the table, if future event is created all the days between the end of the table and the event (up to the end of the day on the event day) are created.

                  This can probably be simplified somehow, I am writing as I think...

                  Now the display can be held as a delegate on per row/hr basis - if the "event id" column has the data the field is painted in corresponding colour, if more events are present (comma separated list?) the display is responding painting over the colours with the shift to right by a few pixels and the newest/latest added on top.

                  It's just an idea and with the db approach would probably require either internal sql query from the delegate to the event table (dirty, don't like it) or QSqlRelationalTable and delegate to work.

                  Doable I think. (don't shoot if I made some grave errors, it's just a thought experiment)

                  R Offline
                  R Offline
                  rand10cs
                  wrote on 2 Jun 2021, 16:21 last edited by
                  #8

                  Thanks for your deep reply ! The good thing is that I already have a model in which my events are stored (actually I started with a TableView alongside but there were displaying problems so I switch to a TableWidget displaying only few information about an event). I can then take this model as a basis for further displaying.

                  @artwaw said in Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget:

                  Now the display can be held as a delegate on per row/hr basis - if the "event id" column has the data the field is painted in corresponding colour, if more events are present (comma separated list?) the display is responding painting over the colours with the shift to right by a few pixels and the newest/latest added on top.

                  I think this quoted paragraph is very interesting and should do the work at first sight. However I can't get how you would implement it. I mean what would you exactly use to design it ?

                  Thanks again for your time

                  A 1 Reply Last reply 2 Jun 2021, 16:44
                  0
                  • J JonB
                    1 Jun 2021, 17:39

                    @rand10cs
                    Whether using a QTableWidget for this is the best or you would be better with something custom I don't know. Someone like @mrjj may see this and comment.

                    The problem is that if I want to do that straighforwardly, I span my cells from Row#1 (8h30) to Row#20 (18h00) and add the green event. But when I add the blue event at 15h00 and I span from Row#14 to Row#18, it is either hidden by the green event or downright not added at all.

                    I don't imagine QTableWidget spanning allows that. You have "overlapping" rows now from 14--18. I would have thought you would have to "split" the first event into two: 8:30--15:00 and 17:00--18:00. You seem to want something which allows multiple layers/overlaps. Hence why this may not be the best widget to use.

                    R Offline
                    R Offline
                    rand10cs
                    wrote on 2 Jun 2021, 16:39 last edited by
                    #9

                    @JonB said in Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget:

                    I would have thought you would have to "split" the first event into two: 8:30--15:00 and 17:00--18:00

                    The only (big) drawback of that is that I can handle multiple events starting at different times but ending at the same time... Thanks for the suggestion though

                    1 Reply Last reply
                    0
                    • R rand10cs
                      2 Jun 2021, 16:21

                      Thanks for your deep reply ! The good thing is that I already have a model in which my events are stored (actually I started with a TableView alongside but there were displaying problems so I switch to a TableWidget displaying only few information about an event). I can then take this model as a basis for further displaying.

                      @artwaw said in Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget:

                      Now the display can be held as a delegate on per row/hr basis - if the "event id" column has the data the field is painted in corresponding colour, if more events are present (comma separated list?) the display is responding painting over the colours with the shift to right by a few pixels and the newest/latest added on top.

                      I think this quoted paragraph is very interesting and should do the work at first sight. However I can't get how you would implement it. I mean what would you exactly use to design it ?

                      Thanks again for your time

                      A Offline
                      A Offline
                      artwaw
                      wrote on 2 Jun 2021, 16:44 last edited by
                      #10

                      @rand10cs said in Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget:

                      I mean what would you exactly use to design it ?

                      Short answer would be "my brain, my keyboard and Qt Documentation" but I think I know what you mean.

                      As I hope you are aware from here https://doc.qt.io/qt-5/model-view-programming.html model is responsible for holding the data, the delegate for rendering the single unit of data (let's say) and the view for displaying the rendered content to the user, if you allow me to simplify that much.

                      My approach would be to create descendant of QStyledItemDelegate that would handle rendering of a single cell (in QTableView) or a row (in QListView). Creating custom delegates is well documented under the links in this post.

                      The real problem is how to get the data for the delegate - as I said in my previous post all depends on how you store the data. But there is plenty of options readily available - for example data roles in model, we have Qt::BackgroundRole that can be set upon event creation (this way the single cell/row/hr will hold the latest colour only though)... That all depends on how you design it.

                      For more information please re-read.

                      Kind Regards,
                      Artur

                      R 1 Reply Last reply 2 Jun 2021, 17:18
                      2
                      • A artwaw
                        2 Jun 2021, 16:44

                        @rand10cs said in Subclassing QTableWidgetItem and QTabWidget to add QTabWidget in QTableWidget:

                        I mean what would you exactly use to design it ?

                        Short answer would be "my brain, my keyboard and Qt Documentation" but I think I know what you mean.

                        As I hope you are aware from here https://doc.qt.io/qt-5/model-view-programming.html model is responsible for holding the data, the delegate for rendering the single unit of data (let's say) and the view for displaying the rendered content to the user, if you allow me to simplify that much.

                        My approach would be to create descendant of QStyledItemDelegate that would handle rendering of a single cell (in QTableView) or a row (in QListView). Creating custom delegates is well documented under the links in this post.

                        The real problem is how to get the data for the delegate - as I said in my previous post all depends on how you store the data. But there is plenty of options readily available - for example data roles in model, we have Qt::BackgroundRole that can be set upon event creation (this way the single cell/row/hr will hold the latest colour only though)... That all depends on how you design it.

                        R Offline
                        R Offline
                        rand10cs
                        wrote on 2 Jun 2021, 17:18 last edited by
                        #11

                        @artwaw Alright thank you I will have a try. I'll comeback to you when I succeed or if I'm eventually stuck.

                        R 1 Reply Last reply 10 Jun 2021, 11:04
                        0
                        • R rand10cs
                          2 Jun 2021, 17:18

                          @artwaw Alright thank you I will have a try. I'll comeback to you when I succeed or if I'm eventually stuck.

                          R Offline
                          R Offline
                          rand10cs
                          wrote on 10 Jun 2021, 11:04 last edited by
                          #12

                          I come back to give y'all what I finally succeed to do. I struggled a lot understanding and above all trying to apply something convenient with delegate. It is still very abstract to me.

                          In order to design something answering my issue, I added a fixed number of narrow columns next to each initial column of my QTableWidget. This is somehow limiting the number of events that can happen in the same period but it should not impact the way I will use it though.

                          Thanks to that, I have been able to manage something like this which is now perfectly functional (up to 4 events in the same period but I could have added more narrow columns to manage more parallel events).

                          Screenshot 2021-06-10 at 12.59.26.png

                          Thanks you all for your help again and hope this can help someone else in the future !

                          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