├── MVD.pro ├── README.md ├── docs ├── MVD.docx └── MVD.pdf ├── main.cpp ├── screenshots ├── 1.png └── 2.png ├── tabledelegate.cpp ├── tabledelegate.h ├── tablemodel.cpp ├── tablemodel.h ├── widget.cpp ├── widget.h └── widget.ui /MVD.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | CONFIG += c++11 6 | 7 | # The following define makes your compiler emit warnings if you use 8 | # any Qt feature that has been marked deprecated (the exact warnings 9 | # depend on your compiler). Please consult the documentation of the 10 | # deprecated API in order to know how to port your code away from it. 11 | DEFINES += QT_DEPRECATED_WARNINGS 12 | 13 | # You can also make your code fail to compile if it uses deprecated APIs. 14 | # In order to do so, uncomment the following line. 15 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 | 18 | SOURCES += \ 19 | main.cpp \ 20 | tabledelegate.cpp \ 21 | tablemodel.cpp \ 22 | widget.cpp 23 | 24 | HEADERS += \ 25 | tabledelegate.h \ 26 | tablemodel.h \ 27 | widget.h 28 | 29 | FORMS += \ 30 | widget.ui 31 | 32 | # Default rules for deployment. 33 | qnx: target.path = /tmp/$${TARGET}/bin 34 | else: unix:!android: target.path = /opt/$${TARGET}/bin 35 | !isEmpty(target.path): INSTALLS += target 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MVD-Model-View-Delegate 2 | Qt MVD (Model View Delegate) 3 | 4 | ![](https://github.com/Qt-Widgets/MVD-Model-View-Delegate/blob/master/screenshots/1.png) 5 | 6 | ![](https://github.com/Qt-Widgets/MVD-Model-View-Delegate/blob/master/screenshots/2.png) 7 | -------------------------------------------------------------------------------- /docs/MVD.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/MVD-Model-View-Delegate/c94293fc75f9c427e3995d9153346841a9e1c6c6/docs/MVD.docx -------------------------------------------------------------------------------- /docs/MVD.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/MVD-Model-View-Delegate/c94293fc75f9c427e3995d9153346841a9e1c6c6/docs/MVD.pdf -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | Widget w; 9 | w.show(); 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /screenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/MVD-Model-View-Delegate/c94293fc75f9c427e3995d9153346841a9e1c6c6/screenshots/1.png -------------------------------------------------------------------------------- /screenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qt-Widgets/MVD-Model-View-Delegate/c94293fc75f9c427e3995d9153346841a9e1c6c6/screenshots/2.png -------------------------------------------------------------------------------- /tabledelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "tabledelegate.h" 2 | 3 | #include 4 | #include "tablemodel.h" 5 | 6 | TableDelegate::TableDelegate(QObject *parent) : QStyledItemDelegate(parent) 7 | { 8 | 9 | } 10 | 11 | QWidget *TableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, 12 | const QModelIndex &index) const 13 | { 14 | if (index.column() == TableModel::Value) 15 | { 16 | QSlider *editor = new QSlider(Qt::Horizontal, parent); 17 | editor->setRange(0, 100); 18 | editor->setAutoFillBackground(true); 19 | return editor; 20 | } 21 | 22 | return QStyledItemDelegate::createEditor(parent, option, index); 23 | } 24 | 25 | void TableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const 26 | { 27 | if (index.column() == TableModel::Value) 28 | { 29 | QSlider *slider = qobject_cast(editor); 30 | if (slider) 31 | { 32 | const int value = index.model()->data(index).toInt(); 33 | slider->setValue(value); 34 | } 35 | } 36 | else 37 | { 38 | QStyledItemDelegate::setEditorData(editor, index); 39 | } 40 | } 41 | 42 | void TableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const 43 | { 44 | if (index.column() == TableModel::Value) 45 | { 46 | QSlider *slider = qobject_cast(editor); 47 | if (editor) 48 | { 49 | model->setData(index, slider->value()); 50 | } 51 | } 52 | else 53 | { 54 | QStyledItemDelegate::setModelData(editor, model, index); 55 | } 56 | } 57 | 58 | void TableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 59 | { 60 | if (index.column() == TableModel::Value) 61 | { 62 | painter->save(); 63 | const int value = index.model()->data(index).toInt(); 64 | QRect rect(option.rect); 65 | const int width = (value * rect.width()) / 100; 66 | rect.setWidth(width); 67 | QColor c; 68 | if (value <= 20) 69 | { 70 | c = Qt::red; 71 | } 72 | else if (value <= 50) 73 | { 74 | c = QColor(240, 96, 0); 75 | } 76 | else 77 | { 78 | c = Qt::green; 79 | } 80 | 81 | painter->fillRect(rect, c); 82 | QTextOption o; 83 | o.setAlignment(Qt::AlignCenter); 84 | painter->drawText(option.rect, QString("%1 %").arg(value), o); 85 | 86 | painter->restore(); 87 | } 88 | else 89 | { 90 | QStyledItemDelegate::paint(painter, option, index); 91 | } 92 | } 93 | 94 | void TableDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, 95 | const QModelIndex &index) const 96 | { 97 | Q_UNUSED(index) 98 | editor->setGeometry(option.rect); 99 | } 100 | -------------------------------------------------------------------------------- /tabledelegate.h: -------------------------------------------------------------------------------- 1 | #ifndef TABLEDELEGATE_H 2 | #define TABLEDELEGATE_H 3 | 4 | #include 5 | 6 | class TableDelegate : public QStyledItemDelegate 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit TableDelegate(QObject *parent = nullptr); 11 | QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; 12 | void setEditorData(QWidget *editor, const QModelIndex &index) const; 13 | void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; 14 | 15 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; 16 | void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; 17 | }; 18 | 19 | #endif // TABLEDELEGATE_H 20 | -------------------------------------------------------------------------------- /tablemodel.cpp: -------------------------------------------------------------------------------- 1 | #include "tablemodel.h" 2 | 3 | 4 | TableModel::TableModel(QObject *parent) : QAbstractTableModel(parent) 5 | { 6 | 7 | } 8 | 9 | Qt::ItemFlags TableModel::flags(const QModelIndex &index) const 10 | { 11 | if (index.column() == Element) 12 | { 13 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 14 | } 15 | else if (index.column() == Value) 16 | { 17 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; 18 | } 19 | 20 | return QAbstractTableModel::flags(index); 21 | } 22 | 23 | int TableModel::rowCount(const QModelIndex &parent) const 24 | { 25 | return parent.isValid() ? 0 : mElements.count(); 26 | } 27 | 28 | int TableModel::columnCount(const QModelIndex &parent) const 29 | { 30 | return parent.isValid() ? 0 : Count; 31 | } 32 | 33 | QVariant TableModel::data(const QModelIndex &index, int role) const 34 | { 35 | if (!index.isValid() || index.row() < 0 || index.row() >= mElements.count()) 36 | { 37 | return QVariant(); 38 | } 39 | 40 | switch (role) 41 | { 42 | case Qt::DisplayRole: 43 | case Qt::EditRole: 44 | if (index.column() == Element) 45 | { 46 | return mElements[index.row()].first; 47 | } 48 | else if (index.column() == Value) 49 | { 50 | return mElements[index.row()].second; 51 | } 52 | break; 53 | } 54 | 55 | return QVariant(); 56 | } 57 | 58 | QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const 59 | { 60 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) 61 | { 62 | switch (section) 63 | { 64 | case Element: 65 | return "Element"; 66 | case Value: 67 | return "Value"; 68 | } 69 | } 70 | 71 | return QAbstractTableModel::headerData(section, orientation, role); 72 | } 73 | 74 | bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) 75 | { 76 | if (!index.isValid() || index.row() < 0 || index.row() >= mElements.count()) 77 | { 78 | return false; 79 | } 80 | 81 | switch (role) 82 | { 83 | case Qt::DisplayRole: 84 | case Qt::EditRole: 85 | if (index.column() == Element) 86 | { 87 | mElements[index.row()].first = value.toString(); 88 | } 89 | else if (index.column() == Value) 90 | { 91 | mElements[index.row()].second = value.toInt(); 92 | } 93 | emit dataChanged(index, index); 94 | return true; 95 | } 96 | 97 | return false; 98 | } 99 | 100 | void TableModel::addElement(const QString &element, int value) 101 | { 102 | const int count = mElements.count(); 103 | if (value < 0) 104 | { 105 | value = 0; 106 | } 107 | else if (value > 100) 108 | { 109 | value = 100; 110 | } 111 | beginInsertRows(QModelIndex(), count, count); 112 | mElements << qMakePair(element, value); 113 | endInsertRows(); 114 | } 115 | -------------------------------------------------------------------------------- /tablemodel.h: -------------------------------------------------------------------------------- 1 | #ifndef TABLEMODEL_H 2 | #define TABLEMODEL_H 3 | 4 | #include 5 | 6 | class TableModel : public QAbstractTableModel 7 | { 8 | Q_OBJECT 9 | public: 10 | enum Columns { Element = 0, Value, Count = Value + 1 }; 11 | 12 | explicit TableModel(QObject *parent = nullptr); 13 | 14 | Qt::ItemFlags flags(const QModelIndex &index) const; 15 | int rowCount(const QModelIndex &parent = QModelIndex()) const; 16 | int columnCount(const QModelIndex &parent = QModelIndex()) const; 17 | 18 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; 19 | QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; 20 | bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole); 21 | 22 | void addElement(const QString &element, int value); 23 | 24 | private: 25 | QList > mElements; 26 | }; 27 | 28 | #endif // TABLEMODEL_H 29 | -------------------------------------------------------------------------------- /widget.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include "ui_widget.h" 3 | 4 | #include "tabledelegate.h" 5 | 6 | Widget::Widget(QWidget *parent) 7 | : QWidget(parent) 8 | , ui(new Ui::Widget) 9 | { 10 | ui->setupUi(this); 11 | 12 | tableModel = new TableModel(); // Model 13 | ui->tableView->setModel(tableModel); // View 14 | ui->tableView->setItemDelegate(new TableDelegate); // Delegate 15 | 16 | ui->tableView->horizontalHeader()->setStretchLastSection(true); 17 | 18 | tableModel->addElement("C++", 90); 19 | tableModel->addElement("C", 70); 20 | tableModel->addElement("C#", 50); 21 | tableModel->addElement("Java", 30); 22 | tableModel->addElement("PHP", 15); 23 | tableModel->addElement("Visual Basic", 7); 24 | tableModel->addElement("Objective-C", 5); 25 | tableModel->addElement("Python", 4); 26 | } 27 | 28 | Widget::~Widget() 29 | { 30 | delete ui; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include 5 | #include "tablemodel.h" 6 | 7 | QT_BEGIN_NAMESPACE 8 | namespace Ui { class Widget; } 9 | QT_END_NAMESPACE 10 | 11 | class Widget : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | Widget(QWidget *parent = nullptr); 17 | ~Widget(); 18 | 19 | private: 20 | Ui::Widget *ui; 21 | 22 | private: 23 | TableModel *tableModel; 24 | }; 25 | #endif // WIDGET_H 26 | -------------------------------------------------------------------------------- /widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 317 10 | 401 11 | 12 | 13 | 14 | Widget 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | --------------------------------------------------------------------------------