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 QAbstractTableModel
18 {
19     Q_OBJECT
20 
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 QHeaderView
50 {
51   Q_OBJECT
52 
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 QTableView
64 {
65     Q_OBJECT
66 
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 turn
102         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));//red
113             //            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         else
122         {
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     else
167     {
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) const
195 {
196     if(vertical_header_list.size() > 0)
197         return vertical_header_list.size();
198 
199     if(NULL == arr_row_list)
200         return 0;
201     else
202         return arr_row_list->size();
203 }
204 
205 int TableModel::columnCount(const QModelIndex &parent) const
206 {
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     else
215         return arr_row_list->at(0).size();
216 }
217 
218 QVariant TableModel::data(const QModelIndex &index, int role) const
219 {
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) const
245 {
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             else
253                 return QVariant();
254         }
255         else
256         {
257             if(vertical_header_list.size() > section)
258                 return vertical_header_list[section];
259             else
260                 return QVariant();
261         }
262     }
263 
264     return QVariant();
265 }
266 
267 Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
268 {
269     if (!index.isValid())
270         return Qt::NoItemFlags;
271 
272     Qt::ItemFlags flag = QAbstractItemModel::flags(index);
273 
274     // flag|=Qt::ItemIsEditable
275     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事件,即鼠标释放,表格中的内容动态变化

 

posted on 2014-09-01 10:53  辉常的D调  阅读(26359)  评论(4编辑  收藏  举报

导航