您的位置:首页 > 编程语言 > Qt开发

QTableView使用自定义委托(QItemDelegate)

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

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

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

如下是实现效果图



/********************ArrowDelegate********************/
class ArrowDelegate : public QItemDelegate
{
Q_OBJECT

public:

ArrowDelegate(QObject* parent = 0);
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 = 0);
~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 = 0);//:QHeaderView(Qt::Horizontal, parent)

protected:
void mouseReleaseEvent(QMouseEvent *e);

signals:
void refresh();
};
/********************ReadOnlyTableView********************/
class MyTableView : public QTableView
{
Q_OBJECT

public:

MyTableView(QWidget *parent=0);
~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 = 0;
}

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(2);
pen_black.setColor(QColor(Qt::black));
QStyleOptionViewItem myOption = option;

if (index.column() == 2)//UE
{
QPainterPath path_UE;

QPoint One;
QPoint Two;
//        pen.setWidth(2);
One.setX(x + width / 2);
One.setY(y);
Two.setX(x + width / 2);
Two.setY(y + height);
path_UE.moveTo(One);
path_UE.lineTo(Two);
painter->setPen(pen_black);
painter->drawPath(path_UE);
}

if (index.column() == 3)
{
g_x = x + width / 2;//get the begin
QPainterPath path_SENB;

QPoint One;
QPoint Two;
One.setX(x + width / 2);
One.setY(y);
Two.setX(x + width / 2);
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() == 4)
{
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 / 2);
One.setY(y);
Two.setX(x + width / 2);
Two.setY(y + height);
path_TENB.moveTo(One);
path_TENB.lineTo(Two);
painter->setPen(pen_black);
painter->drawPath(path_TENB);
}
}

if (index.column() == 5)
{
QPainterPath path,path_SMME;
QPen pen;
QPoint One;
QPoint Two;
//        pen5.setWidth(2);
One.setX(x + width / 2);
One.setY(y);
Two.setX(x + width / 2);
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(0);
int direction = strList.at(1).toInt();

myOption.displayAlignment = Qt::AlignCenter;

QRectF rect;
pen.setWidth(1);
if (direction)
{
pen.setColor(QColor(255,0,0));//red
//            One.setX(x);
//            One.setY(y + 3 * height / 4);
One.setX(g_x);
One.setY(y + 3 * height / 4);
Two.setX(x + width / 2);
Two.setY(y + 3 * height / 4);
//            painter->drawText(One,text);
}
else
{
pen.setColor(QColor(0,0,255));
//            Two.setX(x);
//            Two.setY(y + 3 * height / 4);
Two.setX(g_x);
Two.setY(y + 3 * height / 4);
One.setX(x + width / 2);
One.setY(y + 3 * height / 4);
//            painter->drawText(Two,text);
}

int Height = 20;
//        QPoint Three(x + width / 2 , y + height / 3);

double slopy , cosy , siny;
double Par = Height/2;
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 / 2,y + height / 2));
//        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() > 0)
return vertical_header_list.size();

if(NULL == arr_row_list)
return 0;
else
return arr_row_list->size();
}

int TableModel::columnCount(const QModelIndex &parent) const
{
if(horizontal_header_list.size() > 0)
return horizontal_header_list.size();

if(NULL == arr_row_list)
return 0;
else if(arr_row_list->size() < 1)
return 0;
else
return arr_row_list->at(0).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() < 1)
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(0).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 <= 0)
return;

QList<int> list_row;
for(int i=model_count-1; i>=0; 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()-1; i>=0; 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事件,即鼠标释放,表格中的内容动态变化
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: