C++数据模型怎么应用在QML委托代理机制中(C++,qml,开发技术)

时间:2024-05-04 21:57:30 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

本文小编为大家详细介绍“C++数据模型怎么应用在QML委托代理机制中”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++数据模型怎么应用在QML委托代理机制中”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

定义数据模型

定义的C++数据模型和Qt-Widget中定义的数据模型相同。模型主要用来存储本地图片的ID的对应的图片地址。

实现如下:

//picturemodel.h#ifndefPICTUREMODEL_H#definePICTUREMODEL_H#include<memory>#include<vector>#include<QAbstractListModel>#include<QUrl>classPicture{public:Picture(constQString&filePath=""){mPictureUrl=QUrl::fromLocalFile(filePath);}Picture(constQUrl&fileUrl){mPictureUrl=fileUrl;}intpictureId()const{returnmPictureId;}voidsetPictureId(intpictureId){mPictureId=pictureId;}QUrlpictureUrl()const{returnmPictureUrl;}voidsetPictureUrl(constQUrl&pictureUrl){mPictureUrl=pictureUrl;}private:intmPictureId;//图片IDQUrlmPictureUrl;//图片的地址};classPictureModel:publicQAbstractListModel{Q_OBJECTpublic://自定义每个元素的数据类型enumRoles{UrlRole=Qt::UserRole+1,FilePathRole};PictureModel(QObject*parent=0);//向数据模型中添加单个数据QModelIndexaddPicture(constPicture&picture);Q_INVOKABLEvoidaddPictureFromUrl(constQUrl&fileUrl);//模型的行数introwCount(constQModelIndex&parent=QModelIndex())constoverride;//获取某个元素的数据QVariantdata(constQModelIndex&index,introle)constoverride;//删除某几行数据Q_INVOKABLEboolremoveRows(introw,intcount,constQModelIndex&parent=QModelIndex())override;//每个元素类别的名称QHash<int,QByteArray>roleNames()constoverride;//加载用户图片Q_INVOKABLEvoidloadPictures();//清空模型的中的数据,但不移除本地文件数据voidclearPictures();publicslots://清空模型,删除本地文件中的数据voiddeleteAllPictures();private:voidresetPictures();boolisIndexValid(constQModelIndex&index)const;private:std::unique_ptr<std::vector<std::unique_ptr<Picture>>>mPictures;};#endif//PICTUREMODEL_H
//picturemodel.cpp#include"picturemodel.h"#include<QUrl>usingnamespacestd;PictureModel::PictureModel(QObject*parent):QAbstractListModel(parent),mPictures(newvector<unique_ptr<Picture>>()){}QModelIndexPictureModel::addPicture(constPicture&picture){introws=rowCount();beginInsertRows(QModelIndex(),rows,rows);unique_ptr<Picture>newPicture(newPicture(picture));mPictures->push_back(move(newPicture));endInsertRows();returnindex(rows,0);}voidPictureModel::addPictureFromUrl(constQUrl&fileUrl){addPicture(Picture(fileUrl));}intPictureModel::rowCount(constQModelIndex&/*parent*/)const{returnmPictures->size();}QVariantPictureModel::data(constQModelIndex&index,introle)const{if(!isIndexValid(index)){returnQVariant();}constPicture&picture=*mPictures->at(index.row());switch(role){//展示数据为图片的名称caseQt::DisplayRole:returnpicture.pictureUrl().fileName();break;//图片的URLcaseRoles::UrlRole:returnpicture.pictureUrl();break;//图片地址caseRoles::FilePathRole:returnpicture.pictureUrl().toLocalFile();break;default:returnQVariant();}}boolPictureModel::removeRows(introw,intcount,constQModelIndex&parent){if(row<0||row>=rowCount()||count<0||(row+count)>rowCount()){returnfalse;}beginRemoveRows(parent,row,row+count-1);intcountLeft=count;while(countLeft--){constPicture&picture=*mPictures->at(row+countLeft);}mPictures->erase(mPictures->begin()+row,mPictures->begin()+row+count);endRemoveRows();returntrue;}QHash<int,QByteArray>PictureModel::roleNames()const{QHash<int,QByteArray>roles;roles[Qt::DisplayRole]="name";roles[Roles::FilePathRole]="filepath";roles[Roles::UrlRole]="url";returnroles;}voidPictureModel::loadPictures(){beginResetModel();endResetModel();}voidPictureModel::clearPictures(){resetPictures();}voidPictureModel::resetPictures(){beginResetModel();mPictures.reset(newvector<unique_ptr<Picture>>());endResetModel();return;}voidPictureModel::deleteAllPictures(){resetPictures();}boolPictureModel::isIndexValid(constQModelIndex&index)const{if(index.row()<0||index.row()>=rowCount()||!index.isValid()){returnfalse;}returntrue;}

定义C++数据模型的时候有几点需要注意:

1.如果想在QML中访问模型的某个方法的话需要在方法声明的时候添加Q_INVOKABLE宏

Q_INVOKABLEvoidaddPictureFromUrl(constQUrl&fileUrl);

2.在QML中通过每个元素类别的名称来进行访问,对应的类别名称的定义如下:

QHash<int,QByteArray>PictureModel::roleNames()const{QHash<int,QByteArray>roles;roles[Qt::DisplayRole]="name";roles[Roles::FilePathRole]="filepath";roles[Roles::UrlRole]="url";returnroles;}

定义图片缓存器

由于数据模型中包含图片数据,为了便于在QML中访问图片资源,添加图片缓存器。缓存器继承自QQuickImageProvider。对应的实现如下所示:

//PictureImageProvider.h#ifndefPICTUREIMAGEPROVIDER_H#definePICTUREIMAGEPROVIDER_H#include<QQuickImageProvider>#include<QCache>classPictureModel;classPictureImageProvider:publicQQuickImageProvider{public:staticconstQSizeTHUMBNAIL_SIZE;PictureImageProvider(PictureModel*pictureModel);//请求图片QPixmaprequestPixmap(constQString&id,QSize*size,constQSize&requestedSize)override;//获取缓存QPixmap*pictureFromCache(constQString&filepath,constQString&pictureSize);private://数据模型PictureModel*mPictureModel;//图片缓存容器QCache<QString,QPixmap>mPicturesCache;};#endif//PICTUREIMAGEPROVIDER_H
//PictureImageProvider.cpp#include"PictureImageProvider.h"#include"PictureModel.h"//全屏显示constQStringPICTURE_SIZE_FULL="full";//缩略显示constQStringPICTURE_SIZE_THUMBNAIL="thumbnail";//缩略显示的尺寸constQSizePictureImageProvider::THUMBNAIL_SIZE=QSize(350,350);PictureImageProvider::PictureImageProvider(PictureModel*pictureModel):QQuickImageProvider(QQuickImageProvider::Pixmap),mPictureModel(pictureModel),mPicturesCache(){}QPixmapPictureImageProvider::requestPixmap(constQString&id,QSize*/*size*/,constQSize&/*requestedSize*/){QStringListquery=id.split('/');if(!mPictureModel||query.size()<2){returnQPixmap();}//第几个图片数据introwId=query[0].toInt();//显示模式是缩略显示还是全屏显示QStringpictureSize=query[1];QUrlfileUrl=mPictureModel->data(mPictureModel->index(rowId,0),PictureModel::Roles::UrlRole).toUrl();return*pictureFromCache(fileUrl.toLocalFile(),pictureSize);}QPixmap*PictureImageProvider::pictureFromCache(constQString&filepath,constQString&pictureSize){QStringkey=QStringList{pictureSize,filepath}.join("-");//不包含图片的时候创建新的缓存QPixmap*cachePicture=nullptr;if(!mPicturesCache.contains(key)){QPixmaporiginalPicture(filepath);if(pictureSize==PICTURE_SIZE_THUMBNAIL){cachePicture=newQPixmap(originalPicture.scaled(THUMBNAIL_SIZE,Qt::KeepAspectRatio,Qt::SmoothTransformation));}elseif(pictureSize==PICTURE_SIZE_FULL){cachePicture=newQPixmap(originalPicture);}mPicturesCache.insert(key,cachePicture);}//包含的时候直接访问缓存else{cachePicture=mPicturesCache[key];}returncachePicture;}

初始化QML引擎

在QML引擎初始化的时候添加对应的数据模型和图片缓存器,对应的实现如下:

#include<QGuiApplication>#include<QQmlApplicationEngine>#include<QQmlContext>#include"picturemodel.h"#include"PictureImageProvider.h"intmain(intargc,char*argv[]){QGuiApplicationapp(argc,argv);PictureModelpictureModel;QQmlApplicationEngineengine;QQmlContext*context=engine.rootContext();//添加数据模型和图片缓存器context->setContextProperty("pictureModel",&pictureModel);//图片Provider的ID是"pictures"engine.addImageProvider("pictures",newPictureImageProvider(&pictureModel));engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if(engine.rootObjects().isEmpty())return-1;returnapp.exec();}

QML中访问C++数据模型

在QML中通过数据模型访问数据,通过图片缓存器访问对应的图片资源,对应的实现如下:

//main.qmlimportQtQuick2.8importQtQuick.Dialogs1.2importQtQuick.Controls2.0importQtQuick.Layouts1.3importQtQuick.Window2.2Window{visible:truewidth:640height:480title:qsTr("QML-MVC")RowLayout{id:tool_layout//添加图片的按钮ToolButton{background:Image{source:"qrc:/image/photo-add.svg"}onClicked:{dialog.open()}}//删除图片的按钮ToolButton{background:Image{source:"qrc:/image/photo-delete.svg"}onClicked:{pictureModel.removeRows(pictureListView.currentIndex,1)}}}//网格视图GridView{id:pictureListViewmodel:pictureModelanchors.top:tool_layout.bottomwidth:parent.width;height:parent.height-tool_layout.heightanchors.leftMargin:10anchors.rightMargin:10cellWidth:300cellHeight:230//对应的每个元素的代理delegate:Rectangle{width:290height:200color:GridView.isCurrentItem?"#4d9cf8":"#ffffff"//选中颜色设置Image{id:thumbnailanchors.fill:parentfillMode:Image.PreserveAspectFitcache:false//通过缓存器访问图片//image://pictures/访问器的ID//index+"/thumbnail"图片索引和显示模式source:"image://pictures/"+index+"/thumbnail"}//访问图片的名称Text{height:30anchors.top:thumbnail.bottomtext:namefont.pointSize:16anchors.horizontalCenter:parent.horizontalCenter}//鼠标点击设置当前索引MouseArea{anchors.fill:parentonClicked:{pictureListView.currentIndex=index;}}}}//图片选择窗口FileDialog{id:dialogtitle:"SelectPictures"folder:shortcuts.picturesonAccepted:{varpictureUrl=dialog.fileUrlpictureModel.addPictureFromUrl(pictureUrl)dialog.close()}}}

显示效果如下图所示:

C++数据模型怎么应用在QML委托代理机制中

读到这里,这篇“C++数据模型怎么应用在QML委托代理机制中”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。

本文:C++数据模型怎么应用在QML委托代理机制中的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:uniapp小程序视图容器cover-view怎么使用下一篇:

9 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18