QT QTableView 委托:垂直表头

QTableView使用自定义委托(QItemDelegate)
Qt自定义委托在QTableView中绘制控件、图片、文字
QT QTbaleView移除网线

场景

如图所示
我需要在垂直及水平表头显示 很长的信息,但是,如果文字过长,这个表也会被拉很长。
实际上这个表是一个矩阵,最好用正方形显示
在这里插入图片描述
最方便的方法就是,水平表头可以旋转文字,使得文字垂直显示。但是我没有找到很好的代码

于是我只能用 QStyledItemDelegate托管,把本来要显示在水平表头的文字,显示在最后一行,并用QStyledItemDelegate绘制竖直文字

QStyledItemDelegate 委托最重要的就是重写函数

void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;

因为我是最后一行需要 旋转文字,所以还需要一个成员变量记录哪一行需要旋转
std::set m_rowSet;

我们判断QModelIndex& index行号,如果在m_rowSet就旋转文字,并且去掉网格线

		QPen pen_black;
		pen_black.setWidth(2);
		pen_black.setColor(QColor(Qt::black));
		painter->save();//显将画笔属性进行保存
		painter->translate(x + 3 * width, y);//将原点移动到要画文字的地方
		qDebug() << x << " , " << y;
		painter->rotate(90);//将画笔翻转90度
		QString text = index.model()->data(index, Qt::DisplayRole).toString();
		int h = QFontMetrics(painter->font()).width(text);
		QRectF rect(10, 0, 100, 200);
		painter->setPen(pen_black);

如果是普通的行:
画出网格线,

QStyledItemDelegate::paint(painter, option, index);
painter->save();//显将画笔属性进行保存
QPen LinePen;
LinePen.setWidth(2);
LinePen.setColor(QColor(250,250,250));
painter->setPen(LinePen);
painter->drawLine(option.rect.topRight(), option.rect.bottomRight());//显示垂直网格线
painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());//显示水平网格线
painter->restore();//恢复画笔原有属性

源码

class LineDelegate : public QStyledItemDelegate
{
public:
	LineDelegate(QObject* parent = 0);
	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
	void setVerticalRow(std::set<int> rowSet);
	QColor getColor(int value, int max) const;
private:
	std::set<int>  m_rowSet;
};
LineDelegate::LineDelegate(QObject* parent ) : QStyledItemDelegate(parent)
{

}
 
void LineDelegate::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();

	if (m_rowSet.find(row) != m_rowSet.end())
	{
		
		QPen pen_black;
		pen_black.setWidth(2);
		pen_black.setColor(QColor(Qt::black));
		painter->save();//显将画笔属性进行保存
		painter->translate(x + 3 * width, y);//将原点移动到要画文字的地方
		qDebug() << x << " , " << y;
		painter->rotate(90);//将画笔翻转90度
		QString text = index.model()->data(index, Qt::DisplayRole).toString();
		int h = QFontMetrics(painter->font()).width(text);
		QRectF rect(10, 0, 100, 200);
		painter->setPen(pen_black);
 
		QTextOption textOption;
		textOption.setAlignment(Qt::AlignVCenter);
		qDebug() << rect;
		painter->drawText(/*option.*/rect, text, textOption);
		painter->restore();//恢复画笔原有属性
	}
	else
	{
		//画出网格线,
		QStyledItemDelegate::paint(painter, option, index);
		painter->save();//显将画笔属性进行保存
		QPen LinePen;
		LinePen.setWidth(2);
		LinePen.setColor(QColor(250,250,250));
		painter->setPen(LinePen);
		painter->drawLine(option.rect.topRight(), option.rect.bottomRight());//显示垂直网格线
		painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());//显示水平网格线
		painter->restore();//恢复画笔原有属性
		
		painter->save();
		int value = index.model()->data(index, Qt::DisplayRole).toInt();
		int max = index.model()->data(index, Qt::UserRole + 1).toInt();
		QColor  bColor = getColor(value, max);
		//画背景颜色
		painter->fillRect(option.rect, QBrush(bColor));
		//画文字
		QTextOption op;
		LinePen.setColor(Qt::red);
		painter->setPen(LinePen);
		painter->drawText(x, y, width, height, Qt::AlignCenter, index.data(Qt::DisplayRole).toString());
		painter->restore();//恢复画笔原有属性
	}
}
void LineDelegate::setVerticalRow(std::set<int> rowSet)
{
	m_rowSet = rowSet;
}

QColor LineDelegate::getColor(int value, int max) const
{
	int colorvalue = 255 - int(255 * float(value) / float(max));//黑色 rgb(0,0,0)
	QColor color(colorvalue, colorvalue, colorvalue);
	return color;
}

应用:

QTableView trainTable ;
	 
LineDelegate trainLineDelegate;
......
trainTable.setItemDelegate(&trainLineDelegate);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值