`
qimo601
  • 浏览: 3416981 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

基于QItemDelegate的例子2 trackeEditorDelegate

    博客分类:
  • Qt
阅读更多

 trackeEditorDelegate例子是《 C++ GUI Programming with Qt 4》中自定义委托的标准例子。


和上一个SpinBox例子相比更完整:它多了自定义Editor、重载Paint()函数、提交数据信号commitData()、关闭控件信号closeEditor()

附件中有源码可以下载。

 

Main.cpp

 

#include <QApplication>

#include "trackeditor.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QList<Track> tracks;
    tracks << Track("The Flying Dutchman: Overture", 630)
           << Track("The Flying Dutchman: Wie aus der Fern laengst "
                    "vergangner Zeiten", 374)
           << Track("The Flying Dutchman: Steuermann, lass die Wacht",
                    152)
           << Track("Die Walkuere: Ride of the Valkyries", 286)
           << Track("Tannhaeuser: Freudig begruessen wir die edle "
                    "Halle", 384)
           << Track("Tannhaeuser: Wie Todesahnung - O du mein holder "
                    "Abendstern", 257)
           << Track("Lohengrin: Treulich gefuert ziehet dahnin", 294)
           << Track("Lohengrin: In fernem Land", 383)
           << Track("Die Meistersinger von Nuernberg: Overture", 543)
           << Track("Die Meistersinger von Nuernberg: Verachtet mir "
                    "die Meister nicht", 200)
           << Track("Die Meistersinger von Nuernberg: Ehrt eure "
                    "deutschen Meister", 112)
           << Track("Goetterdaemmerung: Funeral Music", 469)
           << Track("Tristan und Isolde: Mild und leise, wie er "
                    "laechelt", 375);
    //自定义编辑控件
    TrackEditor editor(&tracks);
    editor.resize(600, 300);
    editor.show();

    return app.exec();
}

 

 TrackEditor.h

 

#ifndef TRACKEDITOR_H
#define TRACKEDITOR_H

#include <QDialog>
#include <QList>

class QDialogButtonBox;
class QTableWidget;

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

    QString title;
    int duration;
};

class TrackEditor : public QDialog
{
    Q_OBJECT

public:
    TrackEditor(QList<Track> *tracks, QWidget *parent = 0);

    void done(int result);

private slots:
    void addTrack();

private:
    QTableWidget *tableWidget;
    QDialogButtonBox *buttonBox;
    QList<Track> *tracks;
};

#endif

 

TrackEditor.cpp

 

#include <QtGui>

#include "trackdelegate.h"
#include "trackeditor.h"

Track::Track(const QString &title, int duration)
{
    this->title = title;
    this->duration = duration;
}

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);
        //设置第0列中所有项
        tableWidget->setItem(row, 0, item0);

        QTableWidgetItem *item1
             = new QTableWidgetItem(QString::number(track.duration));
        item1->setTextAlignment(Qt::AlignRight);
        //设置第1列所有项
        tableWidget->setItem(row, 1, item1);
    }
    //根据委托的SizeHint,重新设置视图大小
    tableWidget->resizeColumnToContents(0);

    buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                     | QDialogButtonBox::Cancel);
    QPushButton *addTrackButton = buttonBox->addButton(tr("&Add Track"),
            QDialogButtonBox::ActionRole);

    connect(addTrackButton, SIGNAL(clicked()), this, SLOT(addTrack()));
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(tableWidget);
    mainLayout->addWidget(buttonBox);
    setLayout(mainLayout);

    setWindowTitle(tr("Track Editor"));
}

void TrackEditor::done(int result)
{
    //ok
    if (result == QDialog::Accepted) {
        tracks->clear();
        for (int row = 0; row < tableWidget->rowCount(); ++row) {
            QString title = tableWidget->item(row, 0)->text();
            QTableWidgetItem *item = tableWidget->item(row, 1);
            int duration = item ? item->text().toInt() : 0;
            tracks->append(Track(title, duration));
        }
    }
    QDialog::done(result);
}

void TrackEditor::addTrack()
{
    //在最后新插入一行
    tableWidget->insertRow(tableWidget->rowCount());
}

 

TrackDelegate.h

 

#ifndef TRACKDELEGATE_H
#define TRACKDELEGATE_H

#include <QItemDelegate>

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 durationColumn;
};

#endif

 TrackDelegate.cpp

 

#include <QtGui>

#include "trackdelegate.h"

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

void TrackDelegate::paint(QPainter *painter,
                          const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
    //保存音轨的列
    if (index.column() == durationColumn) {
        //获得索引对应Model中的数据
        int secs = index.model()->data(index, Qt::DisplayRole).toInt();
        //设置时间格式字符串 分:秒
        QString text = QString("%1:%2")
                       .arg(secs / 60, 2, 10, QChar('0'))
                       .arg(secs % 60, 2, 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() == durationColumn) {
        //时间编辑控件
        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::setEditorData(QWidget *editor,
                                  const QModelIndex &index) const
{
    //音轨时间列
    if (index.column() == durationColumn) {
        //获得当前索引在Model中的值
        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);
    }
}
//设置Model值
void TrackDelegate::setModelData(QWidget *editor,
                                 QAbstractItemModel *model,
                                 const QModelIndex &index) const
{
    //音轨列
    if (index.column() == durationColumn) {
        //获得时间控件值
        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);
    }
}
//自定义 提交和关闭 槽函数
void TrackDelegate::commitAndCloseEditor()
{
    QTimeEdit *editor = qobject_cast<QTimeEdit *>(sender());
    //提交该控件的值 否则模型中数据不更改
    emit commitData(editor);
    //关闭该控件 可以告知委托去代开下一个控件
    emit closeEditor(editor);
}
分享到:
评论

相关推荐

    Qt开发的通讯录小程序。

    Qt开发的通讯录小程序。 学习QT时,参照网上的例子完成的小程序,主要是练习之用,不当之处在所难免...2.QSqlTableModel / QDataWidgetMapper / QItemDelegate等类的使用 3.Windows环境下摄像头的使用 4.图像的表示方法

    CustomDelegate.rar

    QT中delegate自定义委托的小例子,有注释说明和源码 简单基础部件的委托可以继承QItemDelegate,并使用这些函数的默认实现,委托编辑器可以通过使用小工具来管理编辑过程或直接处理事件来实现。 使用Delegate的原因...

    tableView.zip

    虽然为了这个目的我们设置了一个自定义的基于整数的表模型,我们可以很容易地使用QStandardItemModel来代替,因为自定义委托控制数据输入。我们构造了一个表视图来显示模型的内容,可以使用自定义的委托来进行编辑。

    TableViewDelegate.zip

    《C++ Qt开发:QItemDelegate自定义代理组件》文章课件

    自定义委托

    自定义委托类,重写QItemDelegate中的5个函数并用于模型实例.

    QTableView 中单元格添加控件的实例代码

    QTableView 中单元格添加控件的实例代码

    Delegates.7z

    QT中代理Delegates使用实例代码,可运行,多种编辑方式,有下列框,日期、QSpinBox,界面显示一看就懂!代码无buge,如果对你有帮助请给好评,有问题可以私信联系我

Global site tag (gtag.js) - Google Analytics