• 4059阅读
  • 0回复

如何在tableview单元格中呈现自定义控件并可编辑 [复制链接]

上一主题 下一主题
离线夏惠霞
 

只看楼主 倒序阅读 楼主  发表于: 2016-03-23
hello,不好意思,刚看到这里还有专门的插入代码工具,之前的那个帖子代码没有用这个工具,太乱了。重复一下我的问题是这样的:有一个数据源,假设我用vectcor容器来盛放它。数据源中的每一个数据项包括三个类容:一张图片,一个图片名字,一个复选框用于记录用户是否选择这张图片。这三项类容我打算放到一个frame上,分别用一个qlabel, 一个qlabel,一个qcheckbox来呈现。现在,我需要把每一个数据项都呈现到tableview的单元格上,也就是说我想把frame放到单元格中,并且单元格可以编辑。比如说,我点击某个单元格,然后单元格的图片就被选中了,复选框自动勾上勾。
我的问题是:当tableview第一次呈现出来的时候,我需要它能够加载数据源中的数据到每个单元格中,那么我该怎么做?是重写model的data()函数来实现这个功能,还是重写delegate的setEditData()函数?

如果热心的你不嫌麻烦的话,我贴出了我的代码,大致展示一下我的思路(我的代码还是有问题的,只能显示一列单元格,而且frame不显示):
这是自定义frame的头文件
  1. class thumbnailFrame : public QFrame
  2. {
  3. public:
  4.     explicit thumbnailFrame(DataSource *datasource, QWidget *parent = 0);
  5.     ~thumbnailFrame();
  6.     void setThumbnailSize();
  7.     QSize getThumbnailSize();
  8.     void setDataSource(DataSource *dataSource);
  9.     DataSource* getDataSource();
  10.     void setCheckBox(bool save);
  11.     QCheckBox * getCheckBox();
  12.     void setImgShowLabel(QPixmap pixmap);
  13.     QLabel *getImgShowLabel();
  14.     void setNameLable(QString name);
  15.     QLabel *getNameLabel();
  16. private:
  17.     Ui::thumbnailFrame *ui;
  18.     QSize thumbnailSize;  //等于数据源中的iconsize
  19.     DataSource *dataSource; //数据源规格
  20. };
这是自定义frame实现:
  1. thumbnailFrame::thumbnailFrame(DataSource *datasource, QWidget *parent) :
  2.     QFrame(parent),
  3.     ui(new Ui::thumbnailFrame)
  4. {
  5.     ui->setupUi(this);
  6.     ui->imgNameLabel->setAlignment(Qt::AlignCenter); //图片名居
  7.     setDataSource(datasource);
  8. }
  9. thumbnailFrame::~thumbnailFrame(){
  10.     delete ui;
  11.     delete dataSource;
  12. }
  13. void thumbnailFrame::setThumbnailSize(){
  14.     int icon_width = this->dataSource->getIconSize().width();
  15.     int icon_height = this->dataSource->getIconSize().height();
  16.     ui->imgShowLabel->resize(icon_width, icon_height);
  17.     int name_width = this->dataSource->getNameLabelSize().width();
  18.     int name_height = this->dataSource->getNameLabelSize().height();
  19.     ui->imgNameLabel->resize(name_width, name_height);
  20.     int space_width = this->dataSource->getSpace().width();
  21.     int space_height = this->dataSource->getSpace().height();
  22.     int frame_width = icon_width + space_width;
  23.     int frame_height = icon_height + name_height + space_height;
  24.     this->thumbnailSize = QSize(frame_width, frame_height);
  25. }
  26. QSize thumbnailFrame::getThumbnailSize(){
  27.     return thumbnailSize;
  28. }
  29. void thumbnailFrame::setDataSource(DataSource* dataSource){
  30.     this->dataSource = dataSource;
  31. }
  32. DataSource* thumbnailFrame::getDataSource(){
  33.     return this->dataSource;
  34. }
  35. void thumbnailFrame::setCheckBox(bool save){
  36.     Qt::CheckState state;
  37.     if(save == true){
  38.         state = Qt::Checked;
  39.     }else{
  40.         state = Qt::Unchecked;
  41.     }
  42.     this->ui->checkBox->setCheckState(state);
  43. }
  44. QCheckBox *thumbnailFrame::getCheckBox(){
  45.     return this->ui->checkBox;
  46. }
  47. void thumbnailFrame::setNameLable(QString name){
  48.     this->ui->imgNameLabel->setText(name);
  49. }
  50. QLabel * thumbnailFrame::getNameLabel(){
  51.     return this->ui->imgNameLabel;
  52. }
  53. void thumbnailFrame::setImgShowLabel(QPixmap pixmap){
  54.     this->ui->imgShowLabel->setPixmap(pixmap);
  55. }

这是数据源头文件:
  1. class DataSource : public QObject
  2. {
  3.     Q_OBJECT
  4. public:
  5.     DataSource(QObject *parent = 0);
  6.     ~ DataSource();
  7.     void setName(QString name);
  8.     QString getName();
  9.     void setPixMap(QPixmap *pixMap);
  10.     QPixmap *getPixMap();
  11.     void setIconSize(QSize size);
  12.     QSize getIconSize();
  13.     void setNameLabelSize(QSize size);
  14.     QSize getNameLabelSize();
  15.     void setCheckboxSize(QSize size);
  16.     QSize getCheckboxSize();
  17.     void setSpace(QSize size);
  18.     QSize getSpace();
  19.     void setSave(bool save);
  20.     bool getSave();
  21. private:
  22.     QString name;
  23.     QPixmap *pixMap;
  24.     bool save;
  25.     QSize iconSize;  //缩略图尺寸
  26.     QSize nameLabelSize; //展现文件名的lable尺寸,宽度最好和缩略图宽度相等
  27.     QSize checkboxSize; //复选框尺寸
  28.     QSize space; //间距
  29. };
这是数据源实现:
  1. DataSource::DataSource(QObject *parent):QObject(parent)
  2. {
  3.     this->name = "";
  4.     this->pixMap = NULL;
  5.     this->save = false;
  6. }
  7. DataSource::~DataSource(){
  8.     delete pixMap;
  9. }
  10. void DataSource::setName(QString name){
  11.     this->name = name;
  12. }
  13. QString DataSource::getName(){
  14.     return this->name;
  15. }
  16. void DataSource::setPixMap(QPixmap *pixMap){
  17.     this->pixMap = pixMap;
  18. }
  19. QPixmap *DataSource::getPixMap(){
  20.     return this->pixMap;
  21. }
  22. void DataSource::setIconSize(QSize size){
  23.     this->iconSize = size;
  24. }
  25. QSize DataSource::getIconSize(){
  26.     return this->iconSize;
  27. }
  28. void DataSource::setNameLabelSize(QSize size){
  29.     this->nameLabelSize = size;
  30. }
  31. QSize DataSource::getNameLabelSize(){
  32.     return this->nameLabelSize;
  33. }
  34. void DataSource::setCheckboxSize(QSize size){
  35.     this->checkboxSize = size;
  36. }
  37. QSize DataSource::getCheckboxSize(){
  38.     return this->checkboxSize;
  39. }
  40. void DataSource::setSpace(QSize size){
  41.     this->space = size;
  42. }
  43. QSize DataSource::getSpace(){
  44.     return this->space;
  45. }
  46. void DataSource::setSave(bool save){
  47.     this->save = save;
  48. }
  49. bool DataSource::getSave(){
  50.     return this->save;
  51. }

这是我实现的自定义delegate,继承自qitemdelegate

  1. class ThumbnailDelegate: public QItemDelegate
  2. {
  3.     Q_OBJECT
  4. public:
  5.     explicit ThumbnailDelegate(DataSource *dataSource, QObject *parent = 0);
  6.     ~ThumbnailDelegate();
  7.     void setDataSource(DataSource *datasource);
  8.     DataSource* getDataSource();
  9.     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const;
  10. //    bool editorEvent(QEvent *event,
  11. //                     QAbstractItemModel *model,
  12. //                     const QStyleOptionViewItem &option,
  13. //                     const QModelIndex &index);
  14.     //返回一个编辑控件,用来编辑指定项的数据
  15.     virtual QWidget *createEditor(QWidget *parent,
  16.                           const QStyleOptionViewItem &option,
  17.                           const QModelIndex &index)const;
  18.     //将Model中数据赋值到控件上
  19.     virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
  20.     //设定模型数据,根据指定项中对应编辑控件的数据
  21.     virtual void setModelData(QWidget *editor, QAbstractItemModel *model,
  22.                       const QModelIndex &index) const;
  23.     //更新编辑框几何形状
  24.     virtual void updateEditorGeometry(QWidget *editor,
  25.             const QStyleOptionViewItem &option, const QModelIndex &index) const;
  26. private:
  27.     QPixmap pixMap;
  28.     thumbnailFrame *frame;
  29.     DataSource *datasource; //数据源样例
  30. };
  31. ThumbnailDelegate::ThumbnailDelegate(DataSource *dataSource, QObject *parent):
  32.     QItemDelegate(parent){
  33.     setDataSource(dataSource);
  34. }
  35. ThumbnailDelegate::~ThumbnailDelegate(){
  36.     delete datasource;
  37. }
  38. void ThumbnailDelegate::setDataSource(DataSource *datasource){
  39.     this->datasource = datasource;
  40. }
  41. DataSource* ThumbnailDelegate::getDataSource(){
  42.     return this->datasource;
  43. }
  44. QWidget * ThumbnailDelegate::createEditor(QWidget *parent,
  45.                                           const QStyleOptionViewItem &option,
  46.                                           const QModelIndex &index)const{
  47.     thumbnailFrame *frame = new thumbnailFrame(this->datasource, parent);
  48.     frame->setThumbnailSize();
  49.     return frame;
  50. }
  51. //将Model中数据赋值到控件上
  52. void ThumbnailDelegate::setEditorData(QWidget *editor,
  53.                                     const QModelIndex &index) const{
  54.     //返回该索引的模型,继而返回该模型中此索引的编辑角色数据
  55.     QVariant var = index.model()->data(index);
  56.     DataSource *source = var.value<DataSource*>();
  57.     QString name = source->getName();
  58.     QPixmap *pixMap = source->getPixMap();
  59.     bool save = source->getSave();
  60.     //给控件赋值
  61.     thumbnailFrame *frame = static_cast<thumbnailFrame*>(editor);
  62.     frame->setDataSource(this->datasource);
  63.     frame->setThumbnailSize(); //设置frame上的各个控价大小
  64.     frame->setCheckBox(save);
  65.     frame->setImgShowLabel(*pixMap);
  66.     frame->setNameLable(name);
  67. }
  68. void ThumbnailDelegate::setModelData(QWidget *editor,
  69.                                      QAbstractItemModel *model,
  70.                                      const QModelIndex &index) const
  71. {
  72.     thumbnailFrame *frame = static_cast<thumbnailFrame*>(editor);
  73.     bool save;
  74.     if(frame->getCheckBox()->checkState() == Qt::Checked){
  75.         save = true;
  76.     }else{
  77.         save = false;
  78.     }
  79.     QString name = frame->getDataSource()->getName();
  80.     QPixmap *pixMap = frame->getDataSource()->getPixMap();
  81.     QSize iconSize = frame->getDataSource()->getIconSize();
  82.     QSize nameLabelSize = frame->getDataSource()->getNameLabelSize();
  83.     QSize checkboxSize = frame->getDataSource()->getCheckboxSize();
  84.     QSize space = frame->getDataSource()->getSpace();
  85.     DataSource *data = new DataSource();
  86.     data->setPixMap(pixMap);
  87.     data->setName(name);
  88.     data->setIconSize(iconSize);
  89.     data->setCheckboxSize(checkboxSize);
  90.     data->setSpace(space);
  91.     data->setNameLabelSize(nameLabelSize);
  92.     data->setSave(save);
  93.     //设置模型的数据
  94.     QVariant var;
  95.     var.setValue(data);
  96.     model->setData(index, var);
  97. }
  98. void ThumbnailDelegate::updateEditorGeometry(QWidget *editor,
  99.                                              const QStyleOptionViewItem &option,
  100.                                              const QModelIndex &index) const{
  101.     editor->setGeometry(option.rect);
  102. }
  103. void ThumbnailDelegate::paint(QPainter *painter,
  104.                               const QStyleOptionViewItem &option,
  105.                               const QModelIndex &index) const{
  106.     const QAbstractItemModel *model = index.model();
  107.     QVariant var = model->data(index);
  108.     if(var.isNull()){
  109.         var = false;
  110.         return;
  111.     }
  112.     //画图
  113.     QPixmap *pixMap = var.value<DataSource*>()->getPixMap();
  114.     QSize icon_size = var.value<DataSource*>()->getIconSize(); //图片尺寸
  115.     QSize space_size = var.value<DataSource*>()->getSpace();
  116.     QSize checkbox_size = var.value<DataSource*>()->getCheckboxSize();
  117.     QRect rect = option.rect;
  118.     int x = rect.x() + space_size.width() / 2;
  119.     int y = rect.y() + space_size.height() / 2;
  120.     painter->drawPixmap(x, y, pixMap->scaled((var.value<DataSource*>()->getIconSize())));
  121.     //画图片名称
  122.     QString name = var.value<DataSource*>()->getName();
  123.     int x2 = x;
  124.     int y2 = y + icon_size.height();
  125.     painter->drawText(x2, y2, name);
  126.     painter->end();
  127.     //画复选框
  128.     bool checked = var.value<DataSource*>()->getSave();
  129.     //按钮风格选项
  130.     QStyleOptionButton *checkBoxOption = new QStyleOptionButton();
  131.     checkBoxOption->state |= QStyle::State_Enabled;
  132.     if(checked){
  133.         checkBoxOption->state |= QStyle::State_On;
  134.     }else{
  135.         checkBoxOption->state |= QStyle::State_Off;
  136.     }
  137.     int x3 = x + icon_size.width() - checkbox_size.width();
  138.     int y3 = y;
  139.     QRect rect2(x3, y3, checkbox_size.width(), checkbox_size.height());
  140.     checkBoxOption->rect = rect2;
  141.     QApplication::style()->drawControl(QStyle::CE_CheckBox,checkBoxOption,painter);
  142. }
这是我自定义的model,继承自tablemodel:
  1. class ThumbnailModel: public QAbstractTableModel
  2. {
  3. public:
  4.     ThumbnailModel(DataSource *dataSource, int tableView_h, int tableView_w, QObject *parent = 0);
  5.     ~ThumbnailModel();
  6.     void setVectorDataSource(QVector<DataSource*> vectorDataSource);
  7.     int rowCount(const QModelIndex &parent) const;
  8.     int columnCount(const QModelIndex &parent) const;
  9.     QVariant data(const QModelIndex &index, int role) const;
  10.     QVariant headerData(int section, Qt::Orientation orientation, int role) const;
  11.     void setTableView_width(int width);
  12.     int getTableView_width();
  13.     void setTableView_height(int height);
  14.     int getTableView_height();
  15.     void setDataSource(DataSource *dataSource);
  16.     DataSource *getDataSource();
  17. private:
  18.     QVector<DataSource*> vectorDataSource;  //底层数据
  19.     int tableView_width;
  20.     int tableView_heigth;
  21.     DataSource *dataSource; //底层数据单个范例
  22. };
  23. ThumbnailModel::ThumbnailModel(DataSource *dataSource, int tableview_h, int tableview_w, QObject *parent):
  24.     QAbstractTableModel(parent)
  25. {
  26.     setDataSource(dataSource);
  27.     setTableView_height(tableview_h);
  28.     setTableView_width(tableview_w);
  29. }
  30. ThumbnailModel::~ThumbnailModel(){
  31.     delete dataSource;
  32. }
  33. void ThumbnailModel::setVectorDataSource(QVector<DataSource*> vectorDataSource){
  34.     this->vectorDataSource = vectorDataSource;
  35. }
  36. void ThumbnailModel::setTableView_width(int width){
  37.     this->tableView_width = width;
  38. }
  39. int ThumbnailModel::getTableView_width(){
  40.     return this->tableView_width;
  41. }
  42. void ThumbnailModel::setTableView_height(int height){
  43.     this->tableView_heigth = height;
  44. }
  45. int ThumbnailModel::getTableView_height(){
  46.     return this->tableView_heigth;
  47. }
  48. void ThumbnailModel::setDataSource(DataSource *datasource){
  49.     this->dataSource = datasource;
  50. }
  51. DataSource* ThumbnailModel::getDataSource(){
  52.     return this->dataSource;
  53. }
  54. int ThumbnailModel::rowCount(const QModelIndex &/*parent*/) const{
  55.     int frame_height = this->dataSource->getIconSize().height() +
  56.                        this->dataSource->getNameLabelSize().height() +
  57.                        this->dataSource->getSpace().height();
  58.     int rowCount = this->tableView_heigth / frame_height;
  59.     return rowCount;
  60. }
  61. int ThumbnailModel::columnCount(const QModelIndex &/*parent*/) const{
  62.     int space_width = this->dataSource->getSpace().width();
  63.     int other_width = this->dataSource->getIconSize().width() > this->dataSource->getNameLabelSize().width()?
  64.                 this->dataSource->getIconSize().width():
  65.                 this->dataSource->getNameLabelSize().width();
  66.     int frame_width = space_width + other_width;
  67.     int columnCount = this->tableView_width / frame_width;
  68.     return columnCount;
  69. }
  70. QVariant ThumbnailModel::data(const QModelIndex &index, int role) const{
  71.     if(!index.isValid()){
  72.         return QVariant();
  73.     }
  74.     int row = index.row();
  75.     int col = index.column();
  76.     int index_ = row * this->columnCount(QModelIndex()) + col - 1;
  77.     QVariant var;
  78.     var.setValue((void *)this->vectorDataSource.at(index_));
  79.     return var;
  80. }
  81. QVariant ThumbnailModel::headerData(int section, Qt::Orientation /* orientation */, int role) const{
  82.     if(role != Qt::DisplayRole)
  83.         return QVariant();
  84.     return section;
  85. }


快速回复
限100 字节
 
上一个 下一个