Использование QItemDelegate с QAbstractTableModel - PullRequest
2 голосов
/ 17 августа 2011

У меня есть QAbstractItemModel и QItemDelegate, и вот моя проблема. Делегат ничего не делает. Его подпрограммы называются, но ничего не происходит.

Вот что я хотел бы видеть в своей таблице.

Текст: QComboBox: Текст: Текст: QProgressBar

где: разделитель столбцов.

Делегат. #ifndef DELEGATEACTION_H #define DELEGATEACTION_H

#include <QVariant>
#include <QItemDelegate>

#include <QWidget>
#include <QLabel>
#include <QComboBox>
#include <QProgressBar>

class DelegateAction : public QItemDelegate
{
    Q_OBJECT
public:
    explicit DelegateAction(QObject *parent = 0);

    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setEditorData(QWidget *editor, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

#endif // DELEGATEACTION_H

#include "DelegateAction.h"

DelegateAction::DelegateAction(QObject *parent) :
    QItemDelegate(parent)
{
}

QWidget * DelegateAction::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QWidget* editor = 0;

    switch (index.column())
    {
    case 0:
    default:
    {
        editor = new QLabel();
        break;
    }
    case 1:
    {
        QComboBox* combo = new QComboBox(parent);
        combo->addItem("Test");
        combo->addItem("Test 2");
        editor = combo;
        break;
    }
    case 4:
    {
        editor = new QProgressBar(parent);
        break;
    }
    }

    editor->installEventFilter(const_cast<DelegateAction*>(this));
    return editor;
}

void DelegateAction::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    QVariant value = index.model()->data(index, Qt::DisplayRole);

    switch (index.column())
    {
    case 0:
    default:
    {
        QLabel* label = static_cast<QLabel*>(editor);
        label->setText(value.toString());
        break;
    }
    case 1:
    {
        QComboBox* combo = static_cast<QComboBox*>(editor);
        combo->setCurrentIndex(combo->findText(value.toString()));
        break;
    }
    case 4:
    {
        QProgressBar* progress = static_cast<QProgressBar*>(editor);
        progress->setValue(value.toInt());
        break;
    }
    }

}

void DelegateAction::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QVariant value;
    switch (index.column())
    {
    case 0:
    default:
    {
        value = static_cast<QLabel*>(editor)->text();
        break;
    }
    case 1:
    {
        value = static_cast<QComboBox*>(editor)->currentText();
        break;
    }
    case 4:
    {
        value = static_cast<QProgressBar*>(editor)->value();
        break;
    }
    }

    model->setData(index, value);
}

void DelegateAction::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);
}

Модель.

#ifndef MODELACTIONS_H
#define MODELACTIONS_H

#include <QAbstractTableModel>

#include <Unit.h>

class ModelAction : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit ModelAction(QObject *parent = 0);
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    void sort(int column, Qt::SortOrder order);


    void setUnits(const QList<Unit*>* units);

private:
    const QList<Unit*>* units;
    bool ascending[5];

};

#endif // MODELACTIONS_H

#include "ModelAction.h"

ModelAction::ModelAction(QObject *parent) :
    QAbstractTableModel(parent),
    units(0)
{
}

int ModelAction::rowCount(const QModelIndex &parent) const
{
    if (units == 0)
    {
        return 0;
    }
    else
    {
        return units->length();
    }
}
int ModelAction::columnCount(const QModelIndex &parent) const
{
    return 5;
}
QVariant ModelAction::data(const QModelIndex &index, int role) const
{
    if (index.isValid() == false)
    {
        return QVariant();
    }

    if (role == Qt::TextAlignmentRole)
    {
        if (index.column() == 0 || index.column() == 2)
        {
            return int(Qt::AlignLeft | Qt::AlignVCenter);
        }
        else
        {
            return int(Qt::AlignRight | Qt::AlignVCenter);
        }
    }
    else if (role == Qt::DisplayRole)
    {
        if (index.column() == 0)
        {
            // Unit's id.
            return index.row() + 1;
        }
        else if (index.column() == 1)
        {
            return "bob";
            // Unit's Action.
            //return mechs.at(index.row())->getWeight();
        }
        else if (index.column() == 2)
        {
            // Unit's Action start.
            //return mechs.at(index.row())->getTechnology();
        }
        else if (index.column() == 3)
        {
            // Unit's Action end.
            //return Currency::numberToCurrency(mechs.at(index.row())->getPurchaseValue());
        }
        else if (index.column() == 4)
        {
            // Unit's Action progress.
            //return Currency::numberToCurrency(mechs.at(index.row())->getSellValue());
        }
    }
    return QVariant();
}

QVariant ModelAction::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
    {
        return QVariant();
    }

    if (orientation == Qt::Horizontal)
    {
        if (section == 0)
        {
            return "Id";
        }
        else if (section == 1)
        {
            return "Action";
        }
        else if (section == 2)
        {
            return "Begin Time";
        }
        else if (section == 3)
        {
            return "End Time";
        }
        else if (section == 4)
        {
            return "Progress";
        }
    }
    return QVariant();
}

void ModelAction::sort(int column, Qt::SortOrder order)
{
//    MechCompare compare;
//    compare.column = column;
//    ascending[column] = !ascending[column];
//    compare.ascending = ascending[column];
//    qSort(mechs.begin(), mechs.end(), compare);
    //    reset();
}

void ModelAction::setUnits(const QList<Unit *> *units)
{
    this->units = units;
    reset();
}

Qt::ItemFlags ModelAction::flags(const QModelIndex &index) const
{
    switch (index.column())
    {
    case 0:
    default:
    {
        return Qt::NoItemFlags;
        break;
    }
    case 1:
    {
        return Qt::ItemIsEditable | Qt::ItemIsEnabled;
    }
    }
}

bool ModelAction::setData(const QModelIndex &index, const QVariant &value, int role)
{
    switch (index.column())
    {
    case 1:
    {

    }
    }
}

Единственная проблема, о которой я знаю, это то, что функция ModelAction :: setData () является неполной. Я должен вернуться и отредактировать классы данных, которые эта модель отображает, прежде чем я смогу завершить эту подпрограмму. Тем не менее, все еще должны отображаться выпадающие списки и индикаторы, просто ничего не делать.

На данный момент я вижу только идентификаторы и мой тестовый текст "bob" для каждой строки в таблице. QComboBox и QProgressBar не отображаются вообще.

Любая помощь будет оценена.

Jec

Ответы [ 2 ]

4 голосов
/ 17 августа 2011

Реализованные вами функции делегата предназначены для редакторов . Они не отображаются, когда вы не редактируете элемент. Кажется, вы можете захотеть QAbstractItemView :: setIndexWidget вместо делегата.

0 голосов
/ 17 августа 2011

Метод createEditor вызывается только после определенных событий.Например, когда вы дважды щелкаете ячейку, ... Как заметил Бак, вы должны использовать setIndexWidget.

...