首页 > 代码库 > QTableView使用自定义委托(QItemDelegate)

QTableView使用自定义委托(QItemDelegate)

需要在表格中绘制流程图,主要有箭头,方向,颜色,字符串,由于QTableView没有可用的绘制函数,所以需要自己去定义、

委托(delegate)继承QItemDelegate,模型(model)继承QAbstractTableModel,表头(headerview)继承QHeaderView,表(table)继承QTableView

这里只实现绘制显示功能,如果需要进行编辑还需另外重写createEditor setEditorData setModelData 函数

如下是实现效果图

 1 /********************ArrowDelegate********************/ 2 class ArrowDelegate : public QItemDelegate 3 { 4     Q_OBJECT 5  6 public: 7  8     ArrowDelegate(QObject* parent = 0); 9     virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;10 11 protected:12 13 private:14 };15 16 /********************TableModel********************/17 class TableModel : public QAbstractTableModel18 {19     Q_OBJECT20 21 public:22 23     TableModel(QObject *parent = 0);24     ~TableModel(void);25     void setHorizontalHeaderList(QStringList horizontalHeaderList);26     void setVerticalHeaderList(QStringList verticalHeaderList);27     int rowCount(const QModelIndex &parent = QModelIndex()) const;28     int columnCount(const QModelIndex &parent = QModelIndex()) const;29     QVariant data(const QModelIndex &index, int role) const;30     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;31     Qt::ItemFlags flags(const QModelIndex &index) const;32     void setModalDatas(QList< QStringList > *rowlist);33     void refrushModel();34 35 protected:36 37 signals:38 39     void updateCount(int count);40 41 private:42 43     QStringList horizontal_header_list;44     QStringList vertical_header_list;45     QList< QStringList > *arr_row_list;46 47 };48 49 class MyHeader : public QHeaderView50 {51   Q_OBJECT52 53 public:54     MyHeader(QWidget *parent = 0);//:QHeaderView(Qt::Horizontal, parent)55 56 protected:57     void mouseReleaseEvent(QMouseEvent *e);58 59 signals:60     void refresh();61 };62 /********************ReadOnlyTableView********************/63 class MyTableView : public QTableView64 {65     Q_OBJECT66 67 public:68 69     MyTableView(QWidget *parent=0);70     ~MyTableView(void);71     void addRow(QStringList rowList);72     void clearAllRow(int row);//数据清空73     int rowCount();74 75 public slots:76 77     void remove();78     void clear();79     void changeValue();80     void refreshmymodel();81 82     void mouseReleaseEvent(QMouseEvent *event);83 private:84 85     void initHeader();86 87 private:88     MyHeader *myheader;89     TableModel *mymodel;90     QList< QStringList > grid_data_list;91     ArrowDelegate *arrow_delegate;92     int row;93 signals:94 95     void updateCount(int count);96 };

 

  1 #include "tableview.h"  2 #include "math.h"  3 #include <QApplication>  4 #include <QPen>  5   6 int g_x;  7 /********************ArrowDelegate********************/  8 ArrowDelegate::ArrowDelegate(QObject *parent)  9     : QItemDelegate(parent) 10 { 11     g_x = 0; 12 } 13  14 void ArrowDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const 15 { 16     int row = index.row(); 17     int x = option.rect.x(); 18     int y = option.rect.y(); 19     int width = option.rect.width(); 20     int height = option.rect.height(); 21     QPen pen_black; 22     pen_black.setWidth(2); 23     pen_black.setColor(QColor(Qt::black)); 24     QStyleOptionViewItem myOption = option; 25  26     if (index.column() == 2)//UE 27     { 28         QPainterPath path_UE; 29  30         QPoint One; 31         QPoint Two; 32         //        pen.setWidth(2); 33         One.setX(x + width / 2); 34         One.setY(y); 35         Two.setX(x + width / 2); 36         Two.setY(y + height); 37         path_UE.moveTo(One); 38         path_UE.lineTo(Two); 39         painter->setPen(pen_black); 40         painter->drawPath(path_UE); 41     } 42  43     if (index.column() == 3) 44     { 45         g_x = x + width / 2;//get the begin 46         QPainterPath path_SENB; 47  48         QPoint One; 49         QPoint Two; 50         One.setX(x + width / 2); 51         One.setY(y); 52         Two.setX(x + width / 2); 53         Two.setY(y + height); 54         path_SENB.moveTo(One); 55         path_SENB.lineTo(Two); 56         //        pen.setColor(QColor(Qt::black)); 57         painter->setPen(pen_black); 58         painter->drawPath(path_SENB); 59         //        g_y = y + height / 2; 60     } 61     if (index.column() == 4) 62     { 63         QString str4 = index.model()->data(index,Qt::DisplayRole).toString(); 64         if (!str4.isEmpty()) 65         { 66             QPainterPath path_TENB; 67  68             QPoint One; 69             QPoint Two; 70             //        pen.setWidth(2); 71             One.setX(x + width / 2); 72             One.setY(y); 73             Two.setX(x + width / 2); 74             Two.setY(y + height); 75             path_TENB.moveTo(One); 76             path_TENB.lineTo(Two); 77             painter->setPen(pen_black); 78             painter->drawPath(path_TENB); 79         } 80     } 81  82     if (index.column() == 5) 83     { 84         QPainterPath path,path_SMME; 85         QPen pen; 86         QPoint One; 87         QPoint Two; 88         //        pen5.setWidth(2); 89         One.setX(x + width / 2); 90         One.setY(y); 91         Two.setX(x + width / 2); 92         Two.setY(y + height); 93         path_SMME.moveTo(One); 94         path_SMME.lineTo(Two); 95         //        pen5.setColor(QColor(Qt::black)); 96         painter->setPen(pen_black); 97         painter->drawPath(path_SMME); 98  99         QString str = index.model()->data(index,Qt::DisplayRole).toString();100         if (str.isEmpty())101             return;//break this turn102         QStringList strList = str.split("+");103         QString text = strList.at(0);104         int direction = strList.at(1).toInt();105 106         myOption.displayAlignment = Qt::AlignCenter;107 108         QRectF rect;109         pen.setWidth(1);110         if (direction)111         {112             pen.setColor(QColor(255,0,0));//red113             //            One.setX(x);114             //            One.setY(y + 3 * height / 4);115             One.setX(g_x);116             One.setY(y + 3 * height / 4);117             Two.setX(x + width / 2);118             Two.setY(y + 3 * height / 4);119             //            painter->drawText(One,text);120         }121         else122         {123             pen.setColor(QColor(0,0,255));124             //            Two.setX(x);125             //            Two.setY(y + 3 * height / 4);126             Two.setX(g_x);127             Two.setY(y + 3 * height / 4);128             One.setX(x + width / 2);129             One.setY(y + 3 * height / 4);130             //            painter->drawText(Two,text);131         }132 133         int Height = 20;134         //        QPoint Three(x + width / 2 , y + height / 3);135 136         double slopy , cosy , siny;137         double Par = Height/2;138         slopy = atan2( ( One.y() - Two.y() ),( One.x() - Two.x() ) );139         cosy = cos( slopy );140         siny = sin( slopy );141 142 143         path.moveTo(One);144         path.lineTo(Two);145 146 147         path.moveTo(Two);148         path.lineTo(Two.x() + int( Par * cosy - ( Par / 2.0 * siny ) ),149                     Two.y() + int( Par * siny + ( Par / 2.0 * cosy ) ) );150         path.moveTo(Two);151         path.lineTo(Two.x() + int( Par * cosy - ( Par / 2.0 * siny ) ),152                     Two.y() - int( Par * siny + ( Par / 2.0 * cosy ) ) );153 154         painter->setPen(pen);155         painter->drawPath(path);156 157         //        pen.setColor(QColor(Qt::black));158         painter->setPen(pen_black);159         rect.setTopLeft(QPointF(g_x,y));160         rect.setBottomRight(QPointF(x + width / 2,y + height / 2));161         //        rect(QPointF(g_x,y),QPointF(x + width / 2,y + height / 2));162         QTextOption textOption;163         textOption.setAlignment(Qt::AlignCenter);164         painter->drawText(rect,text,textOption);165     }166     else167     {168         return QItemDelegate::paint (painter, option, index);169     }170 }171 172 /********************TableModel********************/173 TableModel::TableModel(QObject *parent)174     : QAbstractTableModel(parent), arr_row_list(NULL)175 {176 177 }178 179 TableModel::~TableModel(void)180 {181     arr_row_list = NULL;182 }183 184 void TableModel::setHorizontalHeaderList(QStringList horizontalHeaderList)185 {186     horizontal_header_list = horizontalHeaderList;187 }188 189 void TableModel::setVerticalHeaderList(QStringList verticalHeaderList)190 {191     vertical_header_list = verticalHeaderList;192 }193 194 int TableModel::rowCount(const QModelIndex &parent) const195 {196     if(vertical_header_list.size() > 0)197         return vertical_header_list.size();198 199     if(NULL == arr_row_list)200         return 0;201     else202         return arr_row_list->size();203 }204 205 int TableModel::columnCount(const QModelIndex &parent) const206 {207     if(horizontal_header_list.size() > 0)208         return horizontal_header_list.size();209 210     if(NULL == arr_row_list)211         return 0;212     else if(arr_row_list->size() < 1)213         return 0;214     else215         return arr_row_list->at(0).size();216 }217 218 QVariant TableModel::data(const QModelIndex &index, int role) const219 {220     if (!index.isValid())221         return QVariant();222 223     if(NULL == arr_row_list)224         return QVariant();225 226     if(arr_row_list->size() < 1)227         return QVariant();228 229     if (role == Qt::TextAlignmentRole)230     {231         return int(Qt::AlignLeft | Qt::AlignVCenter);232     }233     else if (role == Qt::DisplayRole)234     {235         if(index.row() >= arr_row_list->size())236             return QVariant();237         if(index.column() >= arr_row_list->at(0).size())238             return QVariant();239         return arr_row_list->at(index.row()).at(index.column());240     }241     return QVariant();242 }243 244 QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const245 {246     if(role==Qt::DisplayRole)247     {248         if(orientation==Qt::Horizontal)249         {250             if(horizontal_header_list.size() > section)251                 return horizontal_header_list[section];252             else253                 return QVariant();254         }255         else256         {257             if(vertical_header_list.size() > section)258                 return vertical_header_list[section];259             else260                 return QVariant();261         }262     }263 264     return QVariant();265 }266 267 Qt::ItemFlags TableModel::flags(const QModelIndex &index) const268 {269     if (!index.isValid())270         return Qt::NoItemFlags;271 272     Qt::ItemFlags flag = QAbstractItemModel::flags(index);273 274     // flag|=Qt::ItemIsEditable275     return flag;276 }277 278 void TableModel::setModalDatas(QList< QStringList > *rowlist)279 {280     arr_row_list = rowlist;281 }282 283 void TableModel::refrushModel()284 {285     beginResetModel();286     endResetModel();287 288     emit updateCount(this->rowCount(QModelIndex()));289 }290 291 /********************TableView********************/292 MyTableView::MyTableView(QWidget *parent)293     : QTableView(parent)294 {295     this->setAlternatingRowColors(true);296     //    this->setStyleSheet( "QTableView{background-color: rgb(250, 250, 115);"297     //                         "alternate-background-color: rgb(141, 163, 215);}" );//????298     this->setSelectionBehavior(QAbstractItemView::SelectRows);299     this->horizontalHeader()->setStretchLastSection(true);300     this->horizontalHeader()->setHighlightSections(false);301     this->verticalHeader()->setVisible(false);302     this->setShowGrid(false);303     this->setEditTriggers(QAbstractItemView::NoEditTriggers);304     this->setSelectionMode(QAbstractItemView::ExtendedSelection);305 306 307     mymodel = new TableModel();308     this->setModel(mymodel);309     myheader = new MyHeader;310     myheader->setModel(mymodel);311     this->setHorizontalHeader(myheader);312 313     this->initHeader();314     mymodel->setModalDatas(&grid_data_list);315     arrow_delegate = new ArrowDelegate();316     this->setItemDelegate(arrow_delegate);317 318 319     connect(mymodel, SIGNAL(updateCount(int)), this, SLOT(updateCount(int )));320     connect(myheader,SIGNAL(refresh()),this,SLOT(refreshmymodel()));321 322 }323 324 MyTableView::~MyTableView(void)325 {326     if(arrow_delegate) {327         delete arrow_delegate;328         arrow_delegate = NULL;329     }330 331     if(mymodel) {332         delete mymodel;333         mymodel = NULL;334     }335     grid_data_list.clear();336 }337 338 void MyTableView::addRow(QStringList rowList)339 {340     grid_data_list.append(rowList);341     mymodel->refrushModel();342 }343 344 void MyTableView::clearAllRow(int row)345 {346     this->row = row;347     grid_data_list.clear();348     mymodel->refrushModel();349 }350 351 void MyTableView::remove()352 {353     QModelIndexList model_index_list = this->selectedIndexes();354     int model_count = model_index_list.count();355     if(model_count <= 0)356         return;357 358     QList<int> list_row;359     for(int i=model_count-1; i>=0; i--)360     {361         QModelIndex model_index = model_index_list.at(i);362         int row = model_index.row();363         if(!list_row.contains(row))364             list_row.append(row);365     }366 367     if(list_row.isEmpty())368         return;369 370     qSort(list_row);371 372     for(int i=list_row.count()-1; i>=0; i--)373     {374         grid_data_list.removeAt(list_row.at(i));375     }376 377     mymodel->refrushModel();378 }379 380 void MyTableView::clear()381 {382     grid_data_list.clear();383     mymodel->refrushModel();384 }385 386 int MyTableView::rowCount()387 {388     return mymodel->rowCount(QModelIndex());389 }390 391 void MyTableView::initHeader()392 {393     QStringList header;394     header<<"NO"<<"Time"<<"UE"<<"S-ENB"<<"T-ENB"<<"S-MME"<<"T-MME"<<"SGSN"395          <<"S-SGW"<<"T-SGW"<<"PGW/GGSN"<<"HSS/EIR"<<"PCRF"<<"AAA/ALP"<<"AF";396     mymodel->setHorizontalHeaderList(header);397     //    MyHeader *h = new MyHeader(this->horizontalHeader());398 399 }400 401 402 void MyTableView::refreshmymodel()403 {404     mymodel->refrushModel();405 }406 407 408 MyHeader::MyHeader(QWidget *parent):QHeaderView(Qt::Horizontal, parent)409 {410 411 }412 413 void MyHeader::mouseReleaseEvent(QMouseEvent *e)414 {415     emit refresh();416 }

通过全局变量保存箭头的左边点,函数计算箭头的头部画线路径。因为需要实现拖动表头列宽,改变对应表格项的宽度,所以需要触发表头的mouserelease事件,即鼠标释放,表格中的内容动态变化

 

QTableView使用自定义委托(QItemDelegate)