QItemDelegate

.h
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QItemDelegate>
class QTableWidget;
class QItemDelegate;
class QStyleOptionViewItem;
class QModelIndex;
class QAbstractItemModel;

class Track{
public:
    explicit Track(const QString& title="",int duration=0){

    }

    QString title;
    int duration;
};

class TrackEditor:public QDialog{
    Q_OBJECT
public:
    explicit TrackEditor(QList<Track> *tracks,QWidget* parent=NULL);
private:
    QList<Track> *tracks;
    QTableWidget* tableWidget;
};

class TrackDelegate:public QItemDelegate{
    Q_OBJECT
public:
    TrackDelegate(int durationColumn,QObject *parent=0);
    void paint(QPainter *painter,const QStyleOptionViewItem &option,
               const QModelIndex& index)const;
    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;
private slots:
    void commitAndCloseEditor();
private:
    int duration;
};

#endif // DIALOG_H



.cpp
#include "dialog.h"
#include <QTableWidget>
#include <QItemDelegate>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QTimeEdit>
#include <QVBoxLayout>

TrackEditor::TrackEditor(QList<Track> *tracks, QWidget *parent)
    :QDialog(parent)
{
    this->tracks = tracks;
    tableWidget = new QTableWidget(tracks->count(),2);
    tableWidget->setItemDelegate(new TrackDelegate(1));
    tableWidget->setHorizontalHeaderLabels(
                QStringList()<<tr("Track")<<tr("Duration"));

    for(int row=0;row<tracks->count();++row){
        Track track = tracks->at(row);

        QTableWidgetItem *item0 = new QTableWidgetItem(track.title);
        tableWidget->setItem(row,0,item0);
        QTableWidgetItem *item1 = new QTableWidgetItem(
                    QString::number(track.duration));
        item1->setTextAlignment(Qt::AlignRight);
        tableWidget->setItem(row,1,item1);
    }
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(tableWidget);
    setLayout(layout);
}

TrackDelegate::TrackDelegate(int durationColumn, QObject *parent)
    :QItemDelegate(parent)
{
    this->duration = durationColumn;
}

void TrackDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
    if(index.column()==duration){
        int secs = index.model()->data(index,Qt::DisplayRole).toInt();
        QString text = QString("%1:%2").arg(secs/60,2,10,QChar('0'))
                                       .arg(secs%60,20,10,QChar('0'));
        QStyleOptionViewItem myOption = option;
        myOption.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;
        drawDisplay(painter,myOption,myOption.rect,text);
        drawFocus(painter,myOption,myOption.rect);
    }else{
        QItemDelegate::paint(painter,option,index);
    }
}

QWidget *TrackDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                                     const QModelIndex &index) const
{
    if(index.column()==duration){
        QTimeEdit *timeEdit = new QTimeEdit(parent);
        timeEdit->setDisplayFormat("mm:ss");
        connect(timeEdit,SIGNAL(editingFinished()),this,SLOT(commitAndCloseEditor()));
        return timeEdit;
    }else{
        return QItemDelegate::createEditor(parent,option,index);
    }
}

void TrackDelegate::commitAndCloseEditor()
{
    QTimeEdit *edit = qobject_cast<QTimeEdit *>(sender());
    emit commitData(edit);
    emit closeEditor(edit);
}

void TrackDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    if(index.column()==duration){
        int secs = index.model()->data(index,Qt::DisplayRole).toInt();
        QTimeEdit *timeEdit = qobject_cast<QTimeEdit *>(editor);
        timeEdit->setTime(QTime(0,secs/60,secs%60));
    }else{
        QItemDelegate::setEditorData(editor,index);
    }
}


void TrackDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                 const QModelIndex &index) const
{
    if(index.column()==duration){
        QTimeEdit *timeEdit = qobject_cast<QTimeEdit *>(editor);
        QTime time = timeEdit->time();
        int secs = (time.minute()*60)+time.second();
        model->setData(index,secs);
    }else{
        QItemDelegate::setModelData(editor,model,index);
    }
}



main.cpp
#include <QtGui/QApplication>
#include "dialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QList<Track> list;
    for(int i=0;i<10;i++){
        list.push_back(Track(QString("title%1").arg(i),10));
    }
    TrackEditor w(&list);
    w.show();
    return a.exec();
}

你可能感兴趣的:(delegate)