//model有以下几种:
// QStringListModel 存储一组字符串
// QStandardItemModel 存储任意层次结构的数据
// QDirModel 对文件系统进行封装
// QSqlQueryModel 对SQL的查询结果集进行封装
// QSqlTableModel 对SQL中的table进行封装
// QSqlRelationalTableModel 对带有foreign key的SQL table进行封装
// QSortFilterProxyModel 对另一个model执行sort and/or filter
// model中存放的每项数据都有相应的"model index",由QModelIndex类来表示。
// 每个index由三个部分构成:row,column和表明所属model的指针。对于一维的list model,column部分永远为0。
//下面是两个例子(此实例可适当改动),介绍了QStringListModel,QStandardItemModel,QDirModel用QTreeView和QListView来显示的例子
//建一个cpp文件 拷贝以下代码即可
#include <QApplication>
#include <QWidget>
#include<QTreeView>
#include<QDirModel>
#include<QHBoxLayout>
#include<QSplitter>
#include<QStringListModel>
#include<QListView>
#include<QStandardItemModel>
int main(int argc, char *argv[]) {
/*
QApplication app(argc, argv);
//以下是QStandardItemModel的简单使用,只需替换view的model为qstmodel就可以看到效果
QStandardItemModel *qstmodel=new QStandardItemModel();
QStandardItem* item1 = new QStandardItem("item1");
QStandardItem* item2 = new QStandardItem("item2");
QStandardItem* item3 = new QStandardItem("item3");
item1->appendRow(item2);
qstmodel->appendRow(item1);
qstmodel->appendRow(item3);
//以下是StringListModel的示例,只需替换view的model为mod就可以看到效果,QListView也适用
QStringList names;
names<<"a"<<"b";
QAbstractItemModel *mod=new QStringListModel(names);
//要注意的是,这里把StringListModel作为一个QAbstractItemModel来使用。这样我们就可以
//使用model中的抽象接口,而且如果将来我们用别的model代替了当前这个model,这些代码也会照样工作。
//QListView提供的列表视图足以满足当前这个model的需要了。
QDirModel *model=new QDirModel;
QTreeView *view=new QTreeView;
//这里设置Model即可
view->setModel(model);
view->setSelectionMode(QAbstractItemView::SingleSelection);
view->setAutoFillBackground(true);
//设置列是否隐藏
// view->setColumnHidden(1,true);
// view->setColumnHidden(2,true);
// view->setColumnHidden(3,true);
// widget->setAutoFillBackground(true);
QHBoxLayout *blayout=new QHBoxLayout;
blayout->addWidget(view);
blayout->addStretch();
QSplitter *splitter = new QSplitter;
splitter->setLayout(blayout);
//splitter->addWidget(view);
splitter->show();
// widget->show();
return app.exec();
*/
QApplication app(argc, argv);
QSplitter *splitter = new QSplitter;
//从缺省目录创建数据
QDirModel *model = new QDirModel;
QTreeView *tree = new QTreeView(splitter);
//配置一个view去显示model中的数据,只需要简单地调用 setModel(),并把目录model作为参数传递
tree->setModel(model);
//setRootIndex()告诉views显示哪个目录的信息,这需要提供一个model index,然后用这个
//model index去model中去获取数据,这里默认的是当前路径
tree->setRootIndex(model->index(QDir::currentPath()));
QListView *list = new QListView(splitter);
list->setModel(model);
//index()这个函数是QDirModel特有的,通过把一个目录做为参数,得到了需要的model index
//其他的代码只是窗口show出来,进入程序的事件循环就好了
list->setRootIndex(model->index(QDir::currentPath()));
splitter->setWindowTitle("Two views onto the same directory model");
splitter->show();
return app.exec();
}
void Auditctl_Win::save()
{
/* if ( !listView->firstChild() )
return;
QFile f( filename );
if ( !f.open( IO_WriteOnly ) )
return;
QTextStream t( &f );
QListViewItemIterator it( listView );
for ( ; it.current(); ++it )
for ( unsigned int i = 0; i < 50; i++ )
t << it.current()->text( i ) << "\n";
f.close();*/
}
void Auditctl_Win::load( const QString &filename )
{
//listView->clear();
QFile f( filename );
if ( !f.open( QIODevice::ReadOnly) )
return;
QTextStream t( &f );
while ( !t.atEnd() )
{
QString string = static_cast<QString>(t.readLine());
QStandardItem *item = new QStandardItem(string);
standardItemModel->appendRow(item);
listView->setModel(standardItemModel);
}
实现彩色选框
standardItemModel = new QStandardItemModel(this);
/*QStringList strList;
strList.append("string1");
strList.append("string2");
strList.append("string3");
strList.append("string4");
strList.append("string5");
strList.append("string6");
strList.append("string7");
strList << "string8";
strList += "string9";
int nCount = strList.size();
for(int i = 0; i < nCount; i++)
{
QString string = static_cast<QString>(strList.at(i));
QStandardItem *item = new QStandardItem(string);
if(i % 2 == 1)
{
QLinearGradient linearGrad(QPointF(0, 0), QPointF(200, 200));
linearGrad.setColorAt(0, Qt::darkGreen);
linearGrad.setColorAt(1, Qt::yellow);
QBrush brush(linearGrad);
item->setBackground(brush);
}
standardItemModel->appendRow(item);
}
listView->setModel(standardItemModel); */
// listView->setFixedSize(200,300); f.close();
}
QListView 類別提供樹狀的列示元件,可以顯示多欄與樹狀結構,它常與QListViewItem或者是QCheclListItem一同使用;使用 QListView最簡單的方式,就是以QListView作為樹根,並使用addColumn()方法加入欄位,然後使用QListViewItem或 QCheckListItem指定這個QListView作父節點,例如:
QListView *root; root->addColumn( "Name" ); root->addColumn( "Size" ); QListViewItem element = new QListViewItem(root, "fName", "fSize"); 上面是在QListView中加入一個QListViewItem的方法,我們也可以指定一個QListViewItem作為父節點,而子節點會自動內縮於父節點之內;通常若要加入至樹枝或樹葉的項目是有一個規律,例如HTML或是XML文件,我們會使用迴圈來加入這些項目,例如下面的程式片段加入新的屬性項目至之前的element子節點之中,成為它的子節點:
for ( int i = 0 ; i < attributes.length(); i++ ) { new QListViewItem(element, attributes.qName(i), attributes.uri(i) ); } 下面這個程式我們綜合前面的FileInfo類別與QDir類別,使用遞迴查詢出使用者家目錄下的所有目錄與檔案,但不包括隱藏檔與符號連結,我們將查詢的結果分為目錄與檔案,並使用QListView類別的樹狀結構加以顯示: #include <qapplication.h> #include <qlistview.h> #include <qdir.h> #include <qfileinfo.h> #include <qpixmap.h> void dirlist(QListViewItem*, QFileInfo*); int main(int argc, char **argv) { QApplication app(argc, argv); QListView *root = new QListView(); root->addColumn("Name"); root->addColumn("Size"); QDir d = QDir::home(); d.setFilter(QDir::Files | QDir::Dirs | QDir::NoSymLinks); d.setSorting(QDir::DirsFirst | QDir::Name); const QFileInfoList *list = d.entryInfoList(); QFileInfoListIterator it(*list); QFileInfo *fi; QListViewItem *child; while((fi = it.current()) != 0) { if ( fi->fileName() == "." || fi->fileName() == ".." ); else if(fi->isDir()) { child = new QListViewItem(root, fi->fileName().latin1(), "dir"); child->setPixmap(0, QPixmap( "dirclosed.xpm" )); dirlist(child, fi); } else { child = new QListViewItem(root, fi->fileName().latin1(), QString::number(fi->size())); child->setPixmap(0, QPixmap( "file.xpm" )); } ++it; } app.setMainWidget(root); root->show(); return app.exec(); } void dirlist(QListViewItem *parent, QFileInfo *pfi) { QDir d; d.setPath(pfi->filePath()); d.setFilter(QDir::Files | QDir::Dirs | QDir::NoSymLinks); d.setSorting(QDir::DirsFirst | QDir::Name); const QFileInfoList *list = d.entryInfoList(); QFileInfoListIterator it(*list); QFileInfo *fi; QListViewItem *child; while((fi = it.current()) != 0) { if ( fi->fileName() == "." || fi->fileName() == ".." ); else if(fi->isDir()) { child = new QListViewItem(parent, fi->fileName().latin1(), "dir"); child->setPixmap(0, QPixmap("dirclosed.xpm" )); dirlist(child, fi); } else { child = new QListViewItem(parent, fi->fileName().latin1(), QString::number(fi->size())); child->setPixmap(0, QPixmap("file.xpm" )); } ++it; } } QListView本身的使用基本上很簡單,這個程式本身反而是遞迴查詢的部份要注意,其中我們查詢到的".."與"."並不作任何的處理,而若查詢到是目錄,就將之加入QListView樹狀結構中,然後以該目錄名稱作基礎,再次呼叫dirlist()進行遞迴查詢。 為了分辨是目錄或檔案,我們簡單的使用兩個圖案作區別,您也可以進一步配合事件處理,讓目錄的圖案在按下後,會有開啟與關閉的差別,這就請自己試試看吧! 下圖是程式執行時的畫面: |