Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableView display data in millimeter or inch
Qt 6.12 LTS is out! See what's new in the release blog

QTableView display data in millimeter or inch

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 2 Posters 927 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.
  • A Offline
    A Offline
    addebito
    wrote on last edited by
    #1

    Hi at all,

    do you know the "best way" to display data in millimeters or inch inside a QTableView and QLineEdit mapped to a database table?

    As usual, any suggestion will be appreciated.

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

      Hi,

      What version of the value are you storing in the database ?

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

      1 Reply Last reply
      0
      • A Offline
        A Offline
        addebito
        wrote on last edited by
        #3

        Hi @SGaist,
        inside the database all datas are stored in millimeters.

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

          In that case, a QStyledItemDelegate for the QTableView.

          For the QLineEdit, are you sure you will not be better served by a QSpinBox ?

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

          1 Reply Last reply
          0
          • A Offline
            A Offline
            addebito
            wrote on last edited by
            #5

            @SGaist said in QTableView display data in millimeter or inch:

            In that case, a QStyledItemDelegate for the QTableView.

            I forgot to specify that the QTableView is in "read-only mode", to edit or insert a new row the user write the data inside the QLineEdits mapped by QDataWidgetMapper.
            I've about 15 column to convert on the fly between mm / inch depending of the user choice.

            The qtwidgets-itemviews-stardelegate-example could be a good starting point?

            QSpinBox... I don't know why, there is no real reason, but I don't like much the "spin box" widget. Not only in QT, but in general. Anyway, I'll give it a chance :-)

            1 Reply Last reply
            0
            • A Offline
              A Offline
              addebito
              wrote on last edited by
              #6

              Hi @SGaist ,

              I've created my QStyledItemDelegate...

              #pragma once
              
              #include <QStyledItemDelegate>
              
              class VTMmInchItemDelegate : public QStyledItemDelegate
              {
                public:
                  explicit VTMmInchItemDelegate(QObject *parent = nullptr);
                  virtual QString displayText(const QVariant &value, const QLocale &locale) const;
              
                public slots:
                  void slotMeasChanged(bool mm);
              
                private:
                  /// unit measure (mm = 1.0, inch = 25.4)
                  double m_unitMeas = 1.0;
              
                  /// decimal precision mm = 3, inch = 5
                  int m_decimalPrecision = 3;
              };
              
              #include "vtmminchitemdelegate.h"
              
              VTMmInchItemDelegate::VTMmInchItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
              {
                  //
              }
              
              QString VTMmInchItemDelegate::displayText(const QVariant &value, const QLocale &locale) const
              {
                  // unit measure (mm = 1.0, inch = 25.4)
                  // decimal precision (mm = 3, inch = 5)
                  return QString::number(value.toDouble() / m_unitMeas, 'f', m_decimalPrecision);
              }
              
              void VTMmInchItemDelegate::slotMeasChanged(bool mm)
              {
                  if (mm)
                  {
                      m_unitMeas         = 1.0;
                      m_decimalPrecision = 3;
                  }
                  else
                  {
                      m_unitMeas         = 25.4;
                      m_decimalPrecision = 5;
                  }
              }
              

              ...and I can use it with a QTableView in this way:

              ui->tableView->setItemDelegateForColumn(2, new VTMmInchItemDelegate(this));
              ui->tableView->setItemDelegateForColumn(3, new VTMmInchItemDelegate(this));
              

              But now I don't know how to achieve the same behavior with the widgets mapped by QDataWidgetMapper.

              I have about 30 widgets (QlineEdit or QComboBox) and I'd like to map some QLineEdits to display as the QTableView, the data correctly according to the setting mm / inch.

              Do you have any suggestion please?
              Thank you so much.

              PS: I've try another way, subclassing the QSqlTableModel and reimplementing the function:

              QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
              

              ...but I obtain the same result, the QTableView works fine, the widgets mapped by QDataWidgetMapper not.

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

                You can create a widget that contains a QLineEdit and serves as proxy.

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

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  addebito
                  wrote on last edited by
                  #8

                  Hi @SGaist ,

                  thank you for your suggestions, follow my implementation.

                  • QSqlTableModel subclass
                  • QItemDelegate subclass

                  vtsqltablemodel.h

                  #pragma once
                  
                  #include <QSqlTableModel>
                  
                  class VTSqlTableModel : public QSqlTableModel
                  {
                    public:
                      VTSqlTableModel(const QVector<int> &column, QObject *parent = nullptr, QSqlDatabase db = QSqlDatabase());
                      QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
                  
                    public slots:
                      void slotMeasChanged(bool mm);
                  
                    private:
                      /// list of columns to format in mm or inch
                      QVector<int> m_column;
                  
                      /// unit measure (mm = 1.0, inch = 25.4)
                      double m_unitMeas = 1.0;
                  
                      /// decimal precision mm = 3, inch = 5
                      int m_decimalPrecision = 3;
                  };
                  

                  vtsqltablemodel.cpp

                  #include "vtsqltablemodel.h"
                  
                  VTSqlTableModel::VTSqlTableModel(const QVector<int> &column, QObject *parent, QSqlDatabase db) : QSqlTableModel(parent, db), m_column(column)
                  {
                      //
                  }
                  
                  QVariant VTSqlTableModel::data(const QModelIndex &index, int role) const
                  {
                      if (role == Qt::DisplayRole)
                      {
                          if (m_column.contains(index.column()))
                              return QVariant(QString::number(QSqlTableModel::data(index, role).toDouble() / m_unitMeas, 'f', m_decimalPrecision));
                      }
                  
                      return QSqlTableModel::data(index, role);
                  }
                  
                  void VTSqlTableModel::slotMeasChanged(bool mm)
                  {
                      if (mm)
                      {
                          m_unitMeas         = 1.0;
                          m_decimalPrecision = 3;
                      }
                      else
                      {
                          m_unitMeas         = 25.4;
                          m_decimalPrecision = 5;
                      }
                      select();
                  }
                  

                  vtmminchitemdelegate.h

                  #pragma once
                  
                  #include <QItemDelegate>
                  
                  class VTMmInchItemDelegate : public QItemDelegate
                  {
                      Q_OBJECT
                    public:
                      explicit VTMmInchItemDelegate(const QVector<int> &column, QObject *parent = nullptr);
                      void setEditorData(QWidget *editor, const QModelIndex &index) const;
                      void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
                  
                    public slots:
                      void slotMeasChanged(bool mm);
                  
                    private:
                      /// list of columns to format in mm or inch
                      QVector<int> m_column;
                  
                      /// unit measure (mm = 1.0, inch = 25.4)
                      double m_unitMeas = 1.0;
                  
                      /// decimal precision mm = 3, inch = 5
                      int m_decimalPrecision = 3;
                  };
                  

                  vtmminchitemdelegate.cpp

                  #include "vtmminchitemdelegate.h"
                  
                  #include <QDebug>
                  #include <QLineEdit>
                  #include <QVariant>
                  
                  VTMmInchItemDelegate::VTMmInchItemDelegate(const QVector<int> &column, QObject *parent) : QItemDelegate(parent), m_column(column)
                  {
                      //
                  }
                  
                  void VTMmInchItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
                  {
                      QLineEdit *edt = (dynamic_cast<QLineEdit *>(editor));
                  
                      if ((m_column.contains(index.column())) && (edt))
                      {
                          // I have only to display data because is already formatted as QString by my SqlTableModel
                          edt->setText(index.data().toString());
                      }
                      else
                          QItemDelegate::setEditorData(editor, index);
                  }
                  
                  void VTMmInchItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
                  {
                      QLineEdit *edt = (dynamic_cast<QLineEdit *>(editor));
                  
                      if ((m_column.contains(index.column())) && (edt))
                      {
                          // I have to convert the user input data regarding to the "unit measure" private variable
                          QVariant value = edt->text().toDouble() * m_unitMeas;
                          model->setData(index, value);
                      }
                      else
                          QItemDelegate::setModelData(editor, model, index);
                  }
                  
                  void VTMmInchItemDelegate::slotMeasChanged(bool mm)
                  {
                      if (mm)
                      {
                          m_unitMeas         = 1.0;
                          m_decimalPrecision = 3;
                      }
                      else
                      {
                          m_unitMeas         = 25.4;
                          m_decimalPrecision = 5;
                      }
                  }
                  

                  ...and you can use it as follow.

                      QVector<int> cols;
                      cols << 2 << 3 << 4;
                      m_model = new VTSqlTableModel(cols);
                  ...
                      m_mapper = new QDataWidgetMapper;
                      m_mapper->setModel(m_model);
                      m_mapper->setItemDelegate(new VTMmInchItemDelegate(cols, this));
                  
                  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
                  • Unsolved