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. Widget in a QListView

Widget in a QListView

Scheduled Pinned Locked Moved Solved General and Desktop
qlistviewwidget
10 Posts 3 Posters 2.7k 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.
  • C Offline
    C Offline
    coaxmetal
    wrote on 14 Jan 2020, 18:25 last edited by
    #1

    Hi! So, I have this problem: I have a QListView with QStyledItemDelegate. What I want to do is paint a widget for each item and it should be able to receive events (for example, if that widget is a button, it would be possible to click it).

    So far, in the paint method of the delegate, I initialize the widget and do

    widget.render(painter, targetOffset=option.rect.topLeft())
    

    This paints the widget, but there's no way to interact with it. I thought, is there another way? Maybe I could somehow redirect the events to the widget? But how? Need help on this.

    PS I need to use QListView with a delegate for speed (as there's no limit on the size of the model) and flexibility.

    PS2 If there are ways to do this without delegate, I guess I might sacrifice some flexibility after all (QListWidget won't let me set a custom model, so that one won't work).

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 14 Jan 2020, 19:42 last edited by
      #2

      Hi and welcome to devnet,

      This stack overflow answer and the answer linked there is likely what you are looking for.

      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
      • C Offline
        C Offline
        coaxmetal
        wrote on 15 Jan 2020, 13:30 last edited by
        #3

        @SGaist Thank you! That link's gonna turn up useful very soon for me for some specific tweaking.

        But what about widgets whose structure I don't know in advance? Is there a simple way to make it interactive? Is it maybe possible to set the editor of the item to be a widget? Like make it a full-blown widget on mouse-over and restore the state when the mouse leaves the item area?

        1 Reply Last reply
        0
        • C Offline
          C Offline
          coaxmetal
          wrote on 15 Jan 2020, 16:22 last edited by
          #4

          @mrjj Also, found in this thread that

          You can also cheat and use render() if you have a lots of widgets in one cell. But that uses memory since each items then has an image to maintain.

          Why does that work that way? Why would each item (of the whole model?) have to maintain an image? Doesn't the delegate just repaint the widget every time based on the need and that's that?

          M 1 Reply Last reply 15 Jan 2020, 16:40
          0
          • C coaxmetal
            15 Jan 2020, 16:22

            @mrjj Also, found in this thread that

            You can also cheat and use render() if you have a lots of widgets in one cell. But that uses memory since each items then has an image to maintain.

            Why does that work that way? Why would each item (of the whole model?) have to maintain an image? Doesn't the delegate just repaint the widget every time based on the need and that's that?

            M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 15 Jan 2020, 16:40 last edited by
            #5

            @coaxmetal
            Hi
            The delegate only uses real widgets when in edit mode. (as in one row at a time)
            The rest of the time, the Delegate must paint a look-alike of the Widget
            using QStyle/QPainter calls. So the cheat is let the widget render to an image and show that instead of painting it with paint calls.

            If it uses real QWidgets all the time, it would have the same bad performance as
            setCellWidget (that places a real Widget on top of the cell for all rows )

            So a Delegate is to avoid using setCellWidget as that is very heavy on large lists and/or small IOT boards.

            1 Reply Last reply
            1
            • C Offline
              C Offline
              coaxmetal
              wrote on 15 Jan 2020, 18:02 last edited by
              #6

              @mrjj I see, thanks for the clarification, I just misunderstood you the first time around!

              By the way, I am wondering, say, if all I wanted to render is a bunch of labels in each item, is it going to be much faster if I draw them myself using QPen, fillRect etc versus putting them as QLabels in a widget with a custom layout? Widgets+QLabels would be more generic and easier, but speed is of major importance. I guess, one has to check, but maybe someone has tried that before...

              M 1 Reply Last reply 15 Jan 2020, 18:06
              0
              • C coaxmetal
                15 Jan 2020, 18:02

                @mrjj I see, thanks for the clarification, I just misunderstood you the first time around!

                By the way, I am wondering, say, if all I wanted to render is a bunch of labels in each item, is it going to be much faster if I draw them myself using QPen, fillRect etc versus putting them as QLabels in a widget with a custom layout? Widgets+QLabels would be more generic and easier, but speed is of major importance. I guess, one has to check, but maybe someone has tried that before...

                M Offline
                M Offline
                mrjj
                Lifetime Qt Champion
                wrote on 15 Jan 2020, 18:06 last edited by mrjj
                #7

                @coaxmetal
                Hi
                Why would you use Labels in the cells ?
                The normal CellDrawing can draw the text already ?
                For RichText Support or what is the use case ? (if i may ask)
                (ahh for multiple texts (non editable) in same cell ?)

                From my tests, yes QLabel is slower (due to more checks/options/code )
                than a few QPainter Calls. But it all depends.
                You can see its paint here
                https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html
                line 999

                1 Reply Last reply
                1
                • C Offline
                  C Offline
                  coaxmetal
                  wrote on 15 Jan 2020, 18:22 last edited by
                  #8

                  @mrjj

                  (ahh for multiple texts (non editable) in same cell ?)

                  yes, this one : ) I have a flow of generic data, meaning QTable wouldn't work, so doing it this way.

                  You can see its paint here
                  https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html
                  line 999

                  Yeah, I see, that's quite a function there, better paint it myself then.

                  Thank you!

                  PS Looks like the best way to display a widget without setItemWidget is to employ the editor in the delegate to display actual interactive widget on editing. For anyone finding this and doing the same, look at StarDelegate example, at the very minimum you will have to redefine flags() function in your view to indicate that an index is editable and also the createEditor to return the widget which will be drawn over the item (StarDelegate has this). So, marking as solved.

                  M 1 Reply Last reply 15 Jan 2020, 18:35
                  0
                  • C coaxmetal
                    15 Jan 2020, 18:22

                    @mrjj

                    (ahh for multiple texts (non editable) in same cell ?)

                    yes, this one : ) I have a flow of generic data, meaning QTable wouldn't work, so doing it this way.

                    You can see its paint here
                    https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html
                    line 999

                    Yeah, I see, that's quite a function there, better paint it myself then.

                    Thank you!

                    PS Looks like the best way to display a widget without setItemWidget is to employ the editor in the delegate to display actual interactive widget on editing. For anyone finding this and doing the same, look at StarDelegate example, at the very minimum you will have to redefine flags() function in your view to indicate that an index is editable and also the createEditor to return the widget which will be drawn over the item (StarDelegate has this). So, marking as solved.

                    M Offline
                    M Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on 15 Jan 2020, 18:35 last edited by
                    #9

                    @coaxmetal
                    Hi
                    Ok You might have other requirements making a Delegate the way to go.
                    Yes, the Starelegate is the usual sample we refer to. And yes
                    the design of the Delegate API is to use CreateEditor to use a real widget for editing and then draw the rest of the time. (fake it , one could say )

                    Just a a note. It can display multiple lines of text ready. ( if it has newlines)

                    int main(int argc, char **argv)
                    {
                        QApplication app(argc, argv);
                        QTreeView view;
                        QStandardItemModel *model = new QStandardItemModel;
                        // Prepend 4 rows into the model
                        model->insertRows(0, 4);
                        // Prepend 4 columns into the model
                        model->insertColumns(0, 4);
                    
                        for (int row = 0; row < 4; row++) {
                            for (int col = 0; col < 4; col++) {
                                // Return a model index for the given row and column.
                                QModelIndex index = model->index(row, col);
                                // Set the index's data to the specified value
                                model->setData(index, QVariant("hello\nnextline"));
                            }
                        }
                    
                    
                        view.setModel(model);
                        view.show();
                        return app.exec();
                    }
                    
                    

                    alt text

                    C 1 Reply Last reply 15 Jan 2020, 19:16
                    2
                    • M mrjj
                      15 Jan 2020, 18:35

                      @coaxmetal
                      Hi
                      Ok You might have other requirements making a Delegate the way to go.
                      Yes, the Starelegate is the usual sample we refer to. And yes
                      the design of the Delegate API is to use CreateEditor to use a real widget for editing and then draw the rest of the time. (fake it , one could say )

                      Just a a note. It can display multiple lines of text ready. ( if it has newlines)

                      int main(int argc, char **argv)
                      {
                          QApplication app(argc, argv);
                          QTreeView view;
                          QStandardItemModel *model = new QStandardItemModel;
                          // Prepend 4 rows into the model
                          model->insertRows(0, 4);
                          // Prepend 4 columns into the model
                          model->insertColumns(0, 4);
                      
                          for (int row = 0; row < 4; row++) {
                              for (int col = 0; col < 4; col++) {
                                  // Return a model index for the given row and column.
                                  QModelIndex index = model->index(row, col);
                                  // Set the index's data to the specified value
                                  model->setData(index, QVariant("hello\nnextline"));
                              }
                          }
                      
                      
                          view.setModel(model);
                          view.show();
                          return app.exec();
                      }
                      
                      

                      alt text

                      C Offline
                      C Offline
                      coaxmetal
                      wrote on 15 Jan 2020, 19:16 last edited by
                      #10

                      @mrjj Thanks for the newline example, but yeah, I am planning for some other requirements (coloring, custom arrangements, no-columns etc.)

                      1 Reply Last reply
                      1

                      10/10

                      15 Jan 2020, 19:16

                      • Login

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