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

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

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

如下是实现效果图

 /********************ArrowDelegate********************/
class ArrowDelegate : public QItemDelegate
{
Q_OBJECT public: ArrowDelegate(QObject* parent = );
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; protected: private:
}; /********************TableModel********************/
class TableModel : public QAbstractTableModel
{
Q_OBJECT public: TableModel(QObject *parent = );
~TableModel(void);
void setHorizontalHeaderList(QStringList horizontalHeaderList);
void setVerticalHeaderList(QStringList verticalHeaderList);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
void setModalDatas(QList< QStringList > *rowlist);
void refrushModel(); protected: signals: void updateCount(int count); private: QStringList horizontal_header_list;
QStringList vertical_header_list;
QList< QStringList > *arr_row_list; }; class MyHeader : public QHeaderView
{
Q_OBJECT public:
MyHeader(QWidget *parent = );//:QHeaderView(Qt::Horizontal, parent) protected:
void mouseReleaseEvent(QMouseEvent *e); signals:
void refresh();
};
/********************ReadOnlyTableView********************/
class MyTableView : public QTableView
{
Q_OBJECT public: MyTableView(QWidget *parent=);
~MyTableView(void);
void addRow(QStringList rowList);
void clearAllRow(int row);//数据清空
int rowCount(); public slots: void remove();
void clear();
void changeValue();
void refreshmymodel(); void mouseReleaseEvent(QMouseEvent *event);
private: void initHeader(); private:
MyHeader *myheader;
TableModel *mymodel;
QList< QStringList > grid_data_list;
ArrowDelegate *arrow_delegate;
int row;
signals: void updateCount(int count);
};
 #include "tableview.h"
#include "math.h"
#include <QApplication>
#include <QPen> int g_x;
/********************ArrowDelegate********************/
ArrowDelegate::ArrowDelegate(QObject *parent)
: QItemDelegate(parent)
{
g_x = ;
} void ArrowDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
int row = index.row();
int x = option.rect.x();
int y = option.rect.y();
int width = option.rect.width();
int height = option.rect.height();
QPen pen_black;
pen_black.setWidth();
pen_black.setColor(QColor(Qt::black));
QStyleOptionViewItem myOption = option; if (index.column() == )//UE
{
QPainterPath path_UE; QPoint One;
QPoint Two;
// pen.setWidth(2);
One.setX(x + width / );
One.setY(y);
Two.setX(x + width / );
Two.setY(y + height);
path_UE.moveTo(One);
path_UE.lineTo(Two);
painter->setPen(pen_black);
painter->drawPath(path_UE);
} if (index.column() == )
{
g_x = x + width / ;//get the begin
QPainterPath path_SENB; QPoint One;
QPoint Two;
One.setX(x + width / );
One.setY(y);
Two.setX(x + width / );
Two.setY(y + height);
path_SENB.moveTo(One);
path_SENB.lineTo(Two);
// pen.setColor(QColor(Qt::black));
painter->setPen(pen_black);
painter->drawPath(path_SENB);
// g_y = y + height / 2;
}
if (index.column() == )
{
QString str4 = index.model()->data(index,Qt::DisplayRole).toString();
if (!str4.isEmpty())
{
QPainterPath path_TENB; QPoint One;
QPoint Two;
// pen.setWidth(2);
One.setX(x + width / );
One.setY(y);
Two.setX(x + width / );
Two.setY(y + height);
path_TENB.moveTo(One);
path_TENB.lineTo(Two);
painter->setPen(pen_black);
painter->drawPath(path_TENB);
}
} if (index.column() == )
{
QPainterPath path,path_SMME;
QPen pen;
QPoint One;
QPoint Two;
// pen5.setWidth(2);
One.setX(x + width / );
One.setY(y);
Two.setX(x + width / );
Two.setY(y + height);
path_SMME.moveTo(One);
path_SMME.lineTo(Two);
// pen5.setColor(QColor(Qt::black));
painter->setPen(pen_black);
painter->drawPath(path_SMME); QString str = index.model()->data(index,Qt::DisplayRole).toString();
if (str.isEmpty())
return;//break this turn
QStringList strList = str.split("+");
QString text = strList.at();
int direction = strList.at().toInt(); myOption.displayAlignment = Qt::AlignCenter; QRectF rect;
pen.setWidth();
if (direction)
{
pen.setColor(QColor(,,));//red
// One.setX(x);
// One.setY(y + 3 * height / 4);
One.setX(g_x);
One.setY(y + * height / );
Two.setX(x + width / );
Two.setY(y + * height / );
// painter->drawText(One,text);
}
else
{
pen.setColor(QColor(,,));
// Two.setX(x);
// Two.setY(y + 3 * height / 4);
Two.setX(g_x);
Two.setY(y + * height / );
One.setX(x + width / );
One.setY(y + * height / );
// painter->drawText(Two,text);
} int Height = ;
// QPoint Three(x + width / 2 , y + height / 3); double slopy , cosy , siny;
double Par = Height/;
slopy = atan2( ( One.y() - Two.y() ),( One.x() - Two.x() ) );
cosy = cos( slopy );
siny = sin( slopy ); path.moveTo(One);
path.lineTo(Two); path.moveTo(Two);
path.lineTo(Two.x() + int( Par * cosy - ( Par / 2.0 * siny ) ),
Two.y() + int( Par * siny + ( Par / 2.0 * cosy ) ) );
path.moveTo(Two);
path.lineTo(Two.x() + int( Par * cosy - ( Par / 2.0 * siny ) ),
Two.y() - int( Par * siny + ( Par / 2.0 * cosy ) ) ); painter->setPen(pen);
painter->drawPath(path); // pen.setColor(QColor(Qt::black));
painter->setPen(pen_black);
rect.setTopLeft(QPointF(g_x,y));
rect.setBottomRight(QPointF(x + width / ,y + height / ));
// rect(QPointF(g_x,y),QPointF(x + width / 2,y + height / 2));
QTextOption textOption;
textOption.setAlignment(Qt::AlignCenter);
painter->drawText(rect,text,textOption);
}
else
{
return QItemDelegate::paint (painter, option, index);
}
} /********************TableModel********************/
TableModel::TableModel(QObject *parent)
: QAbstractTableModel(parent), arr_row_list(NULL)
{ } TableModel::~TableModel(void)
{
arr_row_list = NULL;
} void TableModel::setHorizontalHeaderList(QStringList horizontalHeaderList)
{
horizontal_header_list = horizontalHeaderList;
} void TableModel::setVerticalHeaderList(QStringList verticalHeaderList)
{
vertical_header_list = verticalHeaderList;
} int TableModel::rowCount(const QModelIndex &parent) const
{
if(vertical_header_list.size() > )
return vertical_header_list.size(); if(NULL == arr_row_list)
return ;
else
return arr_row_list->size();
} int TableModel::columnCount(const QModelIndex &parent) const
{
if(horizontal_header_list.size() > )
return horizontal_header_list.size(); if(NULL == arr_row_list)
return ;
else if(arr_row_list->size() < )
return ;
else
return arr_row_list->at().size();
} QVariant TableModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant(); if(NULL == arr_row_list)
return QVariant(); if(arr_row_list->size() < )
return QVariant(); if (role == Qt::TextAlignmentRole)
{
return int(Qt::AlignLeft | Qt::AlignVCenter);
}
else if (role == Qt::DisplayRole)
{
if(index.row() >= arr_row_list->size())
return QVariant();
if(index.column() >= arr_row_list->at().size())
return QVariant();
return arr_row_list->at(index.row()).at(index.column());
}
return QVariant();
} QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role==Qt::DisplayRole)
{
if(orientation==Qt::Horizontal)
{
if(horizontal_header_list.size() > section)
return horizontal_header_list[section];
else
return QVariant();
}
else
{
if(vertical_header_list.size() > section)
return vertical_header_list[section];
else
return QVariant();
}
} return QVariant();
} Qt::ItemFlags TableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags; Qt::ItemFlags flag = QAbstractItemModel::flags(index); // flag|=Qt::ItemIsEditable
return flag;
} void TableModel::setModalDatas(QList< QStringList > *rowlist)
{
arr_row_list = rowlist;
} void TableModel::refrushModel()
{
beginResetModel();
endResetModel(); emit updateCount(this->rowCount(QModelIndex()));
} /********************TableView********************/
MyTableView::MyTableView(QWidget *parent)
: QTableView(parent)
{
this->setAlternatingRowColors(true);
// this->setStyleSheet( "QTableView{background-color: rgb(250, 250, 115);"
// "alternate-background-color: rgb(141, 163, 215);}" );//????
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->horizontalHeader()->setStretchLastSection(true);
this->horizontalHeader()->setHighlightSections(false);
this->verticalHeader()->setVisible(false);
this->setShowGrid(false);
this->setEditTriggers(QAbstractItemView::NoEditTriggers);
this->setSelectionMode(QAbstractItemView::ExtendedSelection); mymodel = new TableModel();
this->setModel(mymodel);
myheader = new MyHeader;
myheader->setModel(mymodel);
this->setHorizontalHeader(myheader); this->initHeader();
mymodel->setModalDatas(&grid_data_list);
arrow_delegate = new ArrowDelegate();
this->setItemDelegate(arrow_delegate); connect(mymodel, SIGNAL(updateCount(int)), this, SLOT(updateCount(int )));
connect(myheader,SIGNAL(refresh()),this,SLOT(refreshmymodel())); } MyTableView::~MyTableView(void)
{
if(arrow_delegate) {
delete arrow_delegate;
arrow_delegate = NULL;
} if(mymodel) {
delete mymodel;
mymodel = NULL;
}
grid_data_list.clear();
} void MyTableView::addRow(QStringList rowList)
{
grid_data_list.append(rowList);
mymodel->refrushModel();
} void MyTableView::clearAllRow(int row)
{
this->row = row;
grid_data_list.clear();
mymodel->refrushModel();
} void MyTableView::remove()
{
QModelIndexList model_index_list = this->selectedIndexes();
int model_count = model_index_list.count();
if(model_count <= )
return; QList<int> list_row;
for(int i=model_count-; i>=; i--)
{
QModelIndex model_index = model_index_list.at(i);
int row = model_index.row();
if(!list_row.contains(row))
list_row.append(row);
} if(list_row.isEmpty())
return; qSort(list_row); for(int i=list_row.count()-; i>=; i--)
{
grid_data_list.removeAt(list_row.at(i));
} mymodel->refrushModel();
} void MyTableView::clear()
{
grid_data_list.clear();
mymodel->refrushModel();
} int MyTableView::rowCount()
{
return mymodel->rowCount(QModelIndex());
} void MyTableView::initHeader()
{
QStringList header;
header<<"NO"<<"Time"<<"UE"<<"S-ENB"<<"T-ENB"<<"S-MME"<<"T-MME"<<"SGSN"
<<"S-SGW"<<"T-SGW"<<"PGW/GGSN"<<"HSS/EIR"<<"PCRF"<<"AAA/ALP"<<"AF";
mymodel->setHorizontalHeaderList(header);
// MyHeader *h = new MyHeader(this->horizontalHeader()); } void MyTableView::refreshmymodel()
{
mymodel->refrushModel();
} MyHeader::MyHeader(QWidget *parent):QHeaderView(Qt::Horizontal, parent)
{ } void MyHeader::mouseReleaseEvent(QMouseEvent *e)
{
emit refresh();
}

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

QTableView使用自定义委托(QItemDelegate)的更多相关文章

  1. Qt自定义委托在QTableView中绘制控件、图片、文字(内容比较全)

    自定义委托,继承于,QStyledItemDelegate类,重载Paint()函数, 1.实现在QTableView中绘制 格式字符串 2.实现在QTableView中绘制进度条 3.实现在QTab ...

  2. Qt自定义委托在QTableView中绘制控件、图片、文字

    自定义委托,继承于,QStyledItemDelegate类,重载Paint()函数, 1.实现在QTableView中绘制 格式字符串 2.实现在QTableView中绘制进度条 3.实现在QTab ...

  3. 26.QT-模型视图之自定义委托

    在上一章学习 25.QT-模型视图 后,本章接着学习视图委托 视图委托(Delegate)简介 由于模型负责组织数据,而视图负责显示数据,所以当用户想修改显示的数据时,就要通过视图中的委托来完成 视图 ...

  4. QTableWidget自定义委托

    QTableWidget单元格使用自定义的lineEdit控件导致不能选中 使用自定义委托解决 1.自定义委托 class LineEditDelegate : public QItemDelegat ...

  5. 自定义委托类型 - .Net自带委托类型

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递. 与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用. 一.自定义委托类型 1.语法结构:访问修 ...

  6. EventHandler委托与自定义委托

    http://blog.csdn.net/uuxyz/article/details/7175248 EventHandler委托与自定义委托 自定义委托: //1. public delegate ...

  7. 阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:9. 自定义委托事件方法

    文档目录: 说明 1. 连接阿里云物联网 2. IoT 客户端 3. 订阅Topic与响应Topic 4. 设备上报属性 4.1 上报位置信息 5. 设置设备属性 6. 设备事件上报 7. 服务调用 ...

  8. 在QTableView中使用各种自定义委托

    QT的MVC(View/Delegate)模型十分强大,可以利用各种控件来对表格的输入进行限制,不过我以前一直没有过,这几天研究了一下,写个小例子,希望大家喜欢. 如果看不懂这个例子,请先看QT的自带 ...

  9. PyQt5之 QTableView 添加复选框(自定义委托)

    import sys from untitled import Ui_Form from PyQt5.QtWidgets import QApplication, QWidget, QStyleOpt ...

随机推荐

  1. JavaScript高级程序设计52.pdf

    表单脚本 表单的基础知识 在HTML中,表单是由<form>元素表示的,在Javascript对应的是HTMLFormElement类型,它继承自HTMLElement,因此具有与其他HT ...

  2. zabbix邮件告警

    Zabbix邮件告警看了很多文档,写的那叫一个蛋疼,明明没有发出去邮件,硬要糊弄观众,我也跟着被糊弄. 操作系统环境: CentOS 5.5 x84_64位 Zabbix版本2.2.3 Web服务器: ...

  3. useradd、passwd、userdel

    useradd是新建用户 userdel -r 是删除用户 passwd是修改密码 groupadd是新建组 groupdel是删除组 useradd yonghu  为添加用户 echo " ...

  4. cdn加速对门户网站产生的影响

    满意的用户体验是门户网站吸引和留住用户的必备条件.据统计,如果等待网页打开的时间超过8秒,将会有超过30%的用户放弃等待,造成严重的用户流失,降低了用户的体验度和忠诚度.门户网站内容涉及面多,涵盖文字 ...

  5. SUSE Linux实现局域网时间同步

    0.前言     需求是这么来的,搭建了Storm集群进行协同过滤算法的计算性能测试,要求精度在毫秒(ms)级别.局域网内40个虚拟机节点,用 date 命令,精度上和效率上都不可行.所以,就搭建了 ...

  6. Cookie案例分析

    一.案例- 显示用户上次访问的时间 当用户第一次访问该页面的时候提示:你好,你是第一次访问本页面,当前时间为:2016-11-3 22:10:30 第n次访问该页面时:欢迎回来,你上次访问的时间是:2 ...

  7. emacs配置详解及C/C++IDE全功能配置演示(附配置文件)

    我的emacs插件下载地址: http://pan.baidu.com/share/link?shareid=4196458904&uk=3708780105 说明: 1.为什么使用emacs ...

  8. 【转】Android Studio 的小小配置

    这篇博文的内容列表: 1.编辑器的字体设置 2.预览XML布局 3.导入项目  4.显示行号  5.新建Java类和Component的子类 额~~程序猿一般话都不多,嘿嘿,那咱就直接图文吧~ ^_^ ...

  9. 80端口被system占用的问题

    80端口被system占用的问题今天启动Apache的时候发现无法启动-80端口被占用. 检查进程发现是system进程id=4给占用了.这个是系统进程 检查服务,看看IIS.没发现问题. 检查了半天 ...

  10. Linux下设置最大文件打开数nofile及nr_open、file-max

    在开发运维的时候我们常常会遇到类似“Socket/File: Can’t open so many files”,“无法打开更多进程”,或是coredump过大等问题,这些都可以设置资源限制来解决.今 ...