Qt学习之路——QFileSystemModel&QStandardItemModel

August 12th, 2013 by JasonLe's Tech Leave a reply »

今天学习了QFileSystemModel,这个Model与QStringListModel类似,但是更加灵活。
总的功能与QDirModel差不多Qt 内置了两种模型:QStandardItemModel 和 QFileSystemModel。QStandardItemModel 是一种多用途的模型,能够让列表、表格、树等视图显示不同的数据结构。这种模型会将数据保存起来。试想一下,列表和表格所要求的数据结构肯定是不一样的:前者是一维的,后者是二维的。因此,模型需要保存有实际数据,当视图是列表时,以一维的形式提供数据;当视图是表格时,以二维的形式提供数据。QFileSystemModel 则是另外一种方式。它的作用是维护一个目录的信息。因此,它不需要保存数据本身,而是保存这些在本地文件系统中的实际数据的一个索引。我们可以利用 QFileSystemModel 显示文件系统的信息、甚至通过模型来修改文件系统。
首先我来说一下QFileSystemModel。先看一下我设计的软件效果:
Screenshot
这个demon的功能就是点击左边的treeview类型的Dir,然后显示在右边的listiew的文件。这个小demon的难度不大,困难在于理解信号槽用法,
当我们点击左边后,引发SIGNAL()clicked(index),然后发射到void MainWindow::on_treeView_clicked(const QModelIndex &index)中
然后我们要做的就是获取这个index的绝对路径,然后设置右边的index,通过创建一个包含绝对路径的index即可。ui->listView->setRootIndex(filemodel->setRootPath(path))

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    dirmodel = new QFileSystemModel(this);
    dirmodel->setRootPath("/home/lzz/");
    dirmodel->setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
    ui->treeView->setModel(dirmodel);

    filemodel = new QFileSystemModel(this);
    filemodel->setFilter(QDir::NoDotAndDotDot | QDir::Files);
   // filemodel->setRootPath("/home/lzz/");

    ui->listView->setModel(filemodel);

}
void MainWindow::on_treeView_clicked(const QModelIndex &index)
{
    QString path = dirmodel->fileInfo(index).absoluteFilePath();
    ui->listView->setRootIndex(filemodel->setRootPath(path));
}

还有一个就是QStandardItemModel,这个类型非常灵活,可以将一个tableview编辑出非常复杂的界面,比如在一个单元格嵌入其他控件,现在我插入了一个spinbox。
Screenshot-1
构造函数和QFileSystemModel差不多,不同的是,设置每一个item的类型。然后将delegate设置进去即可。

    model = new QStandardItemModel(4,4,this);
    mydelegate = new Delegate(this);

    for(int row = 0 ; row < 4 ; row++)     {         QModelIndex index = model->index(row,3,QModelIndex());
        model->setData(index,0);
    }
    ui->tableView->setModel(model);
    ui->tableView->setItemDelegate(mydelegate);

mydelegate做法是要创建一个delegate的类,然后继承QItemDelegate。重写几个纯虚函数。
下面是一些官方文档

PS:http://qt-project.org/doc/qt-5.0/qtwidgets/qitemdelegate.html#details
Only the standard editing functions for widget-based delegates are reimplemented here:
createEditor() returns the widget used to change data from the model and can be reimplemented to customize editing behavior.
setEditorData() provides the widget with data to manipulate.
updateEditorGeometry() ensures that the editor is displayed correctly with respect to the item view.
setModelData() returns updated data to the model.
然后我实现这四个函数:

QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSpinBox *spinbox = new QSpinBox(parent);
    spinbox->setMinimum(0);
    spinbox->setMaximum(100);
    return spinbox;//返回一个spinbox
}

void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    int value = index.model()->data(index,Qt::EditRole).toInt();
    QSpinBox *spinbox = static_cast<QSpinBox *> (editor);
    spinbox->setValue(value);
}

void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QSpinBox *spinbox = static_cast<QSpinBox *> (editor);
    spinbox->interpretText();
    int value = spinbox->value();
    model->setData(index,value,Qt::EditRole);
}

void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    editor->setGeometry(option.rect);//调整位置
}

另外贴出要重写的纯虚函数参数列表,以及每个函数的功能。

QWidget * QItemDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const [virtual]

Reimplemented from QAbstractItemDelegate::createEditor().
Returns the widget used to edit the item specified by index for editing. The parent widget and style option are used to control how the editor widget appears.

void QItemDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const [virtual]

Reimplemented from QAbstractItemDelegate::setEditorData().
Sets the data to be displayed and edited by the editor from the data model item specified by the model index.

void QItemDelegate::updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const [virtual]

Reimplemented from QAbstractItemDelegate::updateEditorGeometry().
Updates the editor for the item specified by index according to the style option given.

void QItemDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const [virtual]

Reimplemented from QAbstractItemDelegate::setModelData().
Gets data from the editor widget and stores it in the specified model at the item index.
The default implementation gets the value to be stored in the data model from the editor widget’s user property.