Как объединить QAbstractTableModel и QItemDelegate в один рабочий источник? - PullRequest
2 голосов
/ 09 августа 2010

У меня есть QTableView определяет в файле пользовательского интерфейса. Вот эта цифра:

альтернативный текст http://www.freeimagehosting.net/uploads/c5fa6c5d22.png

Я бы хотел изменить месяц (где точки массива красный ) с виджетом QComboBox, работающим с делегатами, но для меня, для моего пользовательского делегата и модели это слишком сложная проблема и я не могу понять, что не так?!

Проблема : по моему мнению, QAbstractTableModel не может работать с QItemDelegate, потому что я не могу объединить свой собственный простой ComboBoxDelegate виджет с QTableView. Wtf

Вот что у меня есть:

Мой пользовательский заголовок делегата / исходные данные:

class ComboBoxDelegate : public QItemDelegate
{
    Q_OBJECT

public:
    ComboBoxDelegate(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;
};

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

QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &/* option */,
    const QModelIndex &index) const
{
    QComboBox* editor = new QComboBox(parent);
    editor->addItem(index.data(Qt::DisplayRole).toString());
    return editor;
}

void ComboBoxDelegate::setEditorData(QWidget *editor,
    const QModelIndex &index) const
{
    QString value = index.model()->data(index, Qt::EditRole).toString();
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    comboBox->setCurrentIndex(comboBox->findText(value));
}

void ComboBoxDelegate::setModelData(QWidget *editor,
    QAbstractItemModel *model,
    const QModelIndex &index) const
{
    QComboBox *comboBox = static_cast<QComboBox*>(editor);
    QString value = comboBox->currentText();
    model->setData(index, value, Qt::EditRole);
}

Данные модели:

class PortfolioModel : public QAbstractTableModel
{
    Q_OBJECT;

    // types
    enum Position
    {
          ePosValue = 0
        , eColumnCount
    };

    enum Constants
    {
          eLocalCcy = 0
            , eCurrentTime
        , eCurrentMonthName
        , eRowCount
    };

    // data
    static QFont    font_;
    static QBrush   foreground_;
    static QBrush   background_;

    // methods
    QVariant        _valueName(int index) const;
    QVariant        _valueNameTooltip(int index) const;
    QVariant        _data(int index, int col, bool tooltip) const;

public:
    PortfolioModel(QObject* parent = 0);
    ~PortfolioModel();

    int         rowCount(const QModelIndex& parent = QModelIndex()) const;
    int         columnCount(const QModelIndex& parent = QModelIndex()) const;

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

signals:
    void            resizeToContents(void);

public slots:
    void            refreshData(void);
};

QFont PortfolioModel::font_ = QFont("Tahoma", 8, QFont::Normal);
QBrush PortfolioModel::foreground_ = QBrush(QColor("#000000")); // Black
QBrush PortfolioModel::background_ = QBrush(QColor("#C3FDB8")); // Dark Sea Green1

PortfolioModel::PortfolioModel(QObject* parent)
    : QAbstractTableModel(parent)
{}

PortfolioModel::~PortfolioModel()
{}

void PortfolioModel::refreshData(void)
{
    emit dataChanged(QModelIndex(), QModelIndex());
    emit resizeToContents();
}

int PortfolioModel::rowCount(const QModelIndex& parent/* = QModelIndex()*/) const
{
    return eRowCount;
}

int PortfolioModel::columnCount(const QModelIndex& parent/* = QModelIndex()*/) const
{
    return eColumnCount;
}

QVariant PortfolioModel::data(const QModelIndex& index, int role/* = Qt::DisplayRole*/) const
{
    if (!index.isValid())
        return QVariant();

    switch (role)
    {
        case Qt::DisplayRole:
            return _data(index.row(), index.column(), false);
        case Qt::FontRole:
            break;
        case Qt::BackgroundRole:
            return background_;
        case Qt::ForegroundRole:
            return foreground_;
        case Qt::TextAlignmentRole:
        case Qt::DecorationRole:
        case Qt::EditRole:
            break;
        case Qt::ToolTipRole:
            return _data(index.row(), index.column(), true);
        case Qt::StatusTipRole:
        case Qt::WhatsThisRole:
        case Qt::SizeHintRole:
            break;
    }
    return QVariant();
}

QVariant PortfolioModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    switch (orientation)
    {
    case Qt::Horizontal:
        switch (role)
        {
        case Qt::DisplayRole:
            if (section == ePosValue)
            {
                return QVariant("Value");
            }
        case Qt::ToolTipRole:
            if (section == ePosValue)
            {
                return QVariant("Fund values");
            }
            break;
        }
    case Qt::Vertical:
        switch (role)
        {
        case Qt::DisplayRole:
            return _valueName(section);
        case Qt::ToolTipRole:
            return _valueNameTooltip(section);
        }
        break;
    }

    return QVariant();
}

QVariant PortfolioModel::_valueNameTooltip(int index) const
{
    switch (index)
    {
    case eLocalCcy:
        return QObject::tr("Local currency");
    case eCurrentTime:
        return QObject::tr("Current time");
    case eCurrentMonthName:
        return QObject::tr("Current Month");
    }
    return QVariant();
}

QVariant PortfolioModel::_valueName(int index) const
{
    switch (index)
    {
    case eLocalCcy:
        return QObject::tr("Local Currency");
    case eCurrentTime:
        return QObject::tr("Current Time");
    case eCurrentMonthName:
        return QObject::tr("Month");
    }
    return QVariant();
}

QVariant PortfolioModel::_data(int index, int col, bool tooltip) const
{
    switch (index)
    {
    case eLocalCcy:
        if (col == ePosValue)
        {
            return QString(Nav::bk()->currentFund().currency(Nav::bk()->currentFund().localCcy()).code());
        }
        break;
    case eCurrentTime:
        if (col == ePosValue)
        {
            return Nav::bk()->currentFund().currentTime();
        }
        break;
    case eCurrentMonthName:
        if (col == ePosValue)
        {
            return QDate::longMonthName(Nav::bk()->currentFund().currentTime().date().month());
        }
        break;
    }
    return QVariant();
}

И после этого я сделал init делегат вот так:

ComboBoxDelegate *delegate_ = new ComboBoxDelegate(this);
this->ui.tableView->setItemDelegate(delegate_);

PS: простите за длинный вывод, но я думаю, что будет лучше, если все источники будут представлены здесь.

Спасибо!


  1. Добавлено:

Ответы [ 2 ]

2 голосов
/ 13 августа 2010

Из обзора QAbstractItemModel (см. Заголовок Подклассы ):

Чтобы включить редактирование в вашей модели, вы должен также реализовать setData (), и переопределить флаги (), чтобы ItemIsEditable возвращается.

Та же информация приведена в обзоре QAbstractTableModel . Ваш PortfolioModel класс не переопределяет ни одну из этих функций. Для того, чтобы использовать редактор делегата, вам нужно использовать do.

В качестве альтернативы, вы можете только захотеть, чтобы он выглядел так, как будто есть комбинированный список (на самом деле не разрешать редактирование). Если это так, вам, вероятно, понадобится сделать несколько хаков для рисования самостоятельно, чтобы он выглядел так ... или пометить его как редактируемый, но отключить виджет или что-то в этом роде.

1 голос
/ 09 августа 2010

в этом блоге http://qt -articles.blogspot.com / 2010/07 / как настроить listview-in-qt-using.html приведен один пример делегата .. пожалуйста, проверьте Ваш делегат с примером примера делегата, присутствующего в блоге. надеюсь, ты сможешь получить хоть какую-то подсказку.

...