QTableView display data in millimeter or inch
-
Hi,
What version of the value are you storing in the database ?
-
In that case, a QStyledItemDelegate for the QTableView.
For the QLineEdit, are you sure you will not be better served by a QSpinBox ?
-
@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 :-)
-
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.
-
You can create a widget that contains a QLineEdit and serves as proxy.
-
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));