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. QSqlTableModel
Forum Updated to NodeBB v4.3 + New Features

QSqlTableModel

Scheduled Pinned Locked Moved Unsolved General and Desktop
36 Posts 6 Posters 4.9k Views 1 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.
  • JonBJ JonB

    @Xilit
    Yes, you can do something like this.

    As I said, personally I do not do this in a QStyledItemDelegate at all. I suggested you do it in data() override for Qt::DisplayRole. Personally I think this is simpler to write, but perhaps that's opinion.

    Rationale: QStyledItemDelegate is only usable in a QTableView or similar. However, to me the choice to display a numeric in a particular format like you have is not restricted to/has nothing to do with whether you happen to be displaying it as an item in table. If, say, you want to display it in its own widget, or export it to a text file, you would (presumably) still want to display/output it in your chosen format. So I see it best as an attribute of the data, putting the logic in data(Qt::DisplayRole) makes that available/shareable everywhere.

    X Offline
    X Offline
    Xilit
    wrote on last edited by
    #17

    BTW is there are recommendation / tutorial how to reimplement QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const? To know how to reimplement method I need to know how this method works but I don't. Were I can find realization of it? There are no information about it in docs.

    JonBJ 1 Reply Last reply
    1
    • X Xilit

      BTW is there are recommendation / tutorial how to reimplement QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const? To know how to reimplement method I need to know how this method works but I don't. Were I can find realization of it? There are no information about it in docs.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #18

      @Xilit
      No mention about it in the docs?? Oh, I think you mean you have found the reference page (https://doc.qt.io/qt-5/qabstractitemmodel.html#data), but not examples? One is https://doc.qt.io/qt-5/model-view-programming.html#a-read-only-example-model, another is https://doc.qt.io/qt-5/model-view-programming.html#read-only-access. Read around those two areas. There are perhaps better links, I don't know. Understanding how data() & setData() methods work and can be overridden is important for Qt models.

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

        Did you follow the Model View Programming Guide ?
        There are several examples linked with some of them implementing custom models and views.

        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
        • JonBJ JonB

          @Xilit
          Yes, you can do something like this.

          As I said, personally I do not do this in a QStyledItemDelegate at all. I suggested you do it in data() override for Qt::DisplayRole. Personally I think this is simpler to write, but perhaps that's opinion.

          Rationale: QStyledItemDelegate is only usable in a QTableView or similar. However, to me the choice to display a numeric in a particular format like you have is not restricted to/has nothing to do with whether you happen to be displaying it as an item in table. If, say, you want to display it in its own widget, or export it to a text file, you would (presumably) still want to display/output it in your chosen format. So I see it best as an attribute of the data, putting the logic in data(Qt::DisplayRole) makes that available/shareable everywhere.

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #20

          @JonB said in QSqlTableModel:

          I suggested you do it in data() override for Qt::DisplayRole. Personally I think this is simpler to write, but perhaps that's opinion.

          Strongly disagree. The model is data, it shouldn't care how the data is represented. Also, the model is locale unaware

          Just subclass QStyledItemDelegate and override displayText:

          class NoScNotationDelegate : public QStyledItemDelegate{
          Q_OBJECT
          Q_DISABLE_COPY(NoScNotationDelegate)
          public:
          using QStyledItemDelegate::QStyledItemDelegate;
          QString displayText(const QVariant &value, const QLocale &locale) const override{
          switch(value.type()){
          case QMetaType::Double:
          return locale.toString(value.toDouble(),'f');
          case QMetaType::Float:
          return locale.toString(value.toFloat(),'f');
          default:
          return QStyledItemDelegate::displayText(value,locale);
          }
          }
          };
          

          Then you can just use it with tableView->setItemDelegate(new NoScNotationDelegate(tableView)); (you can also use setItemDelegateForColumn to apply it ta a single column)

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          3
          • JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #21

            @JonB said in QSqlTableModel:
            @Xilit
            Prefacing my remarks to @VRonin below: Then in view of his post above, I think you should follow QStyledItemDelegate route, as he is much more of a Qt expert than I am.

            @VRonin
            I'll keep it brief here, otherwise perhaps we should take this issue to its own dedicated thread. I respect your expertise, but it does not chime right for me. Just a couple of reasons:

            • Somewhere in the existing Qt code for data(DisplayRole) there must be the equivalent of QString::arg(char format = 'g') to give the results it does. You are saying that is OK, but changing to QString::arg(char format = 'f') is not. Makes no sense to me. If the model must not care how the data is represented, it should not have a DisplayRole.

            • Your code is all in a QStyledItemDelegate for a QTableView or similar. I do not want special code for displaying a number in a view, I want it just as much for displaying it in, say, a label, or hundreds of other places. So the code has to be refactored to be available from all other places you might want your string representation of a numeric data item, and one will never be able to use plain, default data() method in practice (given something like the OP's requirement for numeric format).

            X VRoninV 2 Replies Last reply
            1
            • JonBJ JonB

              @JonB said in QSqlTableModel:
              @Xilit
              Prefacing my remarks to @VRonin below: Then in view of his post above, I think you should follow QStyledItemDelegate route, as he is much more of a Qt expert than I am.

              @VRonin
              I'll keep it brief here, otherwise perhaps we should take this issue to its own dedicated thread. I respect your expertise, but it does not chime right for me. Just a couple of reasons:

              • Somewhere in the existing Qt code for data(DisplayRole) there must be the equivalent of QString::arg(char format = 'g') to give the results it does. You are saying that is OK, but changing to QString::arg(char format = 'f') is not. Makes no sense to me. If the model must not care how the data is represented, it should not have a DisplayRole.

              • Your code is all in a QStyledItemDelegate for a QTableView or similar. I do not want special code for displaying a number in a view, I want it just as much for displaying it in, say, a label, or hundreds of other places. So the code has to be refactored to be available from all other places you might want your string representation of a numeric data item, and one will never be able to use plain, default data() method in practice (given something like the OP's requirement for numeric format).

              X Offline
              X Offline
              Xilit
              wrote on last edited by
              #22

              @JonB
              @SGaist
              Thank you guys for links! I'm going to dive in to deeply understand how model works.

              @VRonin
              Thank you that you find time to help me out with my programm and wrote example code! Written code is really very valueble for me because sometimes it's very hard to understand what senior experts talking about without code example.)

              Thank you all guys that I can always count on your help!

              1 Reply Last reply
              0
              • JonBJ JonB

                @JonB said in QSqlTableModel:
                @Xilit
                Prefacing my remarks to @VRonin below: Then in view of his post above, I think you should follow QStyledItemDelegate route, as he is much more of a Qt expert than I am.

                @VRonin
                I'll keep it brief here, otherwise perhaps we should take this issue to its own dedicated thread. I respect your expertise, but it does not chime right for me. Just a couple of reasons:

                • Somewhere in the existing Qt code for data(DisplayRole) there must be the equivalent of QString::arg(char format = 'g') to give the results it does. You are saying that is OK, but changing to QString::arg(char format = 'f') is not. Makes no sense to me. If the model must not care how the data is represented, it should not have a DisplayRole.

                • Your code is all in a QStyledItemDelegate for a QTableView or similar. I do not want special code for displaying a number in a view, I want it just as much for displaying it in, say, a label, or hundreds of other places. So the code has to be refactored to be available from all other places you might want your string representation of a numeric data item, and one will never be able to use plain, default data() method in practice (given something like the OP's requirement for numeric format).

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #23

                @JonB said in QSqlTableModel:

                Somewhere in the existing Qt code for data(DisplayRole) there must be the equivalent of QString::arg(char format = 'g')

                No, data is converted to string to represent it inside QStyledItemDelegate::displayText, nowhere else (and it uses QLocale::toString instead of the C-locale-only QString::number). The model holds the data in the native format and never cares about how it is represented to the user

                Your code is all in a QStyledItemDelegate for a QTableView or similar

                Yes, my code is for the model-view-delegate architecture

                I do not want special code for displaying a number in a view, I want it just as much for displaying it in, say, a label, or hundreds of other places

                Then it's the final user that has to take care of knowing how to convert a double to string. Exactly because of the reason you mentioned. the model is agnostic to what you use it in/for

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                JonBJ 1 Reply Last reply
                3
                • VRoninV VRonin

                  @JonB said in QSqlTableModel:

                  Somewhere in the existing Qt code for data(DisplayRole) there must be the equivalent of QString::arg(char format = 'g')

                  No, data is converted to string to represent it inside QStyledItemDelegate::displayText, nowhere else (and it uses QLocale::toString instead of the C-locale-only QString::number). The model holds the data in the native format and never cares about how it is represented to the user

                  Your code is all in a QStyledItemDelegate for a QTableView or similar

                  Yes, my code is for the model-view-delegate architecture

                  I do not want special code for displaying a number in a view, I want it just as much for displaying it in, say, a label, or hundreds of other places

                  Then it's the final user that has to take care of knowing how to convert a double to string. Exactly because of the reason you mentioned. the model is agnostic to what you use it in/for

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #24

                  @VRonin said in QSqlTableModel:

                  No, data is converted to string to represent it inside QStyledItemDelegate::displayText, nowhere else. The model holds the data in the native format and never cares about how it is represented to the user

                  If you are saying that QStyledItemDelegate::displayText does its own conversion off data(EditRole) then I don't get it, because I change data(DisplayRole) for numbers and they come out reflecting that in table views? Unless you are saying I am going mad.

                  If the model never cares about representation to the user, what is the purpose of DisplayRole? (Or, for that matter, FontRole etc. Indeed, why does the model's data() even offer or get called for such roles?)

                  1 Reply Last reply
                  1
                  • VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #25

                    For all native Qt Models EditRole and DisplayRole are one and the same. They never get separated. They are distinct only if you implement a custom model. QStyledItemDelegate::displayText does its own conversion off data(DisplayRole) it never cares about EditRole (unless you have some custom implementation that passes editrole to it)

                    what is the purpose of DisplayRole?

                    The most iconic example of the purpose is thinking abount excel/libre office calc: edit role is the formula, display role is the result of that formula. You can never change the result directly when you modify a cell. You always change the formula (edit role) then the program calculates the result and shows it in dispaly role. The result of =2+2 (string in editrole) is stored as int/double in the displayrole. The delegate then takes care of taking that number and converting it to something that can be printed on the screen

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    JonBJ 1 Reply Last reply
                    5
                    • VRoninV VRonin

                      For all native Qt Models EditRole and DisplayRole are one and the same. They never get separated. They are distinct only if you implement a custom model. QStyledItemDelegate::displayText does its own conversion off data(DisplayRole) it never cares about EditRole (unless you have some custom implementation that passes editrole to it)

                      what is the purpose of DisplayRole?

                      The most iconic example of the purpose is thinking abount excel/libre office calc: edit role is the formula, display role is the result of that formula. You can never change the result directly when you modify a cell. You always change the formula (edit role) then the program calculates the result and shows it in dispaly role. The result of =2+2 (string in editrole) is stored as int/double in the displayrole. The delegate then takes care of taking that number and converting it to something that can be printed on the screen

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #26

                      @VRonin said in QSqlTableModel:

                      QStyledItemDelegate::displayText does its own conversion off data(DisplayRole) it never cares about EditRole

                      That is very interesting. So when (for right or for wrong) I made my data(DisplayRole) of a floating produce the format I wanted (f format, 2 decimal places) as a string, displayText saw a string instead of a number and passed it through without its own formatting, that's why it came out as it did.

                      I know about the spreadsheet case. It is "unusual", compared to 99% of cases. I thought DisplayRole was supposed to return the desired string for the default way you wanted the data output, hence why I did it that way for the floating point numbers. I think it was the very first area I did with Qt/PyQt, and I didn't know what you are saying now.

                      Although I know this conversation has been long, I hope @Xilit, the OP, won't mind as it's actually useful for him to see this stuff.

                      So my last question to @VRonin is: why are there all the other "presentational" roles (FontRole, TextAlignmentRole, ForegroundRole etc.)? If you are so keen that "The model [...] never cares about how it is represented to the user", why do you let the model provide/handle those? Even worse, data() returns types like QFont and QBrush for these (not even just a "symbolic" indicator), which is all to do with the presentation to the user.

                      X 1 Reply Last reply
                      1
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #27

                        Those roles are still pure data. It's the delegate responsibility to use them. The model suggest the delegate how to align stuff but it's still the delegate responsibility to do it and it can ignore them altogether.

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        3
                        • JonBJ JonB

                          @VRonin said in QSqlTableModel:

                          QStyledItemDelegate::displayText does its own conversion off data(DisplayRole) it never cares about EditRole

                          That is very interesting. So when (for right or for wrong) I made my data(DisplayRole) of a floating produce the format I wanted (f format, 2 decimal places) as a string, displayText saw a string instead of a number and passed it through without its own formatting, that's why it came out as it did.

                          I know about the spreadsheet case. It is "unusual", compared to 99% of cases. I thought DisplayRole was supposed to return the desired string for the default way you wanted the data output, hence why I did it that way for the floating point numbers. I think it was the very first area I did with Qt/PyQt, and I didn't know what you are saying now.

                          Although I know this conversation has been long, I hope @Xilit, the OP, won't mind as it's actually useful for him to see this stuff.

                          So my last question to @VRonin is: why are there all the other "presentational" roles (FontRole, TextAlignmentRole, ForegroundRole etc.)? If you are so keen that "The model [...] never cares about how it is represented to the user", why do you let the model provide/handle those? Even worse, data() returns types like QFont and QBrush for these (not even just a "symbolic" indicator), which is all to do with the presentation to the user.

                          X Offline
                          X Offline
                          Xilit
                          wrote on last edited by
                          #28

                          @JonB said in QSqlTableModel:

                          I hope @Xilit, the OP, won't mind as it's actually useful for him to see this stuff.

                          Nope! Of course I don't mind! Rather I vote for this disscusion! It is really useful information. I'll read all this stuff very carefully after I read all information about model by links above. Then I'll read this comments because I never understand DisplayRole properly.((

                          X 1 Reply Last reply
                          1
                          • X Xilit

                            @JonB said in QSqlTableModel:

                            I hope @Xilit, the OP, won't mind as it's actually useful for him to see this stuff.

                            Nope! Of course I don't mind! Rather I vote for this disscusion! It is really useful information. I'll read all this stuff very carefully after I read all information about model by links above. Then I'll read this comments because I never understand DisplayRole properly.((

                            X Offline
                            X Offline
                            Xilit
                            wrote on last edited by
                            #29

                            There are really tons of information on tutorials.))) In order not to sink there I decided to start my project from scretch and make this tutorial step by step. But now I stand at a crossroads what project architecture should I choose. I prepare one picture for you to show you what I mean.

                            1.jpg

                            I want to choose scheme number 6 and implement it in my project. I need universal solution to show tables from DB and lists in future. Maybe list, I'm not sure, that's why I want to create universal model (if it's possible). But for now I want to show table to user with my data from database table.

                            If it's not to hard for you to say what scheme (1-6) is incorrect at all and what scheme is preferable to implement in my situation.

                            Thank you!

                            X 1 Reply Last reply
                            0
                            • X Xilit

                              There are really tons of information on tutorials.))) In order not to sink there I decided to start my project from scretch and make this tutorial step by step. But now I stand at a crossroads what project architecture should I choose. I prepare one picture for you to show you what I mean.

                              1.jpg

                              I want to choose scheme number 6 and implement it in my project. I need universal solution to show tables from DB and lists in future. Maybe list, I'm not sure, that's why I want to create universal model (if it's possible). But for now I want to show table to user with my data from database table.

                              If it's not to hard for you to say what scheme (1-6) is incorrect at all and what scheme is preferable to implement in my situation.

                              Thank you!

                              X Offline
                              X Offline
                              Xilit
                              wrote on last edited by
                              #30

                              Emmm... Guys? Are you here? Is this topic is overloaded? Should I opened new one?

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

                                Follow the chain up, QSqlTableModel is already a subclass of QAbstractTableModel.

                                As for the delegate, it's a QStyledItemDelegate that is used by default by the view to render the table's content.

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

                                X 1 Reply Last reply
                                2
                                • SGaistS SGaist

                                  Follow the chain up, QSqlTableModel is already a subclass of QAbstractTableModel.

                                  As for the delegate, it's a QStyledItemDelegate that is used by default by the view to render the table's content.

                                  X Offline
                                  X Offline
                                  Xilit
                                  wrote on last edited by
                                  #32

                                  @SGaist

                                  "QStyledItemDelegate that is used by default by the view"

                                  Yes I know that. Tutorial says that if I want to make my own view I need to reimplement QStyledItemDelegate by sybclassing it. If you see what @VRonin said me to do is:
                                  "Just subclass QStyledItemDelegate and override displayText:". So does this scheme correct?

                                  1.png

                                  P.S. Sorry for my persistance but tommorow I start working with my project so I want to understand all the details. Thank you!

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

                                    No, QStyledItemDelegate is at the view level, or maybe between the view and the model since it uses it to render something from the data in the model.

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

                                    X 1 Reply Last reply
                                    3
                                    • SGaistS SGaist

                                      No, QStyledItemDelegate is at the view level, or maybe between the view and the model since it uses it to render something from the data in the model.

                                      X Offline
                                      X Offline
                                      Xilit
                                      wrote on last edited by
                                      #34

                                      @SGaist

                                      Yes it is clear. My main question is where should I connect (pass) my delegat? I created MyDelegate.cpp, describe what I want and then pass it / connect it in QSqlTableModel.cpp? That I discribed in scheme above. This is the simpliest case. Of course there is another possibility to create MyClass.cpp and pass to this class my model and delegate, but now I'm talking about simple one. If all my app is just show info from DB can I pass my delegate to QSqlTableModel.cpp?

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

                                        The delegate has nothing to do directly with the model. You set the delegate on the view with setItemDelegate or one of its more precise sibling.

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

                                        X 1 Reply Last reply
                                        2
                                        • SGaistS SGaist

                                          The delegate has nothing to do directly with the model. You set the delegate on the view with setItemDelegate or one of its more precise sibling.

                                          X Offline
                                          X Offline
                                          Xilit
                                          wrote on last edited by
                                          #36

                                          @SGaist

                                          Ok, thank you!

                                          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