How to visualize model data in different ways in QTableView?
I have a model containing in one column floats (ex: 22.7). Now, I want that in QTableView, it will be visualized together with the unit (MB): 22.7 MB. The reason I am doing so is because I want that sorting is based on floats, but the visualization is as I said with units.
I created a Model, a Filter and a View. But it does not work. Here is a piece of my code:
QStandardItemModel* model = new QStandardItemModel(this);
QSortFilterProxyModel *filterModel = new QSortFilterProxyModel(0);
filterModel->setSourceModel(model);
QStandardItem* vSItem6 = new QStandardItem();
vSItem6->setData(22.7, Qt::DisplayRole);
model->setItem(1, 7, vSItem6);
QModelIndex index = model->index(1, 7, QModelIndex());
QString itext = model->data(index, Qt::DisplayRole).toS开发者_高级运维tring();
filterModel->setData(index, itext + " MB", Qt::DisplayRole);
mUi.tableView->setModel(filterModel);
mUi.tableView->setSortingEnabled(true);
mUi.tableView->show();
Everything seems to be fine, but in QTableView, only the float number is visualized (without the unit MB). Can anybody please help me? Thanks
Have a look at setItemDelegate or setItemDelegateForColumn. You can derive your delegate class from QStyledItemDelegate, and in the overridden paint method you can paint your numbers including the units.
I'm a newbie in Qt development, but can't you derive from class QAbstactTableModel
, and implement the data
method so that it returns the float value plus "MB" (in a QString object), when role is DisplayRole
?
If you just want to take the value of the model and modify it's string representation you can do so easily by inheriting from QStyledItemDelegate and just overriding a single method namely displayText(), which returns a QString. I just did that to have the values (representing the amount of memory consumed by a process) displayed in the most appropriate unit (byte, kbyte, megabyte and so on). So it's a usecase that is more or less similar to the problem described above and it works like a charme. You can see the code below (but ignore the application specific parts).
Header file:
#pragma once
#include <QStyledItemDelegate>
class UnitAwareItemDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
explicit UnitAwareItemDelegate(QObject* parent = 0);
virtual QString displayText(const QVariant & value, const QLocale & locale) const;
};
Implementation file:
#include "UnitAwareItemDelegate.hpp"
#include "UnitUtils.hpp"
#include <QPainter>
#include <QStyleOptionViewItem>
#include <QModelIndex>
UnitAwareItemDelegate::UnitAwareItemDelegate(QObject* parent): QStyledItemDelegate(parent)
{
}
QString UnitAwareItemDelegate::displayText(const QVariant& value, const QLocale& locale) const
{
if (value == 0)
return QString();
// value supplied by libproc is in kb so we mul by 1024 to get the byte value
uint64_t oldValue = value.toULongLong() * 1024;
const UnitUtils::ValueUnit unit = UnitUtils::findSuitableUnit(oldValue);
const uint64_t newValue = oldValue / UnitUtils::value(unit);
return QString("%1 %2")
.arg(QString::number(newValue))
.arg(QString(UnitUtils::name(unit).at(0)).toUpper());
}
I know your question was about QTableView, but it might be easier if it is the only thing you want to display (I don't know your objectives) to use a QTableWidget with a QDoubleSpinBox since it has a method that allows you to set a suffix to the value that is displayed.
In your case, it would be:
QDoubleSpinBox* spin = new QDoubleSpinBox();
spin->setSuffix("MB");
Note that the range is set by default from 0.0 to 99.99 so if you want to set other values you should change the range before.
Hope this helps.
精彩评论