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. How to prevent exponential numbers view in tableView?

How to prevent exponential numbers view in tableView?

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 5 Posters 4.5k Views 2 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.
  • MucipM Mucip

    Hi @KillerSmath ,
    I already use delegate in other forms. But this number comes directly from sql query?!...

    Regards,
    Mucip:)

    KillerSmathK Offline
    KillerSmathK Offline
    KillerSmath
    wrote on last edited by KillerSmath
    #9

    @Mucip
    The delegate uses QLocale to convert it to String, and by default, it uses 'g' format to convert float and double values to string.

    Edit: If you're little curious, you can see this conversion directly in the QAbstractItemDelegate source code (Inherited By QItemDelegate, the standard QTableView delegate)

    @Computer Science Student - Brazil
    Web Developer and Researcher
    “Sometimes it’s the people no one imagines anything of who do the things that no one can imagine.” - Alan Turing

    1 Reply Last reply
    2
    • JonBJ Online
      JonBJ Online
      JonB
      wrote on last edited by JonB
      #10

      Please excuse me for having my say, but this area has ben a bug-bear of mine for some time.

      I'm sure that @KillerSmath, the post he links to and the others who do this via a delegate know much more than I do about Qt. But to me this is just the wrong place to do number formatting. For one, thing it locks all the logic down into some QStyledItemDelegate. But the string formatting of the number, to me, is just not something to do with a table's/delegate's displayText(). You may want it for all sorts of other purposes, e.g. exporting the data. Shouldn't a delegate be used for drawing it big, or upside-down or with purple stripes in a box?

      Surely @raven-worx's very, very simple code in data(Qt::DisplayRole) is the place that makes logical sense for this feature, returning the desired string representation to be used for display while still being available to be called by anything else which wants it, and that's where I have done mine. It also has the virtue of being about one line of code instead of all the code required for a NumberFormatDelegate-type solution!

      VRoninV 1 Reply Last reply
      1
      • raven-worxR raven-worx

        @Mucip
        ok so then you could try to cast the column already in the SQL query.
        Or subclass your sql model and in data() (for the corresponding column's Qt::DisplayRole) return:

        QString::number(doubleVal, 'f', 0)
        
        MucipM Offline
        MucipM Offline
        Mucip
        wrote on last edited by
        #11

        Hi @raven-worx ,
        Well, How can I cast it in SQL?

        Regards,
        Mucip:)

        1 Reply Last reply
        0
        • raven-worxR raven-worx

          @Mucip
          ok so then you could try to cast the column already in the SQL query.
          Or subclass your sql model and in data() (for the corresponding column's Qt::DisplayRole) return:

          QString::number(doubleVal, 'f', 0)
          
          MucipM Offline
          MucipM Offline
          Mucip
          wrote on last edited by Mucip
          #12

          Hi @raven-worx ,
          I appllied CAST as follow:

          modelTableTalep->setQuery("select sn, stok_kod, stok_ad, CAST(talep_adet AS TEXT), talep_birim, mevcut_stok, talep_onay, sebep, talep_zaman, termin_tarih, kullanici, talep_eden FROM talep ORDER BY sn DESC;",baglanti::mdb());
          But still same problem 1,2E+8 like?!...

          But I wanted to use "Qt::DisplayRole"
          Any example please?...

          regards,
          Mucip:)

          JonBJ 1 Reply Last reply
          0
          • MucipM Mucip

            Hi @raven-worx ,
            I appllied CAST as follow:

            modelTableTalep->setQuery("select sn, stok_kod, stok_ad, CAST(talep_adet AS TEXT), talep_birim, mevcut_stok, talep_onay, sebep, talep_zaman, termin_tarih, kullanici, talep_eden FROM talep ORDER BY sn DESC;",baglanti::mdb());
            But still same problem 1,2E+8 like?!...

            But I wanted to use "Qt::DisplayRole"
            Any example please?...

            regards,
            Mucip:)

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by JonB
            #13

            @Mucip
            If you are saying that your column is the CAST(talep_adet AS TEXT) and that still comes out as 1,2E+8, then that would mean that is the textual representation of that number up at SQL. Depending on your SQL server, something like CONVERT(talep_ad, ???) would be required, where the ??? is whatever your SQL allows for producing a number in digits instead, assuming there is such a parameter.

            As for doing it in your model override's data() function (which is how I would do it), you could actually look at the docs. You want something like:

            QVariant MyModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
            {
                val = QSqlQueryModel::data(index, role);
                if (role == Qt::DisplayRole && index.column() == aDoubleNumberColumn)
                {
                    doubleVal = static_cast<double>(val.value());
                    return QString::number(doubleVal, 'f', 0)
                }
                return val;
            }
            
            MucipM 1 Reply Last reply
            0
            • JonBJ JonB

              @Mucip
              If you are saying that your column is the CAST(talep_adet AS TEXT) and that still comes out as 1,2E+8, then that would mean that is the textual representation of that number up at SQL. Depending on your SQL server, something like CONVERT(talep_ad, ???) would be required, where the ??? is whatever your SQL allows for producing a number in digits instead, assuming there is such a parameter.

              As for doing it in your model override's data() function (which is how I would do it), you could actually look at the docs. You want something like:

              QVariant MyModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
              {
                  val = QSqlQueryModel::data(index, role);
                  if (role == Qt::DisplayRole && index.column() == aDoubleNumberColumn)
                  {
                      doubleVal = static_cast<double>(val.value());
                      return QString::number(doubleVal, 'f', 0)
                  }
                  return val;
              }
              
              MucipM Offline
              MucipM Offline
              Mucip
              wrote on last edited by
              #14

              Hi @JonB ,
              In this way I neet to change row by row?! Am I wrong?!...

              Regards,
              Mucip:)

              1 Reply Last reply
              0
              • JonBJ JonB

                Please excuse me for having my say, but this area has ben a bug-bear of mine for some time.

                I'm sure that @KillerSmath, the post he links to and the others who do this via a delegate know much more than I do about Qt. But to me this is just the wrong place to do number formatting. For one, thing it locks all the logic down into some QStyledItemDelegate. But the string formatting of the number, to me, is just not something to do with a table's/delegate's displayText(). You may want it for all sorts of other purposes, e.g. exporting the data. Shouldn't a delegate be used for drawing it big, or upside-down or with purple stripes in a box?

                Surely @raven-worx's very, very simple code in data(Qt::DisplayRole) is the place that makes logical sense for this feature, returning the desired string representation to be used for display while still being available to be called by anything else which wants it, and that's where I have done mine. It also has the virtue of being about one line of code instead of all the code required for a NumberFormatDelegate-type solution!

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

                @JonB Strongly disagree with your post.

                The model should be pure data. If it contains a double then the model only has to care about those 64bits of data. It does not have to care about how to represent that data to the user, it's not its job. The delegate is the one that is concerned to converting pure data into something the user can read/interact with.

                Surely @raven-worx's very, very simple code in data(Qt::DisplayRole) is the place that makes logical sense for this feature

                This is even worse as it breaks the logic of the model itself. Try sorting the column containing the numbers converted to string using QSortFilterProxyModel and you'll quickly realised how bad it is to make the model care about visual representation of data.

                The solution proposed by @KillerSmath is the correct one and the only acceptable one from a model-view logic point of view.

                class NumberFormatDelegate : public QStyledItemDelegate{
                    Q_OBJECT
                    Q_DISABLE_COPY(NumberFormatDelegate)
                public:
                    NumberFormatDelegate(QObject *parent = Q_NULLPTR)
                        :QStyledItemDelegate(parent)
                    {}
                    QString displayText(const QVariant &value, const QLocale &locale) const Q_DECL_OVERRIDE{
                        switch(value.type()){
                        case QMetaType::Float:
                            return locale.toString(value.toFloat(),'f');
                        case QMetaType::Double:
                            return locale.toString(value.toDouble(),'f');
                        default:
                            return QStyledItemDelegate::displayText(value,locale);
                        }
                    }
                };
                

                ui->tVStok->setItemDelegateForColumn(3, new NumberFormatDelegate(this));

                "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

                MucipM JonBJ 2 Replies Last reply
                1
                • VRoninV VRonin

                  @JonB Strongly disagree with your post.

                  The model should be pure data. If it contains a double then the model only has to care about those 64bits of data. It does not have to care about how to represent that data to the user, it's not its job. The delegate is the one that is concerned to converting pure data into something the user can read/interact with.

                  Surely @raven-worx's very, very simple code in data(Qt::DisplayRole) is the place that makes logical sense for this feature

                  This is even worse as it breaks the logic of the model itself. Try sorting the column containing the numbers converted to string using QSortFilterProxyModel and you'll quickly realised how bad it is to make the model care about visual representation of data.

                  The solution proposed by @KillerSmath is the correct one and the only acceptable one from a model-view logic point of view.

                  class NumberFormatDelegate : public QStyledItemDelegate{
                      Q_OBJECT
                      Q_DISABLE_COPY(NumberFormatDelegate)
                  public:
                      NumberFormatDelegate(QObject *parent = Q_NULLPTR)
                          :QStyledItemDelegate(parent)
                      {}
                      QString displayText(const QVariant &value, const QLocale &locale) const Q_DECL_OVERRIDE{
                          switch(value.type()){
                          case QMetaType::Float:
                              return locale.toString(value.toFloat(),'f');
                          case QMetaType::Double:
                              return locale.toString(value.toDouble(),'f');
                          default:
                              return QStyledItemDelegate::displayText(value,locale);
                          }
                      }
                  };
                  

                  ui->tVStok->setItemDelegateForColumn(3, new NumberFormatDelegate(this));

                  MucipM Offline
                  MucipM Offline
                  Mucip
                  wrote on last edited by
                  #16

                  Dear @VRonin ,
                  I uset ItemDelegate and perfect result. Thanks all...

                  Regards,
                  Mucip:)

                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    @JonB Strongly disagree with your post.

                    The model should be pure data. If it contains a double then the model only has to care about those 64bits of data. It does not have to care about how to represent that data to the user, it's not its job. The delegate is the one that is concerned to converting pure data into something the user can read/interact with.

                    Surely @raven-worx's very, very simple code in data(Qt::DisplayRole) is the place that makes logical sense for this feature

                    This is even worse as it breaks the logic of the model itself. Try sorting the column containing the numbers converted to string using QSortFilterProxyModel and you'll quickly realised how bad it is to make the model care about visual representation of data.

                    The solution proposed by @KillerSmath is the correct one and the only acceptable one from a model-view logic point of view.

                    class NumberFormatDelegate : public QStyledItemDelegate{
                        Q_OBJECT
                        Q_DISABLE_COPY(NumberFormatDelegate)
                    public:
                        NumberFormatDelegate(QObject *parent = Q_NULLPTR)
                            :QStyledItemDelegate(parent)
                        {}
                        QString displayText(const QVariant &value, const QLocale &locale) const Q_DECL_OVERRIDE{
                            switch(value.type()){
                            case QMetaType::Float:
                                return locale.toString(value.toFloat(),'f');
                            case QMetaType::Double:
                                return locale.toString(value.toDouble(),'f');
                            default:
                                return QStyledItemDelegate::displayText(value,locale);
                            }
                        }
                    };
                    

                    ui->tVStok->setItemDelegateForColumn(3, new NumberFormatDelegate(this));

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by JonB
                    #17

                    @VRonin
                    Well, just to say I equally strongly disagree with yours :) Of course I respect your doubtless expert views too! I trust we can still be friends.

                    There is a reason that the data() method has a role of DisplayRole. Docs:

                    The key data to be rendered in the form of text. (QString)

                    That's precisely what I want to use. Otherwise remove it, and say there is no such role for the data. I absolutely do allow sorting of my data. And of course the whole point is that I do not sort by DisplayRole, I sort by EditRole (or SortRole).

                    If I sit down one day and have a column in my model which is, say, an int like an enumerated which I want displayed as apples, pears, oranges, and I decide I do want my users to be able to sort by the string they see, I have the option of sorting by DisplayRole if that is what I intend. I can't if it's buried away in some styled item delegate.

                    Meanwhile, I do not only use the data in the model for display in views/tables. I might, for example wish to use to export textual data from my model. And I want the same text whether it's a cell in a table or an item in a PDF file. So again, I don't want the logic to be in some styled item delegate. The textual format of a number, commas, negative signs, leading currency symbol etc. is a real attribute of the data, not just a whim of a table view. To me.

                    VRoninV 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @VRonin
                      Well, just to say I equally strongly disagree with yours :) Of course I respect your doubtless expert views too! I trust we can still be friends.

                      There is a reason that the data() method has a role of DisplayRole. Docs:

                      The key data to be rendered in the form of text. (QString)

                      That's precisely what I want to use. Otherwise remove it, and say there is no such role for the data. I absolutely do allow sorting of my data. And of course the whole point is that I do not sort by DisplayRole, I sort by EditRole (or SortRole).

                      If I sit down one day and have a column in my model which is, say, an int like an enumerated which I want displayed as apples, pears, oranges, and I decide I do want my users to be able to sort by the string they see, I have the option of sorting by DisplayRole if that is what I intend. I can't if it's buried away in some styled item delegate.

                      Meanwhile, I do not only use the data in the model for display in views/tables. I might, for example wish to use to export textual data from my model. And I want the same text whether it's a cell in a table or an item in a PDF file. So again, I don't want the logic to be in some styled item delegate. The textual format of a number, commas, negative signs, leading currency symbol etc. is a real attribute of the data, not just a whim of a table view. To me.

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

                      @JonB said in How to prevent exponential numbers view in tableView?:

                      The key data to be rendered in the form of text

                      data to be rendered the model doesn't care about actual rendering it provides the data to be rendered by someone else

                      And of course the whole point is that I do not sort by DisplayRole, I sort by EditRole

                      EditRole and DispalyRole have another purpose. The easiest comparison is with excel/libreoffice calc: EditRole contains the formula of a cell, DispalyRole contains the result of that formula. The formula does not need to be rendered hence it is buried in that role while the result (not his graphical representation, just the data of the result) is stored in DispalyRole. Then there's the practical point of all the models provided by Qt implement EditRole and DispalyRole as one and the same.

                      I might, for example wish to use to export textual data from my model. And I want the same text whether it's a cell in a table or an item in a PDF file

                      Nothing stops you from storing suggestions on how to render the data inside other roles. There are even pre built roles for fonts and colours, so you can store even the number formatting you prefer in a user role to be used by whoever will take care of rendering that data but the model should only care about data, never of its representation

                      "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
                      0
                      • VRoninV VRonin

                        @JonB said in How to prevent exponential numbers view in tableView?:

                        The key data to be rendered in the form of text

                        data to be rendered the model doesn't care about actual rendering it provides the data to be rendered by someone else

                        And of course the whole point is that I do not sort by DisplayRole, I sort by EditRole

                        EditRole and DispalyRole have another purpose. The easiest comparison is with excel/libreoffice calc: EditRole contains the formula of a cell, DispalyRole contains the result of that formula. The formula does not need to be rendered hence it is buried in that role while the result (not his graphical representation, just the data of the result) is stored in DispalyRole. Then there's the practical point of all the models provided by Qt implement EditRole and DispalyRole as one and the same.

                        I might, for example wish to use to export textual data from my model. And I want the same text whether it's a cell in a table or an item in a PDF file

                        Nothing stops you from storing suggestions on how to render the data inside other roles. There are even pre built roles for fonts and colours, so you can store even the number formatting you prefer in a user role to be used by whoever will take care of rendering that data but the model should only care about data, never of its representation

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by JonB
                        #19

                        @VRonin
                        So it's OK for ForegroundRole to return the color to display text in a table but it's not OK for DisplayRole to return the desired text to be displayed there? The text should be done in a delegate instead, so why shouldn't the color be done in one too? You treat DisplayRole very differently from other roles such as ForegroundRole, and I certainly did not get that as I learned Qt, I don't see from the docs where I should understand this very special handling of DisplayRole.

                        I wish you had been there when I started out on this! [What's your phone number, we should talk so I can understand? ;-) ] Anyway, I am where I am now, and am committed to the way I have implemented in my code. Next time, when I don't start out from existing 32K of already (badly) written code, I will go down the delegate route!

                        VRoninV 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @VRonin
                          So it's OK for ForegroundRole to return the color to display text in a table but it's not OK for DisplayRole to return the desired text to be displayed there? The text should be done in a delegate instead, so why shouldn't the color be done in one too? You treat DisplayRole very differently from other roles such as ForegroundRole, and I certainly did not get that as I learned Qt, I don't see from the docs where I should understand this very special handling of DisplayRole.

                          I wish you had been there when I started out on this! [What's your phone number, we should talk so I can understand? ;-) ] Anyway, I am where I am now, and am committed to the way I have implemented in my code. Next time, when I don't start out from existing 32K of already (badly) written code, I will go down the delegate route!

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

                          @JonB said in How to prevent exponential numbers view in tableView?:

                          So it's OK for ForegroundRole to return the color to display text

                          Indeed. It tells the guy who actually needs to render the item what color to use but it's pure data it doesn't take ownership of the painting. The delegate is free to ignore that role when rendering if it doesn't fit the representation it is showing to the user

                          so why shouldn't the color be done in one too?

                          it is indeed done in the delegate.

                          I don't see from the docs where I should understand this very special handling of DisplayRole

                          And there isn't. [slight simplification ahead] ForegroundRole contains 4 integers for argb. it's pure data as well

                          but it's not OK for DisplayRole to return the desired text to be displayed there?

                          Yep, as it hides from the delegate the fact that it should render a decimal number, the delegate will just see a string and it might render it in the wrong way.

                          "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 How to prevent exponential numbers view in tableView?:

                            So it's OK for ForegroundRole to return the color to display text

                            Indeed. It tells the guy who actually needs to render the item what color to use but it's pure data it doesn't take ownership of the painting. The delegate is free to ignore that role when rendering if it doesn't fit the representation it is showing to the user

                            so why shouldn't the color be done in one too?

                            it is indeed done in the delegate.

                            I don't see from the docs where I should understand this very special handling of DisplayRole

                            And there isn't. [slight simplification ahead] ForegroundRole contains 4 integers for argb. it's pure data as well

                            but it's not OK for DisplayRole to return the desired text to be displayed there?

                            Yep, as it hides from the delegate the fact that it should render a decimal number, the delegate will just see a string and it might render it in the wrong way.

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by
                            #21

                            @VRonin
                            Hmm, food for thought, 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