找回密码
 立即注册
收起左侧

如何在tableview的单元格中呈现自定控件并且可编辑

1
回复
9263
查看
[复制链接]

尚未签到

来源: 2016-3-23 21:17:57 显示全部楼层 |阅读模式
7Qter豆
是这样的:有一个数据源,假设我用vectcor容器来盛放它。数据源中的每一个数据项包括三个类容:一张图片,一个图片名字,一个复选框用于记录用户是否选择这张图片。这三项内容我打算放到一个frame上,分别用一个qlabel展示图片, 一个qlabel展示图片名,一个qcheckbox用来给用户勾选表示是否保存这张图片。现在,我需要把每一个数据项都呈现到tableview的单元格上,也就是说我想把frame放到单元格中,并且单元格可以编辑。比如说,我点击某个单元格,然后单元格的图片就被选中了,复选框自动勾上勾。
我的问题是:当tableview第一次呈现出来的时候,我需要它能够加载数据源中的数据到每个单元格中,那么我该怎么做?是重写model的data()函数来实现这个功能,还是重写delegate的setEditData()函数?

如果热心的你不嫌麻烦的话,我贴出了我的代码,大致展示一下我的思路(我的代码还是有问题的,只能显示一列单元格,而且frame不显示):

自定义frame代码:
  1. #ifndef THUMBNAILFRAME_H
  2. #define THUMBNAILFRAME_H
  3. #include <QFrame>
  4. #include <QWidget>
  5. #include <QSize>
  6. #include <QEvent>
  7. #include <QCheckBox>
  8. #include <QPixmap>
  9. #include <QLabel>
  10. #include "dataSource.h"
  11. namespace Ui {
  12. class thumbnailFrame;
  13. }

  14. class thumbnailFrame : public QFrame
  15. {

  16. public:
  17.     explicit thumbnailFrame(DataSource *datasource, QWidget *parent = 0);
  18.     ~thumbnailFrame();
  19.     void setThumbnailSize();
  20.     QSize getThumbnailSize();
  21.     void setDataSource(DataSource *dataSource);
  22.     DataSource* getDataSource();
  23.     void setCheckBox(bool save);
  24.     QCheckBox * getCheckBox();
  25.     void setImgShowLabel(QPixmap pixmap);
  26.     QLabel *getImgShowLabel();
  27.     void setNameLable(QString name);
  28.     QLabel *getNameLabel();
  29. private:
  30.     Ui::thumbnailFrame *ui;
  31.     QSize thumbnailSize;  //等于数据源中的iconsize
  32.     DataSource *dataSource; //数据源规格
  33. };

  34. #endif // THUMBNAILFRAME_H

  35. #include "thumbnailFrame.h"
  36. #include "ui_thumbnailframe.h"
  37. thumbnailFrame::thumbnailFrame(DataSource *datasource, QWidget *parent) :
  38.     QFrame(parent),
  39.     ui(new Ui::thumbnailFrame)
  40. {
  41.     ui->setupUi(this);
  42.     ui->imgNameLabel->setAlignment(Qt::AlignCenter); //图片名居
  43.     setDataSource(datasource);
  44. }

  45. thumbnailFrame::~thumbnailFrame(){
  46.     delete ui;
  47.     delete dataSource;
  48. }

  49. void thumbnailFrame::setThumbnailSize(){
  50.     int icon_width = this->dataSource->getIconSize().width();
  51.     int icon_height = this->dataSource->getIconSize().height();
  52.     ui->imgShowLabel->resize(icon_width, icon_height);
  53.     int name_width = this->dataSource->getNameLabelSize().width();
  54.     int name_height = this->dataSource->getNameLabelSize().height();
  55.     ui->imgNameLabel->resize(name_width, name_height);
  56.     int space_width = this->dataSource->getSpace().width();
  57.     int space_height = this->dataSource->getSpace().height();
  58.     int frame_width = icon_width + space_width;
  59.     int frame_height = icon_height + name_height + space_height;
  60.     this->thumbnailSize = QSize(frame_width, frame_height);
  61. }

  62. QSize thumbnailFrame::getThumbnailSize(){
  63.     return thumbnailSize;
  64. }

  65. void thumbnailFrame::setDataSource(DataSource* dataSource){
  66.     this->dataSource = dataSource;
  67. }

  68. DataSource* thumbnailFrame::getDataSource(){
  69.     return this->dataSource;
  70. }

  71. void thumbnailFrame::setCheckBox(bool save){
  72.     Qt::CheckState state;
  73.     if(save == true){
  74.         state = Qt::Checked;
  75.     }else{
  76.         state = Qt::Unchecked;
  77.     }
  78.     this->ui->checkBox->setCheckState(state);
  79. }

  80. QCheckBox *thumbnailFrame::getCheckBox(){
  81.     return this->ui->checkBox;
  82. }

  83. void thumbnailFrame::setNameLable(QString name){
  84.     this->ui->imgNameLabel->setText(name);
  85. }

  86. QLabel * thumbnailFrame::getNameLabel(){
  87.     return this->ui->imgNameLabel;
  88. }

  89. void thumbnailFrame::setImgShowLabel(QPixmap pixmap){
  90.     this->ui->imgShowLabel->setPixmap(pixmap);
  91. }
复制代码
自定义数据源:
  1. #ifndef DATASOURCE_H
  2. #define DATASOURCE_H
  3. #include <QObject>
  4. #include <QVector>
  5. #include <QPixmap>
  6. #include <QSize>
  7. class DataSource : public QObject
  8. {
  9.     Q_OBJECT
  10. public:
  11.     DataSource(QObject *parent = 0);
  12.     ~ DataSource();
  13.     void setName(QString name);
  14.     QString getName();
  15.     void setPixMap(QPixmap *pixMap);
  16.     QPixmap *getPixMap();
  17.     void setIconSize(QSize size);
  18.     QSize getIconSize();
  19.     void setNameLabelSize(QSize size);
  20.     QSize getNameLabelSize();
  21.     void setCheckboxSize(QSize size);
  22.     QSize getCheckboxSize();
  23.     void setSpace(QSize size);
  24.     QSize getSpace();
  25.     void setSave(bool save);
  26.     bool getSave();
  27. private:
  28.     QString name;
  29.     QPixmap *pixMap;
  30.     bool save;
  31.     QSize iconSize;  //缩略图尺寸
  32.     QSize nameLabelSize; //展现文件名的lable尺寸,宽度最好和缩略图宽度相等
  33.     QSize checkboxSize; //复选框尺寸
  34.     QSize space; //间距
  35. };

  36. #endif // DATASOURCE_H

  37. #include "dataSource.h"

  38. DataSource::DataSource(QObject *parent):QObject(parent)
  39. {
  40.     this->name = "";
  41.     this->pixMap = NULL;
  42.     this->save = false;
  43. }

  44. DataSource::~DataSource(){
  45.     delete pixMap;
  46. }

  47. void DataSource::setName(QString name){
  48.     this->name = name;
  49. }

  50. QString DataSource::getName(){
  51.     return this->name;
  52. }

  53. void DataSource::setPixMap(QPixmap *pixMap){
  54.     this->pixMap = pixMap;
  55. }

  56. QPixmap *DataSource::getPixMap(){
  57.     return this->pixMap;
  58. }

  59. void DataSource::setIconSize(QSize size){
  60.     this->iconSize = size;
  61. }

  62. QSize DataSource::getIconSize(){
  63.     return this->iconSize;
  64. }

  65. void DataSource::setNameLabelSize(QSize size){
  66.     this->nameLabelSize = size;
  67. }

  68. QSize DataSource::getNameLabelSize(){
  69.     return this->nameLabelSize;
  70. }

  71. void DataSource::setCheckboxSize(QSize size){
  72.     this->checkboxSize = size;
  73. }

  74. QSize DataSource::getCheckboxSize(){
  75.     return this->checkboxSize;
  76. }

  77. void DataSource::setSpace(QSize size){
  78.     this->space = size;
  79. }

  80. QSize DataSource::getSpace(){
  81.     return this->space;
  82. }

  83. void DataSource::setSave(bool save){
  84.     this->save = save;
  85. }

  86. bool DataSource::getSave(){
  87.     return this->save;
  88. }
复制代码
自定义delegate:
  1. #ifndef THUMBNAILDELEGATE_H
  2. #define THUMBNAILDELEGATE_H
  3. #include <QItemDelegate>
  4. #include <QPainter>
  5. #include <QStyleOptionViewItem>
  6. #include <QModelIndex>
  7. #include <QEvent>
  8. #include <QPixmap>
  9. #include "thumbnailFrame.h"


  10. class ThumbnailDelegate: public QItemDelegate
  11. {
  12.     Q_OBJECT
  13. public:
  14.     explicit ThumbnailDelegate(DataSource *dataSource, QObject *parent = 0);
  15.     ~ThumbnailDelegate();
  16.     void setDataSource(DataSource *datasource);
  17.     DataSource* getDataSource();
  18.     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const;
  19. //    bool editorEvent(QEvent *event,
  20. //                     QAbstractItemModel *model,
  21. //                     const QStyleOptionViewItem &option,
  22. //                     const QModelIndex &index);
  23.     //返回一个编辑控件,用来编辑指定项的数据
  24.     virtual QWidget *createEditor(QWidget *parent,
  25.                           const QStyleOptionViewItem &option,
  26.                           const QModelIndex &index)const;
  27.     //将Model中数据赋值到控件上
  28.     virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
  29.     //设定模型数据,根据指定项中对应编辑控件的数据
  30.     virtual void setModelData(QWidget *editor, QAbstractItemModel *model,
  31.                       const QModelIndex &index) const;
  32.     //更新编辑框几何形状
  33.     virtual void updateEditorGeometry(QWidget *editor,
  34.             const QStyleOptionViewItem &option, const QModelIndex &index) const;

  35. private:
  36.     QPixmap pixMap;
  37.     thumbnailFrame *frame;
  38.     DataSource *datasource; //数据源样例
  39. };

  40. #endif // THUMBNAILDELEGATE_H

  41. #include "thumbnailDelegate.h"
  42. #include <QVariant>
  43. #include <QRect>
  44. #include <QStyle>
  45. #include <QApplication>
  46. #include <QEvent>
  47. #include <QVariant>
  48. #include <QModelIndex>
  49. //Q_DECLARE_METATYPE(DataSource*)
  50. //Q_DECLARE_METATYPE(DataSource)

  51. ThumbnailDelegate::ThumbnailDelegate(DataSource *dataSource, QObject *parent):
  52.     QItemDelegate(parent){
  53.     setDataSource(dataSource);
  54. }

  55. ThumbnailDelegate::~ThumbnailDelegate(){
  56.     delete datasource;
  57. }

  58. void ThumbnailDelegate::setDataSource(DataSource *datasource){
  59.     this->datasource = datasource;
  60. }


  61. DataSource* ThumbnailDelegate::getDataSource(){
  62.     return this->datasource;
  63. }

  64. QWidget * ThumbnailDelegate::createEditor(QWidget *parent,
  65.                                           const QStyleOptionViewItem &option,
  66.                                           const QModelIndex &index)const{

  67.     thumbnailFrame *frame = new thumbnailFrame(this->datasource, parent);
  68.     frame->setThumbnailSize();
  69.     return frame;
  70. }

  71. //将Model中数据赋值到控件上
  72. void ThumbnailDelegate::setEditorData(QWidget *editor,
  73.                                     const QModelIndex &index) const{
  74.     //返回该索引的模型,继而返回该模型中此索引的编辑角色数据
  75.     QVariant var = index.model()->data(index);
  76.     DataSource *source = var.value<DataSource*>();
  77.     QString name = source->getName();
  78.     QPixmap *pixMap = source->getPixMap();
  79.     bool save = source->getSave();
  80.     //给控件赋值
  81.     thumbnailFrame *frame = static_cast<thumbnailFrame*>(editor);
  82.     frame->setDataSource(this->datasource);
  83.     frame->setThumbnailSize(); //设置frame上的各个控价大小
  84.     frame->setCheckBox(save);
  85.     frame->setImgShowLabel(*pixMap);
  86.     frame->setNameLable(name);
  87. }

  88. void ThumbnailDelegate::setModelData(QWidget *editor,
  89.                                      QAbstractItemModel *model,
  90.                                      const QModelIndex &index) const
  91. {
  92.     thumbnailFrame *frame = static_cast<thumbnailFrame*>(editor);
  93.     bool save;
  94.     if(frame->getCheckBox()->checkState() == Qt::Checked){
  95.         save = true;
  96.     }else{
  97.         save = false;
  98.     }
  99.     QString name = frame->getDataSource()->getName();
  100.     QPixmap *pixMap = frame->getDataSource()->getPixMap();
  101.     QSize iconSize = frame->getDataSource()->getIconSize();
  102.     QSize nameLabelSize = frame->getDataSource()->getNameLabelSize();
  103.     QSize checkboxSize = frame->getDataSource()->getCheckboxSize();
  104.     QSize space = frame->getDataSource()->getSpace();
  105.     DataSource *data = new DataSource();
  106.     data->setPixMap(pixMap);
  107.     data->setName(name);
  108.     data->setIconSize(iconSize);
  109.     data->setCheckboxSize(checkboxSize);
  110.     data->setSpace(space);
  111.     data->setNameLabelSize(nameLabelSize);
  112.     data->setSave(save);
  113.     //设置模型的数据
  114.     QVariant var;
  115.     var.setValue(data);
  116.     model->setData(index, var);
  117. }

  118. void ThumbnailDelegate::updateEditorGeometry(QWidget *editor,
  119.                                              const QStyleOptionViewItem &option,
  120.                                              const QModelIndex &index) const{

  121.     editor->setGeometry(option.rect);
  122. }


  123. void ThumbnailDelegate::paint(QPainter *painter,
  124.                               const QStyleOptionViewItem &option,
  125.                               const QModelIndex &index) const{

  126.     const QAbstractItemModel *model = index.model();
  127.     QVariant var = model->data(index);
  128.     if(var.isNull()){
  129.         var = false;
  130.         return;
  131.     }
  132.     //画图
  133.     QPixmap *pixMap = var.value<DataSource*>()->getPixMap();
  134.     QSize icon_size = var.value<DataSource*>()->getIconSize(); //图片尺寸
  135.     QSize space_size = var.value<DataSource*>()->getSpace();
  136.     QSize checkbox_size = var.value<DataSource*>()->getCheckboxSize();
  137.     QRect rect = option.rect;
  138.     int x = rect.x() + space_size.width() / 2;
  139.     int y = rect.y() + space_size.height() / 2;
  140.     painter->drawPixmap(x, y, pixMap->scaled((var.value<DataSource*>()->getIconSize())));
  141.     //画图片名称
  142.     QString name = var.value<DataSource*>()->getName();
  143.     int x2 = x;
  144.     int y2 = y + icon_size.height();
  145.     painter->drawText(x2, y2, name);
  146.     painter->end();

  147.     //画复选框
  148.     bool checked = var.value<DataSource*>()->getSave();
  149.     //按钮风格选项
  150.     QStyleOptionButton *checkBoxOption = new QStyleOptionButton();
  151.     checkBoxOption->state |= QStyle::State_Enabled;
  152.     if(checked){
  153.         checkBoxOption->state |= QStyle::State_On;
  154.     }else{
  155.         checkBoxOption->state |= QStyle::State_Off;
  156.     }
  157.     int x3 = x + icon_size.width() - checkbox_size.width();
  158.     int y3 = y;
  159.     QRect rect2(x3, y3, checkbox_size.width(), checkbox_size.height());
  160.     checkBoxOption->rect = rect2;
  161.     QApplication::style()->drawControl(QStyle::CE_CheckBox,checkBoxOption,painter);
  162. }

  163. //bool ThumbnailDelegate::editorEvent(QEvent *event,
  164. //                                    QAbstractItemModel *model,
  165. //                                    const QStyleOptionViewItem &option,
  166. //                                    const QModelIndex &index){

  167. //    if(event->type() == QEvent::MouseButtonPress){
  168. //        QVariant var = model->data(index);
  169. //        if(var.value<DataSource>().getSave()){
  170. //                model->setData();
  171. //                return true;
  172. //        }
  173. //        return false;
  174. //     }
  175. //}

复制代码
自定义model:
  1. #ifndef THUMBNAILMODEL_H
  2. #define THUMBNAILMODEL_H
  3. #include <QVariant>
  4. #include <QAbstractTableModel>
  5. #include "dataSource.h"
  6. class ThumbnailModel: public QAbstractTableModel
  7. {
  8. public:
  9.     ThumbnailModel(DataSource *dataSource, int tableView_h, int tableView_w, QObject *parent = 0);
  10.     ~ThumbnailModel();
  11.     void setVectorDataSource(QVector<DataSource*> vectorDataSource);
  12.     int rowCount(const QModelIndex &parent) const;
  13.     int columnCount(const QModelIndex &parent) const;
  14.     QVariant data(const QModelIndex &index, int role) const;
  15.     QVariant headerData(int section, Qt::Orientation orientation, int role) const;
  16.     void setTableView_width(int width);
  17.     int getTableView_width();
  18.     void setTableView_height(int height);
  19.     int getTableView_height();
  20.     void setDataSource(DataSource *dataSource);
  21.     DataSource *getDataSource();
  22. private:
  23.     QVector<DataSource*> vectorDataSource;  //底层数据
  24.     int tableView_width;
  25.     int tableView_heigth;
  26.     DataSource *dataSource; //底层数据单个范例
  27. };
  28. #endif

  29. #include "thumbnailModel.h"
  30. #include <QModelIndex>

  31. //Q_DECLARE_METATYPE(DataSource)
  32. //Q_DECLARE_METATYPE(DataSource*)
  33. ThumbnailModel::ThumbnailModel(DataSource *dataSource, int tableview_h, int tableview_w, QObject *parent):
  34.     QAbstractTableModel(parent)
  35. {
  36.     setDataSource(dataSource);
  37.     setTableView_height(tableview_h);
  38.     setTableView_width(tableview_w);
  39. }

  40. ThumbnailModel::~ThumbnailModel(){
  41.     delete dataSource;
  42. }

  43. void ThumbnailModel::setVectorDataSource(QVector<DataSource*> vectorDataSource){
  44.     this->vectorDataSource = vectorDataSource;
  45. }

  46. void ThumbnailModel::setTableView_width(int width){
  47.     this->tableView_width = width;
  48. }

  49. int ThumbnailModel::getTableView_width(){
  50.     return this->tableView_width;
  51. }

  52. void ThumbnailModel::setTableView_height(int height){
  53.     this->tableView_heigth = height;
  54. }

  55. int ThumbnailModel::getTableView_height(){
  56.     return this->tableView_heigth;
  57. }

  58. void ThumbnailModel::setDataSource(DataSource *datasource){
  59.     this->dataSource = datasource;
  60. }

  61. DataSource* ThumbnailModel::getDataSource(){
  62.     return this->dataSource;
  63. }

  64. int ThumbnailModel::rowCount(const QModelIndex &/*parent*/) const{
  65.     int frame_height = this->dataSource->getIconSize().height() +
  66.                        this->dataSource->getNameLabelSize().height() +
  67.                        this->dataSource->getSpace().height();
  68.     int rowCount = this->tableView_heigth / frame_height;
  69.     return rowCount;
  70. }
  71. int ThumbnailModel::columnCount(const QModelIndex &/*parent*/) const{
  72.     int space_width = this->dataSource->getSpace().width();
  73.     int other_width = this->dataSource->getIconSize().width() > this->dataSource->getNameLabelSize().width()?
  74.                 this->dataSource->getIconSize().width():
  75.                 this->dataSource->getNameLabelSize().width();
  76.     int frame_width = space_width + other_width;
  77.     int columnCount = this->tableView_width / frame_width;
  78.     return columnCount;
  79. }

  80. QVariant ThumbnailModel::data(const QModelIndex &index, int role) const{
  81.     if(!index.isValid()){
  82.         return QVariant();
  83.     }
  84.     int row = index.row();
  85.     int col = index.column();
  86.     int index_ = row * this->columnCount(QModelIndex()) + col - 1;
  87.     QVariant var;
  88.     var.setValue((void *)this->vectorDataSource.at(index_));
  89.     return var;
  90. }

  91. QVariant ThumbnailModel::headerData(int section, Qt::Orientation /* orientation */, int role) const{
  92.     if(role != Qt::DisplayRole)
  93.         return QVariant();
  94.     return section;
  95. }


复制代码
定义一个tableview,定义数据源,将自定义委托和模型赋给tableview:
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QDebug>
  4. #include <QDir>
  5. #include <QStringList>
  6. #include <QFileInfo>
  7. #include <QTableView>
  8. #include <QList>
  9. #include <QSize>
  10. #include <QDebug>
  11. #include "dataSource.h"
  12. #include "thumbnailDelegate.h"
  13. #include "thumbnailFrame.h"
  14. #include "thumbnailModel.h"
  15. MainWindow::MainWindow(QWidget *parent) :
  16.     QMainWindow(parent),
  17.     ui(new Ui::MainWindow)
  18. {
  19.     ui->setupUi(this);
  20.     QSize icon_size(900, 100);
  21.     QSize name_label_size(100, 15);
  22.     QSize checkbox_size(8, 8);
  23.     QSize space(10, 10);
  24.     QDir dir("C:/Users/happyxiahuixia/Desktop/threadthumbnail");
  25.     QStringList filter;
  26.     filter<<"*.png"<<"*.gif";
  27.     QFileInfoList fileInfo = dir.entryInfoList(filter);
  28.     int icon_count = fileInfo.count();
  29.     qDebug()<<"============================="<<icon_count;
  30.     /*底层数据源*/
  31.     QVector<DataSource*> vectorDataSource;
  32.     /*****单个数据源样例,用于统一delegate,model,底层数据源的控件尺寸*****/
  33.     DataSource *sampleData = new DataSource();
  34.     sampleData->setCheckboxSize(checkbox_size);
  35.     sampleData->setIconSize(icon_size);
  36.     sampleData->setNameLabelSize(name_label_size);
  37.     sampleData->setSpace(space);
  38.     /*******************初始化底层数据源**********************/
  39.     for(int i = 0; i < icon_count; i++){
  40.         QString icon_path = fileInfo.at(i).filePath();
  41.         int index = icon_path.lastIndexOf("/") + 1;
  42.         QString icon_name = icon_path.mid(index);
  43.         qDebug()<<icon_name;
  44.         DataSource *source = new DataSource();
  45.         QPixmap *tmp = new QPixmap(icon_path);
  46.         QPixmap *pixMap = new QPixmap(tmp->scaled(icon_size));
  47.         source->setPixMap(pixMap);
  48.         qDebug()<<"source's pixmap size:"<<source->getPixMap()->width()<<source->getPixMap()->height();
  49.         source->setName(icon_name);
  50.         source->setSave(false);
  51.         source->setSpace(space);
  52.         source->setCheckboxSize(checkbox_size);
  53.         source->setIconSize(icon_size);
  54.         source->setNameLabelSize(name_label_size);
  55.         vectorDataSource.append(source);
  56.     }
  57.     /*************************添加tableview控件**************/
  58.     QTableView *tableView = new QTableView(this);
  59.     this->resize(1000, 1000);
  60.     tableView->adjustSize();//不可以重新定义尺寸

  61.     int cell_width = sampleData->getIconSize().width() +
  62.                        sampleData->getSpace().width();
  63.     int cell_height = sampleData->getIconSize().height() +
  64.                         sampleData->getNameLabelSize().height() +
  65.                         sampleData->getSpace().height();
  66. //    tableView->horizontalHeader()->setDefaultSectionSize(cell_width);
  67. //    tableView->verticalHeader()->setDefaultSectionSize(cell_height);


  68.     /************************自定义委托**********************/
  69.     ThumbnailDelegate *delegate = new ThumbnailDelegate(sampleData);
  70.     /************************自定义模型**********************/
  71.     ThumbnailModel *model = new ThumbnailModel(sampleData, tableView->height(),
  72.                                                tableView->width());
  73.     model->setVectorDataSource(vectorDataSource); //设置底层数据源

  74.     tableView->setModel(model);
  75.     tableView->setItemDelegate(delegate);

  76. }

  77. MainWindow::~MainWindow()
  78. {
  79.     delete ui;
  80. }
复制代码

回复

使用道具 举报

累计签到:410 天
连续签到:1 天
2016-3-23 23:48:33 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了