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. createEditor of a custom widget is not being called. How to debug?

createEditor of a custom widget is not being called. How to debug?

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 4 Posters 591 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.
  • A Offline
    A Offline
    andi456
    wrote on 21 Jun 2024, 15:32 last edited by
    #1

    Hi,

    after tinkering with drawings of a custom delegate in the style of the Star Delegate Example, that worked on a rather simple QTableView in a test project, applying it to a more complex project fails.

    The paint method of the delegate is being called, but as the title of this post suggests the create editor method does not. Except for the pictures drawn the code is pretty much the same as the one from the documentation example. What could be the reason for this? Or rather, what triggers the createEditor method of a delegate?

    Kind regards,

    Andreas

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 21 Jun 2024, 18:55 last edited by
      #2

      Hi,

      Might be a silly question but: are you sure the items on this complex application are editable ?
      Does the model implement the flags method ? If so, check what exactly is returned.

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

      A 1 Reply Last reply 21 Jun 2024, 20:26
      1
      • S SGaist
        21 Jun 2024, 18:55

        Hi,

        Might be a silly question but: are you sure the items on this complex application are editable ?
        Does the model implement the flags method ? If so, check what exactly is returned.

        A Offline
        A Offline
        andi456
        wrote on 21 Jun 2024, 20:26 last edited by
        #3

        @SGaist Yes, you are right, there is something wrong in the flags method of the corresponding model. I'll look deeper into it tomorrow, what exactly goes awry. So far the logic I applied there seemed to work quite well. Thanks.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andi456
          wrote on 22 Jun 2024, 10:11 last edited by
          #4

          There's something strange going on. As the data of the model is stored in a json parameter consisting of an array of json-objects, i.e., a key-value structure with the keys being used as column headers. That's why I needed some way to map the editable columns to the column index integers which are stored in a global std::vector<int> declared in the model's header file that is being populated in the constructor of the model. So in the model's constructor it looks like this

          editablesVector = this->get_editables();
          

          This vector is then used in the flags method like this:

          Qt::ItemFlags f = QAbstractTableModel::flags(index);
          if (!index.isValid()) {
                  return Qt::NoItemFlags;
              } else {
                int col = index.column();
               for (unsigned int i=0; i<editablesVector.size(); ++i) {
                     if (editablesVector[i]==col) {
                         f = Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
                     }
             }
          return f;
          

          It turns out that the editablesVector in the flags method is empty which is really surprising, because I use this approach in other models of the same application, and it works flawlessly. I'm sure there are more elegant ways to accomplish this, but it seemed more efficient than finding out the editable colums in flags method itself, which is called quite often.

          J 1 Reply Last reply 22 Jun 2024, 13:41
          0
          • A Offline
            A Offline
            andi456
            wrote on 22 Jun 2024, 13:10 last edited by
            #5

            Hm, I think I'll replace the std::vector<int> by a std::map<std::string, int> to accomplish the same, which seems to be more stable. Anyway, it's strange that a globally declared vector loses its contents in one particular model and not in others. Are there any recommendations what kind of containers should be used?

            1 Reply Last reply
            0
            • A andi456
              22 Jun 2024, 10:11

              There's something strange going on. As the data of the model is stored in a json parameter consisting of an array of json-objects, i.e., a key-value structure with the keys being used as column headers. That's why I needed some way to map the editable columns to the column index integers which are stored in a global std::vector<int> declared in the model's header file that is being populated in the constructor of the model. So in the model's constructor it looks like this

              editablesVector = this->get_editables();
              

              This vector is then used in the flags method like this:

              Qt::ItemFlags f = QAbstractTableModel::flags(index);
              if (!index.isValid()) {
                      return Qt::NoItemFlags;
                  } else {
                    int col = index.column();
                   for (unsigned int i=0; i<editablesVector.size(); ++i) {
                         if (editablesVector[i]==col) {
                             f = Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
                         }
                 }
              return f;
              

              It turns out that the editablesVector in the flags method is empty which is really surprising, because I use this approach in other models of the same application, and it works flawlessly. I'm sure there are more elegant ways to accomplish this, but it seemed more efficient than finding out the editable colums in flags method itself, which is called quite often.

              J Offline
              J Offline
              JonB
              wrote on 22 Jun 2024, 13:41 last edited by JonB
              #6

              @andi456 said in createEditor of a custom widget is not being called. How to debug?:

              It turns out that the editablesVector in the flags method is empty which is really surprising

              Anyway, it's strange that a globally declared vector loses its contents in one particular model and not in others

              Vectors don't "loses its contents in one particular model". Your statements indicate something is wrong in your code. You should examine it closely and in comparison to where it does work.

              Are there any recommendations what kind of containers should be used?

              You can use whatever container type you wish/is best suited.

              One "recommendation" is don't use global variables at all. At minimum put them in a class, accessible both as native model for your purposes and via model indexing. Your "vector loses its contents in one particular model" might be caused by you re-declaring a scoped variable with the same name/type as your global ("shadowing", you have to be careful in C++), then the global would be hidden and the model would be empty? Seen it here many times. One more reason to avoid globals. Otherwise of course you should check for global being changed anywhere after being set.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andi456
                wrote on 22 Jun 2024, 14:06 last edited by
                #7

                To be more precise, the mentioned std::vector<int>, that's somehow empty, is a private field of the corresponding model. The aforementioned star delegate example also makes intensive use of such private fields in its class definitions. Should I consider this bad practice, too?

                J 1 Reply Last reply 22 Jun 2024, 14:15
                0
                • A andi456
                  22 Jun 2024, 14:06

                  To be more precise, the mentioned std::vector<int>, that's somehow empty, is a private field of the corresponding model. The aforementioned star delegate example also makes intensive use of such private fields in its class definitions. Should I consider this bad practice, too?

                  J Offline
                  J Offline
                  JonB
                  wrote on 22 Jun 2024, 14:15 last edited by JonB
                  #8

                  @andi456 said in createEditor of a custom widget is not being called. How to debug?:

                  the mentioned std::vector<int>, that's somehow empty, is a private field of the corresponding model.

                  So isn't that exactly the shadowing I suggested? If you declare a variable in an inner scope (e.g. inside a class when you have a global, or inside a function where you have a global or class member) of the same name as an outer scope you access the inner one, unless you do something to access the outer one (e.g. this->... or ::...). This is all basic C++.

                  If star delegate example is using private variables I very much doubt they are using globals or have got their code wrong. If yours is wrong (as it sounds) then you must fix it. Why would you declare a local/member variable with the same name if you have some global you want to access instead? Better yet don't use a global in the first place.

                  A 1 Reply Last reply 22 Jun 2024, 14:30
                  1
                  • J JonB
                    22 Jun 2024, 14:15

                    @andi456 said in createEditor of a custom widget is not being called. How to debug?:

                    the mentioned std::vector<int>, that's somehow empty, is a private field of the corresponding model.

                    So isn't that exactly the shadowing I suggested? If you declare a variable in an inner scope (e.g. inside a class when you have a global, or inside a function where you have a global or class member) of the same name as an outer scope you access the inner one, unless you do something to access the outer one (e.g. this->... or ::...). This is all basic C++.

                    If star delegate example is using private variables I very much doubt they are using globals or have got their code wrong. If yours is wrong (as it sounds) then you must fix it. Why would you declare a local/member variable with the same name if you have some global you want to access instead? Better yet don't use a global in the first place.

                    A Offline
                    A Offline
                    andi456
                    wrote on 22 Jun 2024, 14:30 last edited by
                    #9

                    @JonB Maybe, it's a matter of terminology, I'm not sure. If you have a look at starrating.h and starrating.cpp, you'll notice two private fields

                        QPolygonF starPolygon;
                        QPolygonF diamondPolygon;
                    

                    both are being populated in the constructor:

                    StarRating::StarRating(int starCount, int maxStarCount)
                        : myStarCount(starCount),
                          myMaxStarCount(maxStarCount)
                    {
                        starPolygon << QPointF(1.0, 0.5);
                        for (int i = 1; i < 5; ++i)
                            starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14),
                                                   0.5 + 0.5 * std::sin(0.8 * i * 3.14));
                    
                        diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4)
                                       << QPointF(0.6, 0.5) << QPointF(0.5, 0.6)
                                       << QPointF(0.4, 0.5);
                    }
                    

                    Is this bad practice? I have done more or less the same in my model constructor...

                    J P 2 Replies Last reply 22 Jun 2024, 14:37
                    0
                    • A andi456
                      22 Jun 2024, 14:30

                      @JonB Maybe, it's a matter of terminology, I'm not sure. If you have a look at starrating.h and starrating.cpp, you'll notice two private fields

                          QPolygonF starPolygon;
                          QPolygonF diamondPolygon;
                      

                      both are being populated in the constructor:

                      StarRating::StarRating(int starCount, int maxStarCount)
                          : myStarCount(starCount),
                            myMaxStarCount(maxStarCount)
                      {
                          starPolygon << QPointF(1.0, 0.5);
                          for (int i = 1; i < 5; ++i)
                              starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14),
                                                     0.5 + 0.5 * std::sin(0.8 * i * 3.14));
                      
                          diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4)
                                         << QPointF(0.6, 0.5) << QPointF(0.5, 0.6)
                                         << QPointF(0.4, 0.5);
                      }
                      

                      Is this bad practice? I have done more or less the same in my model constructor...

                      J Offline
                      J Offline
                      JonB
                      wrote on 22 Jun 2024, 14:37 last edited by JonB
                      #10

                      @andi456
                      I really don't know what you are thinking of. I don't see where terminology comes into anything. The code shown is just fine. Populating private members in constructor is more than usual. And nothing we are discussing has any relevance to whether you have a class to do with a model or anything else.

                      You may assume as a rule of thumb that the Qt examples are reasonable C++ coding.

                      Your problem is (a) having a global variable in the first place and (b) having a member variable with the same name as the global.

                      1 Reply Last reply
                      1
                      • A andi456
                        22 Jun 2024, 14:30

                        @JonB Maybe, it's a matter of terminology, I'm not sure. If you have a look at starrating.h and starrating.cpp, you'll notice two private fields

                            QPolygonF starPolygon;
                            QPolygonF diamondPolygon;
                        

                        both are being populated in the constructor:

                        StarRating::StarRating(int starCount, int maxStarCount)
                            : myStarCount(starCount),
                              myMaxStarCount(maxStarCount)
                        {
                            starPolygon << QPointF(1.0, 0.5);
                            for (int i = 1; i < 5; ++i)
                                starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14),
                                                       0.5 + 0.5 * std::sin(0.8 * i * 3.14));
                        
                            diamondPolygon << QPointF(0.4, 0.5) << QPointF(0.5, 0.4)
                                           << QPointF(0.6, 0.5) << QPointF(0.5, 0.6)
                                           << QPointF(0.4, 0.5);
                        }
                        

                        Is this bad practice? I have done more or less the same in my model constructor...

                        P Offline
                        P Offline
                        Pl45m4
                        wrote on 22 Jun 2024, 14:44 last edited by Pl45m4
                        #11

                        @andi456 said in createEditor of a custom widget is not being called. How to debug?:

                        Is this bad practice? I have done more or less the same in my model constructor...

                        In your example this

                        starPolygon << QPointF(1.0, 0.5);
                        

                        accesses this

                           QPolygonF starPolygon;
                        

                        which is not a global variable.

                        @andi456 said in createEditor of a custom widget is not being called. How to debug?:

                        Anyway, it's strange that a globally declared vector loses its contents in one particular model and not in others

                        Here you wrote you use a globally declared vector... which is not the same as used in the example.
                        Or are you refering to the above code as "globally declared"... then it's wrong terminology because globally declared is something like:

                        // global counter
                        int counter = 0;
                        
                        class A
                        {
                           A();
                        
                        private:
                           // private counter as a class member
                           int counter;
                        };
                        

                        writing counter = 42; in you a.cpp would shadow the private member counter cause it's ambiguous and it's not clear if you want to set the global counter to 42 or the private member of class A.


                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

                        1 Reply Last reply
                        1
                        • A Offline
                          A Offline
                          andi456
                          wrote on 22 Jun 2024, 16:00 last edited by
                          #12

                          Mea culpa, mea maxima culpa, I used the wrong notion of "global variable", sorry for that. Private field would have been better, I suppose.

                          Well, I don't know what exactly interferes with the std::vector<int> field, which is not visible outside the model, but as the star delegate example code is okay, I will stick with std::map solution, which is analogous....

                          P 1 Reply Last reply 22 Jun 2024, 16:11
                          0
                          • A andi456
                            22 Jun 2024, 16:00

                            Mea culpa, mea maxima culpa, I used the wrong notion of "global variable", sorry for that. Private field would have been better, I suppose.

                            Well, I don't know what exactly interferes with the std::vector<int> field, which is not visible outside the model, but as the star delegate example code is okay, I will stick with std::map solution, which is analogous....

                            P Offline
                            P Offline
                            Pl45m4
                            wrote on 22 Jun 2024, 16:11 last edited by
                            #13

                            @andi456 said in createEditor of a custom widget is not being called. How to debug?:

                            Well, I don't know what exactly interferes with the std::vector<int> field

                            How are you passing the the vector around?


                            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                            ~E. W. Dijkstra

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              andi456
                              wrote on 22 Jun 2024, 17:23 last edited by
                              #14

                              No, I just populate it in the model constructor in a somewhat cumbersome manner. After that it is only being used in the flags method of the model. As I said, it is a little strange, because the approach works in the other models of the application...

                              J 1 Reply Last reply 22 Jun 2024, 18:06
                              0
                              • A andi456
                                22 Jun 2024, 17:23

                                No, I just populate it in the model constructor in a somewhat cumbersome manner. After that it is only being used in the flags method of the model. As I said, it is a little strange, because the approach works in the other models of the application...

                                J Offline
                                J Offline
                                JonB
                                wrote on 22 Jun 2024, 18:06 last edited by
                                #15

                                @andi456 So do you want to show the code that does not work so someone can comment/explain?

                                1 Reply Last reply
                                1
                                • A Offline
                                  A Offline
                                  andi456
                                  wrote on 22 Jun 2024, 19:06 last edited by andi456
                                  #16

                                  Actually, I've begun to put the std::map approach to use it in the other models too, because it is much less awkward. When I'm done with that, I will show the code especially, if I encounter any errors. Thanks for your help, anyway.

                                  1 Reply Last reply
                                  0

                                  8/16

                                  22 Jun 2024, 14:15

                                  • Login

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