`
qimo601
  • 浏览: 3449582 次
  • 性别: 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);
}
分享到:
评论

相关推荐

    自定义gantt 甘特图使用例子

    2. **MainWindow.cpp**: 主窗口类的实现,通常包含用户界面的主要元素,如菜单、工具栏、视图等。在这个例子中,主窗口可能有一个专门用来展示Gantt图的区域,用户可以通过这个窗口与Gantt图交互,如添加、删除、...

    Qt自定义代理,委托,自定义开关

    在Qt中,代理(QItemDelegate)和委托(QSortFilterProxyModel)是两个关键概念,它们对于实现复杂的数据显示和交互功能至关重要。本文将深入探讨这两个概念,并结合自定义开关控件进行讲解。 首先,让我们了解...

    Delegates.7z

    `QItemDelegate`是QT提供的一种基础委托类,我们可以基于它进行扩展,以适应各种特定的需求。 在"Delegates.7z"这个压缩包中,提供的是一系列使用`QT`中的`Delegates`的实例代码。这些代码涵盖了多种编辑方式,包括...

    QT 自定义混合控件——基于View/Model/Delegate的QTableView/QTreewidget/Combobox实现

    在本项目"QT自定义混合控件——基于View/Model/Delegate的QTableView/QTreewidget/Combobox实现"中,我们将深入探讨如何利用QT库中的核心组件构建一个强大的数据展示和交互界面。 首先,我们要理解View/Model/...

    QT自定义委托类代理类.rar

    2. 实现`createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index)`,创建自定义编辑器控件,比如日期选择器、颜色选择器等。 3. 覆盖`setEditorData(QWidget *editor, const ...

    TableViewDelegate.zip

    2. `sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const`:返回一个表示项大小的`QSize`,用于确定表格单元格的尺寸。 3. `createEditor(QWidget *parent, const QStyleOptionViewItem...

    Qt开发的通讯录小程序。

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

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

    在Qt框架中,`QTableView`是用于展示二维表格数据的控件,它基于`QAbstractItemView`类。在一些复杂的应用场景中,我们可能需要在`QTableView`的单元格内添加自定义的控件,比如按钮、下拉框等,以提供更丰富的交互...

    Qt学习之路2

    文档会介绍如何使用QAbstractItemModel、QAbstractItemView和QItemDelegate来实现MODEL/VIEW 架构。 16. **拖放**: 拖放功能是许多现代应用程序的必备功能。Qt中的拖放功能允许在应用程序内部以及应用程序与操作...

    CustomDelegate.rar

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

    C++ Qt设计模式 第2版(中文版)

    2. **工厂模式**:Qt的QObject类提供了动态对象创建的能力,通过QMetaObject和QMetaMethod,可以实现基于元对象系统的工厂模式,动态创建和调用不同类型的对象。 3. **观察者模式**:Qt的信号与槽机制是观察者模式...

    自定义QHeaderView控件+QTable委托

    2. 创建自定义的QItemDelegate子类,处理单元格的显示和编辑。 3. 将自定义的QHeaderView和QItemDelegate应用到QTableView上,通过`setHorizontalHeader()`和`setItemDelegate()`方法设置它们。 4. 配置QTableView的...

    QTreeView应用

    3. **排序和分页**:支持基于某一列的数据排序,以及通过代理实现分页功能。 4. **数据编辑**:默认情况下,用户可以直接点击单元格进行编辑,也可以自定义编辑行为。 代理(QItemDelegate)在模型视图架构中起到...

    Qt跨平台界面应用开发 - 王桂林老师总结的书籍

    3. **第一个QtGUI应用**:本节将会引导读者通过简单的例子创建第一个基于Qt的GUI应用程序,从而对Qt的开发环境和工具有一个初步的认识。 #### 第二章 布局管理器 1. **QHBoxLayout与QVBoxLayout**:Qt中的布局管理...

    QTableView

    ### 2. 应用自定义委托 创建了自定义委托后,我们需要将其应用到`QTableView`上: ```cpp QTableView *tableView = new QTableView; tableView-&gt;setItemDelegate(new MyCustomDelegate(tableView)); ``` ### 3. ...

    tableView.zip

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

    自定义委托

    2. **创建自定义委托类** 自定义委托通常通过继承`QItemDelegate`来实现。例如,我们可以创建一个新的类`MyCustomDelegate`,并在其中重写必要的方法。首先,在头文件中声明委托类: ```cpp class ...

    Qt ModelView 演示

    "Qt ModelView 演示"项目着重展示了`QItemDelegate`的使用,这是一个关键组件,允许我们对QTableView、QListView和QTreeView等视图组件进行自定义渲染和编辑行为。 首先,我们要理解Qt的Model/View编程模型。该模型...

    Qt之QComboBox委托

    在Qt框架中,QComboBox是一个常用的控件,用于在下拉列表中显示可选择的项目。这个控件在用户界面设计中非常常见,比如在创建一个应用时,如果...希望这个例子能帮助你理解如何在Qt中有效地利用QComboBox及其委托机制。

Global site tag (gtag.js) - Google Analytics