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. Creating a calendar using QTableWidget with QItemDelegate
QtWS25 Last Chance

Creating a calendar using QTableWidget with QItemDelegate

Scheduled Pinned Locked Moved General and Desktop
qtablewidgetqitemdelegate
20 Posts 2 Posters 7.1k Views
  • 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.
  • B Offline
    B Offline
    Binary91
    wrote on last edited by
    #1

    Hi,

    I coded a little calendar using a QTableWidget. When the user edits a QListWidget (every row is an hour of the corresponding day), the text is automatically stored into the corresponding QTableWidgetItem.

    Well, after storing three or more things into the QListWidget, the data in the QTableWidget cell is going to look really chaotic. Also, I'd like to have some more stuff stored into the table cells, like little pictograms on the right top corner of the cell.

    My aim is to filter the data in the to-do list (QListWidget) and only list the first three points in the corresponding table cell. These three strings should be listed vertically as a block and the block itsself should be aligned horizontally left and vertically centered.
    On the right top corner of the cell, I'd like to place one ore more pictograms (horizontally listed).

    For these purposes I need something more than just a simple QTableWidgetItem. After googleling for a while, I think that QItemDelegate/QStyledItemDelegate is the thing I need for it.

    My problem now is, I don't have a clue of it. I didn't get it. I think I have to subclass it and reimplement some functions like QItemDelegate::paint(...) and stuff.

    But I don't know how to use them and when they are called and so on... Also I don't know how to realize my purposes with the delegate class.. How can I render the cell like I want it, positioning strings and pictograms in different aligned spaces into the same cell...

    Maybe someone could give me a hint how to do this...

    Thank you in anticipation!
    Binary

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by SGaist
      #2

      Hi,

      The delegate class is called each time a cell must be painted, or an editor is requested.

      You can find several links to good examples in the details of QStyledItemDelegate documentation

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • B Offline
        B Offline
        Binary91
        wrote on last edited by Binary91
        #3

        Hi SGaist,

        thank you for your post. Unfortunatelly, your link did not help me. I already read the documentation, but I can't find any examples. Qt docu tells me that QItemDelegate provides diverse roles for displaying stuff like a role for bitmaps, a role for strings and so on and Qt docu mentions the important functions how to display it.

        My problem is, that I don't know how to position the text/bitmaps together in a cell. How would I have to use the paint(..) function to create a QTableWidget cell with QStrings and pictograms in the following constellation ("-" means empty space):

        ++++++++++++++++++++++++
        +----------------------pictogram--+
        +--string_1-------------------------+
        +--string_2-------------------------+
        +---------------------------------------+
        ++++++++++++++++++++++++

        I have seen layouts like the one above in many calendars/tables of applications. It is a common layout for table cells and I hope, there will be someone who knows how to realize this. I don't need a complete compilable solution, but I have reached a point where I don't know how to go on, I don't get the information I need while reading Qt's docu or google links where the displaying of QSpinBoxes is explained...

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          You will be working with drawImage and drawText. So you'll be painting on a rectangle. Calculate the appropriate position and you're good to go.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • B Offline
            B Offline
            Binary91
            wrote on last edited by
            #5

            Sounds like something to work with. So the fantastic class I was always looking for is the QPainter! Reading its documentation shows me alle the functionality I was looking for in the QItemDelegate class...

            So, do I have to subclass QItemDelegate/QStyledItemDelegate or can I simply create an instance of QPainter and pass it to my table cells?
            If I do have to subclass it, where should I create the QPainter instance? In the paint() function? I still don't understand how Qt manages the call of paint(...) while creating/updating my QTableWidget... Does any QTableWidget cell has its own QPainter that is passed to the paint(..) function? Does that mean that the paint function is called 50 times if I have a table with 50 cells?
            Sorry, but documentation lacks a bit with the description of delegate handling (through the eyes of an unexperienced user). :-)

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              You have to subclass QStyledItemDelegate. You receive the QPainter to use in the paint function (it's the first argument of the function)

              The delegate will be called for each cell since each cell can contain something different.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • B Offline
                B Offline
                Binary91
                wrote on last edited by Binary91
                #7

                Hi and sorry for the belated response.

                Well, I subclassed QStyledItemDelegate now, reimplemented the paint function and tried to display a string on the top left corner of each cell in column 2 of a table. To ensure that only column 2 uses the custom delegate, I set the delegate only for column 2.

                This is how my paint function looks like:
                [code]
                void testDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem &soviOption, const QModelIndex &miIndex) const
                {
                pPainter->drawText(QRect(0,0,50,20), "TestString");
                QStyledItemDelegate::paint(pPainter, soviOption, miIndex);
                return;
                }
                [/code]
                Well, the interesting thing now is, that the strings (5 strings because I have 5 cells in column 2) are all positioned on the top left corner of the top left cell (col 1, row 1). That is suspicious, because the coordinates should be relative for each cell...
                Also , when I manually change the window size, the table and its cells adjust to the window but the strings don't move! Hence, they are not stored into their corresponding cells but hover them as a z-stack... They don't respect cell borders...
                What's the matter with that behaviour??

                Instead, when I use the QRect from the option variable of the argument list of the paint function, I get the results I expected!
                [code]
                pPainter->drawText(soviOption.rect, "TestString");
                [/code]
                Where is the difference between these two methods and why does the first example position the data "over" the cells without respecting their borders and absolute positioning at the top left corner of the whole table??

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Because the same painter is used to paint the whole widget. The option parameter gives you all the information needed to paint one cell.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    Binary91
                    wrote on last edited by
                    #9

                    But option.rect also only returns a QRect, doesn't it? So, where is the difference between the following examples:
                    [code]
                    painter->drawText(option.rect, "TestString"); // assuming that option.rect returns a QRect(100,50,20,20)
                    [/code]

                    [code]
                    painter->drawText(QRect(100,50,20,20), "TestString");
                    [/code]
                    For the compiler, it should be tha same, isn't it?

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      The rect changes for each cell

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        Binary91
                        wrote on last edited by Binary91
                        #11

                        yeah I know, I catched the coordinates of option.rect for the 5 cells with qDebug:
                        x is alway 185, y = index.row * 51, width is always 91 and height is always 50.

                        Hence, the following two methods do exactly the same positioning (I tested it):
                        [code]
                        painter->drawText(option.rect, "TestString");
                        [/code]

                        [code]
                        painter->drawText(QRect(185,index.row()*51,91,50), "TestString");
                        [/code]

                        BUT the difference is, that the first example stores the strings INTO the cells (changing window size also lets the strings move with its corresponding cells). The second example doesn't. In the second example, the strings are layed over the table, they don't belong to a cell and fly over their borders when resizing the window... They are like ghosts!

                        Can you explain this behaviour?

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Again: option.rect changes for each cell. It will be adapted to changes of column size, row size etc.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          1
                          • B Offline
                            B Offline
                            Binary91
                            wrote on last edited by
                            #13

                            Oh yes, this makes sense... I forgot the fact that paint() is also called while resizing... ok everything is clear now. Thanks

                            1 Reply Last reply
                            0
                            • B Offline
                              B Offline
                              Binary91
                              wrote on last edited by Binary91
                              #14

                              Maybe one last Question:
                              Does it make any difference to the appeareance when using a custom item delegate in combination with QTableWidgetItem instead of using the custom delegate with plain cells? Does the custom delegate also effect to QTableWidgetItems or will they use their own display methods?

                              1 Reply Last reply
                              0
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #15

                                No, these are just items holding data, the delegate will act just the same

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                1 Reply Last reply
                                0
                                • B Offline
                                  B Offline
                                  Binary91
                                  wrote on last edited by Binary91
                                  #16

                                  Ah, I see. So a delegate is really just a layer that is not interested in data that is already stored into a table. So I think it will not be possible for me to place data via delegate that should be clickable like a link, right? The click would go "through" the delegate and would only hit the underlying QTableWidgetItem...

                                  1 Reply Last reply
                                  0
                                  • SGaistS Offline
                                    SGaistS Offline
                                    SGaist
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    eventFilter comes to mind to handle that

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    1 Reply Last reply
                                    0
                                    • B Offline
                                      B Offline
                                      Binary91
                                      wrote on last edited by
                                      #18

                                      alright, thank you for your live support! I think I can handle the rest by myself.

                                      Cheers,

                                      1 Reply Last reply
                                      0
                                      • B Offline
                                        B Offline
                                        Binary91
                                        wrote on last edited by
                                        #19

                                        Well, maybe I have one more question:
                                        In my code, I subclass QItemDelegate but I only reimplement the paint function. So the editor behaviour should be the same as in default delegate mode.

                                        What I'm asking myself now is, how the delegate (which, in my eyes, can be seen as a layer of data over the table) interacts with QTableWidgetItems. For a example, I inserted QTableWidgets in every table cell with a text "itemText". Also, I used the custom QItemDelegate and let the paint function paint a text "delegateText" over every cell.
                                        The result is (as expected), that the "delegateText" is displayed over the "itemText". So the delegate is like a layer that is not interested in what the cell does.

                                        BUT, what happens if I try to edit the QTableWidgetItem by double click? As expected, an editable cursor appears. But is this now the editor of the QTableWidgetItem or is it the editor of the QItemDelegate ?? And what would happen if I disable one of them?

                                        1 Reply Last reply
                                        0
                                        • SGaistS Offline
                                          SGaistS Offline
                                          SGaist
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #20

                                          The QTableWidgetItem is essentially a data container, it doesn't know about any editor.

                                          It's the delegate that uses a factory that will return the corresponding editor based on the item content type.

                                          Interested in AI ? www.idiap.ch
                                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/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