.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();
}