基于https://blog.youkuaiyun.com/qq_37735986/article/details/116272226
但是已经完全重构了,修复了原文竖向表头的错误。
因为不知道Qt内部机理,花了大约3天时间,终于成功。基于共享精神发布。
MultiLevelHeaderView.h
#pragma once
#include <QHeaderView>
#include <QModelIndex>
enum MyItemDataRole
{
COLUMN_SPAN_ROLE = Qt::UserRole + 1,
ROW_SPAN_ROLE,
};
class MultiLevelHeaderView : public QHeaderView
{
Q_OBJECT
public:
MultiLevelHeaderView(Qt::Orientation orientation, int rows, int columns, QWidget* parent = 0);
virtual ~MultiLevelHeaderView();
void setRowHeight(int row, int rowHeight);
void setColumnWidth(int col, int colWidth);
void setCellData(int row, int column, int role, const QVariant& value);
// the below methods is just shortcut for setCellData
void setCellSpan(int row, int column, int rowSpanCount, int columnSpanCount);
void setCellBackgroundColor(int row, int column, const QColor&);
void setCellForegroundColor(int row, int column, const QColor&);
void setCellText(int row, int column, const QString& text);
QModelIndex columnSpanIndex(const QModelIndex& currentIndex) const;
QModelIndex rowSpanIndex(const QModelIndex& currentIndex) const;
protected:
// override
virtual void mousePressEvent(QMouseEvent* event) override;
virtual QModelIndex indexAt(const QPoint&);
virtual void paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const override;
virtual QSize sectionSizeFromContents(int logicalIndex) const override;
// inherent features
int columnSpanSize(int row, int from, int spanCount) const;
int rowSpanSize(int column, int from, int spanCount) const;
bool getRootCell(int row, int column, int& rootCellRow, int& rootCellColumn) const;
// (row, column) must be root cell of merged cells
QRect getCellRect(int row, int column) const;
int getSectionRange(QModelIndex& index, int* beginSection, int* endSection) const;
protected slots:
void onSectionResized(int logicalIdx, int oldSize, int newSize);
signals:
void sectionPressed(int from, int to);
};
MultiLevelHeaderView.cpp
#include <set>
#include <QAbstractTableModel>
#include <QMap>
#include <QPainter>
#include <QMouseEvent>
#include <QVariant>
#include <QBrush>
#include <qdrawutil.h>
#include "MultiLevelHeaderView.h"
struct Cell
{
int row = 0;
int column = 0;
bool operator<(const Cell& oth) const
{
if (row < oth.row)
return true;
if (row == oth.row)
return column < oth.column;
return false;
}
};
class MultiLevelHeaderModel : public QAbstractTableModel
{
public:
MultiLevelHeaderModel(Qt::Orientation orientation, int rows, int cols, QObject* parent = 0);
virtual ~MultiLevelHeaderModel();
public:
// override
virtual QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const override;
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex &index, int role) const override;
virtual bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
void setRowHeight(int row, int size);
int getRowHeight(int row) const;
void setColumnWidth(int col, int size);
int getColumnWidth(int col) const;
void setRootCell(int row, int column, int rootRow, int rootColumn);
bool getRootCell(int row, int column, int & rootCellRow, int & rootCellColumn) const;
private:
Qt::Orientation m_orientation;
int m_rowCount;
int m_columnCount;
std::vector<int> m_rowSizes;
std::vector<int> m_columnSizes;
QMap<Cell, QMap<int, QVariant>> m_data;
QMap<Cell, Cell> m_rootCellMap;
};
MultiLevelHeaderModel::MultiLevelHeaderModel(Qt::Orientation orientation, int rows, int cols, QObject* parent) :
QAbstractTableModel(parent), m_orientation(orientation), m_rowCount(rows), m_columnCount(cols)
{
m_rowSizes.resize(rows, 0);
m_columnSizes.resize(cols, 0);
}
MultiLevelHeaderModel::~MultiLevelHeaderModel()
{
}
QModelIndex MultiLevelHeaderModel::index(int row, int column, const QModelIndex & parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
return createIndex(row, column, nullptr);
}
int MultiLevelHeaderModel::rowCount(const QModelIndex &parent) const
{
return m_rowCount;
}
int MultiLevelHeaderModel::columnCount(const QModelIndex &parent) const
{
return m_columnCount;
}
QVariant MultiLevelHeaderModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= m_rowCount || index.row() < 0 || index.column() >= m_columnCount || index.column() < 0)
return QVariant();
auto it = m_data.find({ index.row(), index.column() });
if (it != m_data.end())
{
auto it2 = it.value().find(role);
if (it2 != it.value().end())
return it2.value();
}
// default value
if (role == Qt::BackgroundRole)
return QColor(0xcfcfcf);
if (role == Qt::SizeHintRole)
{
return QSize(m_columnSizes[index.column()], m_rowSizes[index.row()]);
}
return QVariant();
}
bool MultiLevelHeaderModel::setData(const QModelIndex & index, const QVariant & value, int role)
{
if (index.isValid())
{
QVariant value2;
if (role == COLUMN_SPAN_ROLE)
{
int col = index.column();
int span = value.toInt();
if (span > 0) // span size should be more than 1, else nothing to do
{
if (col + span - 1 >= m_columnCount) // span size should be less than whole columns,
span = m_columnCount - col;
value2 = span;
}
}
else if (role == ROW_SPAN_ROLE)
{
int row = index.row();
int span = value.toInt();
if (span > 0) // span size should be more than 1, else nothing to do
{
if (row + span - 1 >= m_rowCount)
span = m_rowCount - row;
value2 = span;
}
}
else
{
value2 = value;
}
if (value.isValid())
{
if (role == Qt::SizeHintRole)
{
m_columnSizes[index.column()] = value.toSize().width();
m_rowSizes[index.row()] = value.toSize().height();
}
else
{
auto& map = m_data[{index.row(), index.column()}];
map.insert(role, value2);
}
}
return true;
}
return false;
}
Qt::ItemFlags MultiLevelHeaderModel::flags(const QModelIndex &index) const
{
return Qt::NoItemFlags | QAbstractTableModel::flags(index);
}
void MultiLevelHeaderModel::setRowHeight(int row, int size)
{
if (row >= 0 && row < m_rowCount)
{
m_rowSizes[row] = size;
emit dataChanged(index(row, 0), index(row, m_columnCount - 1), QVector<int>() << Qt::SizeHintRole);
}
}
int MultiLevelHeaderModel::getRowHeight(int row) const
{
if (row >= 0 && row < m_rowCount)
return m_rowSizes[row];
return 0;
}
void MultiLevelHeaderModel::setColumnWidth(int col, int size)
{
if (col >= 0 && col < m_columnCount)
{
m_columnSizes[col] = size;
emit dataChanged(index(0, col), index(m_rowCount - 1, col), QVector<int>() << Qt::SizeHintRole);
}
}
int MultiLevelHeaderModel::getColumnWidth(int col) const
{
if (col >= 0 && col < m_columnCount)
return m_columnSizes[col];
return 0;
}
void MultiLevelHeaderModel::setRootCell(int row, int column, int rootRow, int rootColumn)
{
Cell c{ row, column };
auto it = m_rootCellMap.find(c);
assert(it == m_rootCellMap.end());
Cell rc{ rootRow, rootColumn };
m_rootCellMap.insert(c, rc);
}
bool MultiLevelHeaderModel::getRootCell(int row, int column, int & rootCellRow, int & rootCellColumn) const
{
Cell c{ row, column };
auto it = m_rootCellMap.find(c);
if(it == m_rootCellMap.end())
return false;
rootCellRow = it.value().row;
rootCellColumn = it.value().column;
return true;
}
MultiLevelHeaderView::MultiLevelHeaderView(Qt::Orientation orientation, int rows, int columns, QWidget* parent) :
QHeaderView(orientation, parent)
{
// create header model
MultiLevelHeaderModel* m = new MultiLevelHeaderModel(orientation, rows, columns);
// set default size of item
if (orientation == Qt::Horizontal)
{
for (int row = 0; row < rows; ++row)
m->setRowHeight(row, 20);
for (int col = 0; col < columns; ++col)
m->setColumnWidth(col, defaultSectionSize());
}
else
{
for (int row = 0; row < rows; ++row)
m->setRowHeight(row, defaultSectionSize());
for (int col = 0; col < columns; ++col)
m->setColumnWidth(col, defaultSectionSize());
}
setModel(m);
connect(this, SIGNAL(sectionResized(int, int, int)), this, SLOT(onSectionResized(int, int, int)));
}
MultiLevelHeaderView::~MultiLevelHeaderView()
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
if (m)
delete m;
setModel(nullptr);
}
void MultiLevelHeaderView::setRowHeight(int row, int rowHeight)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
m->setRowHeight(row, rowHeight);
if (orientation() == Qt::Vertical)
resizeSection(row, rowHeight);
}
void MultiLevelHeaderView::setColumnWidth(int col, int colWidth)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
m->setColumnWidth(col, colWidth);
if (orientation() == Qt::Horizontal)
resizeSection(col, colWidth);
}
void MultiLevelHeaderView::setCellData(int row, int column, int role, const QVariant & value)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
m->setData(m->index(row, column), value, role);
}
void MultiLevelHeaderView::setCellSpan(int row, int column, int rowSpanCount, int columnSpanCount)
{
assert(rowSpanCount > 0);
assert(columnSpanCount > 0);
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
QModelIndex idx = m->index(row, column);
m->setData(idx, rowSpanCount, ROW_SPAN_ROLE);
m->setData(idx, columnSpanCount, COLUMN_SPAN_ROLE);
int lastRow = row + rowSpanCount;
int lastCol = column + columnSpanCount;
for (int i = row; i < lastRow; ++i)
{
for (int j = column; j < lastCol; ++j)
{
m->setRootCell(i, j, row, column);
}
}
}
void MultiLevelHeaderView::setCellBackgroundColor(int row, int column, const QColor& color)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
m->setData(m->index(row, column), color, Qt::BackgroundRole);
}
void MultiLevelHeaderView::setCellForegroundColor(int row, int column, const QColor& color)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
m->setData(m->index(row, column), color, Qt::ForegroundRole);
}
void MultiLevelHeaderView::setCellText(int row, int column, const QString & text)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
m->setData(m->index(row, column), text, Qt::DisplayRole);
}
void MultiLevelHeaderView::mousePressEvent(QMouseEvent* event)
{
QHeaderView::mousePressEvent(event);
QPoint pos = event->pos();
QModelIndex index = indexAt(pos);
const int orient = orientation();
if (index.isValid())
{
int beginSection = -1;
int endSection = -1;
int numbers = 0;
numbers = getSectionRange(index, &beginSection, &endSection);
if (numbers > 0)
{
emit sectionPressed(beginSection, endSection);
return;
}
else
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(this->model());
const int levelCount = (orient == Qt::Horizontal) ? m->rowCount() : m->columnCount();
int logicalIdx = (orient == Qt::Horizontal) ? index.column() : index.row();
int curLevel = (orient == Qt::Horizontal) ? index.row() : index.column();
for (int i = 0; i < levelCount; ++i)
{
QModelIndex cellIndex = (orient == Qt::Horizontal) ? m->index(i, logicalIdx) : m->index(logicalIdx, i);
numbers = getSectionRange(cellIndex, &beginSection, &endSection);
if (numbers > 0)
{
if (beginSection <= logicalIdx && logicalIdx <= endSection)
{
int beginLevel = (orient == Qt::Horizontal) ? cellIndex.row() : cellIndex.column();
QVariant levelSpanCnt = cellIndex.data((orient == Qt::Horizontal) ? ROW_SPAN_ROLE : COLUMN_SPAN_ROLE);
if (!levelSpanCnt.isValid())
continue;
int endLevel = beginLevel + levelSpanCnt.toInt() - 1;
if (beginLevel <= curLevel && curLevel <= endLevel)
{
emit sectionPressed(beginSection, endSection);
break;
}
}
}
}
}
}
}
QModelIndex MultiLevelHeaderView::indexAt(const QPoint& pos)
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(this->model());
const int orient = orientation();
const int ROWS = m->rowCount();
const int COLS = m->columnCount();
int logicalIdx = logicalIndexAt(pos);
if (orient == Qt::Horizontal)
{
int dY = 0;
for (int row = 0; row < ROWS; ++row)
{
dY += m->getRowHeight(row);
if (pos.y() <= dY)
{
QModelIndex cellIndex = m->index(row, logicalIdx);
return cellIndex;
}
}
}
else
{
int dX = 0;
for (int col = 0; col < COLS; ++col)
{
dX += m->getColumnWidth(col);
if (pos.x() <= dX)
{
QModelIndex cellIndex = m->index(logicalIdx, col);
return cellIndex;
}
}
}
return QModelIndex();
}
std::set<Cell> getCellsToBeDrawn(const MultiLevelHeaderView* view, const MultiLevelHeaderModel* m, int orient, int levelCount, int logicalIdx)
{
std::set<Cell> cellsToBeDrawn;
for (int i = 0; i < levelCount; ++i)
{
int row = i, column = logicalIdx;
if (orient == Qt::Vertical)
std::swap(row, column);
int rootRow, rootCol;
if (m->getRootCell(row, column, rootRow, rootCol))
cellsToBeDrawn.insert({ rootRow, rootCol });
}
return cellsToBeDrawn;
}
void MultiLevelHeaderView::paintSection(QPainter* painter, const QRect& rect, int logicalIdx) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(this->model());
const int orient = orientation();
const int levelCount = (orient == Qt::Horizontal) ? m->rowCount() : m->columnCount();
std::set<Cell> cellsToBeDrawn = getCellsToBeDrawn(this, m, orient, levelCount, logicalIdx);
for (const auto& cell: cellsToBeDrawn)
{
QRect sectionRect = getCellRect(cell.row, cell.column);
// draw section with style
QStyleOptionHeader sectionStyle;
initStyleOption(§ionStyle);
sectionStyle.textAlignment = Qt::AlignCenter;
sectionStyle.iconAlignment = Qt::AlignVCenter;
//sectionStyle.section = logicalIdx;
QModelIndex cellIndex = m->index(cell.row, cell.column);
sectionStyle.text = cellIndex.data(Qt::DisplayRole).toString();
sectionStyle.rect = sectionRect;
// file background or foreground color of the cell
QVariant bg = cellIndex.data(Qt::BackgroundRole);
QVariant fg = cellIndex.data(Qt::ForegroundRole);
if (bg.canConvert(QVariant::Brush))
{
sectionStyle.palette.setBrush(QPalette::Button, qvariant_cast<QBrush>(bg));
sectionStyle.palette.setBrush(QPalette::Window, qvariant_cast<QBrush>(bg));
}
if (fg.canConvert(QVariant::Brush))
{
sectionStyle.palette.setBrush(QPalette::ButtonText, qvariant_cast<QBrush>(fg));
}
painter->save();
qDrawShadePanel(painter, sectionStyle.rect, sectionStyle.palette, false, 1, §ionStyle.palette.brush(QPalette::Button));
style()->drawControl(QStyle::CE_HeaderLabel, §ionStyle, painter);
painter->restore();
}
}
QSize MultiLevelHeaderView::sectionSizeFromContents(int logicalIdx) const
{
const MultiLevelHeaderModel* m = static_cast<const MultiLevelHeaderModel*>(this->model());
const int orient = orientation();
const int levelCount = (orient == Qt::Horizontal) ? m->rowCount() : m->columnCount();
int w = 0, h = 0;
if (orient == Qt::Horizontal)
{
w = m->getColumnWidth(logicalIdx);
for (int i = 0; i < levelCount; ++i)
{
h += m->getRowHeight(i);
}
}
else
{
for (int i = 0; i < levelCount; ++i)
{
w += m->getColumnWidth(i);
}
h = m->getRowHeight(logicalIdx);
}
return QSize(w, h);
}
QModelIndex MultiLevelHeaderView::columnSpanIndex(const QModelIndex& currentIdx) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
const int curRow = currentIdx.row();
const int curCol = currentIdx.column();
int i = curCol;
while (i >= 0)
{
QModelIndex spanIndex = m->index(curRow, i);
QVariant span = spanIndex.data(COLUMN_SPAN_ROLE);
if (span.isValid() && spanIndex.column() + span.toInt() - 1 >= curCol)
return spanIndex;
i--;
}
return QModelIndex();
}
QModelIndex MultiLevelHeaderView::rowSpanIndex(const QModelIndex& currentIdx) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
const int curRow = currentIdx.row();
const int curCol = currentIdx.column();
int i = curRow;
while (i >= 0)
{
QModelIndex spanIndex = m->index(i, curCol);
QVariant span = spanIndex.data(ROW_SPAN_ROLE);
if (span.isValid() && spanIndex.row() + span.toInt() - 1 >= curRow)
return spanIndex;
i--;
}
return QModelIndex();
}
int MultiLevelHeaderView::columnSpanSize(int row, int from, int spanCount) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
int span = 0;
for (int i = from; i < from + spanCount; ++i)
{
int colWidth = m->getColumnWidth(i);
span += colWidth;
}
return span;
}
int MultiLevelHeaderView::rowSpanSize(int column, int from, int spanCount) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
int span = 0;
for (int i = from; i < from + spanCount; ++i)
{
int rowHeight = m->getRowHeight(i);
span += rowHeight;
}
return span;
}
bool MultiLevelHeaderView::getRootCell(int row, int column, int & rootCellRow, int & rootCellColumn) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(this->model());
return m->getRootCell(row, column, rootCellRow, rootCellColumn);
}
QRect MultiLevelHeaderView::getCellRect(int row, int column) const
{
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(this->model());
const int orient = orientation();
QModelIndex cellIndex = m->index(row, column);
auto colSpanVar = cellIndex.data(COLUMN_SPAN_ROLE);
auto rowSpanVar = cellIndex.data(ROW_SPAN_ROLE);
assert(colSpanVar.isValid() && rowSpanVar.isValid());
int colSpan = colSpanVar.toInt();
int rowSpan = rowSpanVar.toInt();
int w = 0, h = 0, l = 0, t = 0;
w = columnSpanSize(row, column, colSpan);
h = rowSpanSize(column, row, rowSpan);
if (orient == Qt::Horizontal)
{
l = sectionViewportPosition(column);
for (int i = 0; i < row; ++i)
t += m->getRowHeight(i);
}
else
{
for (int i = 0; i < column; ++i)
l += m->getColumnWidth(i);
t = sectionViewportPosition(row);
}
QRect rect(l, t, w, h);
return rect;
}
/**
* @return section numbers
*/
int MultiLevelHeaderView::getSectionRange(QModelIndex& index, int* beginSection, int* endSection) const
{
int row = index.row(), column = index.column();
int rootRow, rootCol;
bool success = getRootCell(row, column, rootRow, rootCol);
if (!success)
return 0;
const MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(model());
QModelIndex rootIndex = m->index(rootRow, rootCol);
if (orientation() == Qt::Horizontal)
{
int colSpanCnt = rootIndex.data(COLUMN_SPAN_ROLE).toInt();
*beginSection = rootIndex.column();;
*endSection = *beginSection + colSpanCnt - 1;
index = rootIndex;
return colSpanCnt;
}
else
{
int rowSpanCnt = rootIndex.data(ROW_SPAN_ROLE).toInt();
*beginSection = rootIndex.row();;
*endSection = *beginSection + rowSpanCnt - 1;
index = rootIndex;
return rowSpanCnt;
}
}
void MultiLevelHeaderView::onSectionResized(int logicalIndex, int oldSize, int newSize)
{
MultiLevelHeaderModel* m = static_cast<MultiLevelHeaderModel*>(this->model());
const int orient = orientation();
const int levelCount = (orient == Qt::Horizontal) ? m->rowCount() : m->columnCount();
if (orient == Qt::Horizontal)
{
m->setColumnWidth(logicalIndex, newSize);
}
else
{
m->setRowHeight(logicalIndex, newSize);
}
std::set<Cell> cellsToBeDrawn = getCellsToBeDrawn(this, m, orient, levelCount, logicalIndex);
for (const auto& cell : cellsToBeDrawn)
{
QRect sectionRect = getCellRect(cell.row, cell.column);
if (orient == Qt::Horizontal)
{
sectionRect.setWidth(viewport()->width() - sectionRect.left());
}
else
{
sectionRect.setHeight(viewport()->height() - sectionRect.top());
}
viewport()->update(sectionRect);
}
}
main.cpp
#include <QApplication>
#include <QStandardItemModel>
#include <QTableView>
#include "MultiLevelHeaderView.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTableView tableView;
auto pView = &tableView;
pView->setContextMenuPolicy(Qt::CustomContextMenu);
bool horizontal = false;
if (horizontal)
{
auto pHeader = new MultiLevelHeaderView(Qt::Horizontal, 3, 8, pView);
pHeader->setCellSpan(0, 0, 1, 4);
pHeader->setCellSpan(0, 4, 1, 4);
pHeader->setCellSpan(1, 0, 1, 2);
pHeader->setCellSpan(1, 2, 1, 2);
pHeader->setCellSpan(1, 4, 1, 2);
pHeader->setCellSpan(1, 6, 1, 2);
for (int i = 0; i < 8; i++)
{
pHeader->setCellSpan(2, i, 1, 1);
}
//一级
pHeader->setCellText(0, 0, QString(u8"横向尺寸"));
pHeader->setCellText(0, 4, QString(u8"纵向尺寸"));
//二级
pHeader->setCellText(1, 0, QStringLiteral("极耳宽度"));
pHeader->setCellText(1, 2, QStringLiteral("极耳高度"));
pHeader->setCellText(1, 4, QStringLiteral("极片宽度"));
pHeader->setCellText(1, 6, QStringLiteral("极耳间距"));
//三级
pHeader->setCellText(2, 0, QStringLiteral("CCD测量值"));
pHeader->setCellText(2, 1, QStringLiteral("真值"));
pHeader->setCellText(2, 2, QStringLiteral("CCD测量值"));
pHeader->setCellText(2, 3, QStringLiteral("真值"));
pHeader->setCellText(2, 4, QStringLiteral("CCD测量值"));
pHeader->setCellText(2, 5, QStringLiteral("真值"));
pHeader->setCellText(2, 6, QStringLiteral("CCD测量值"));
pHeader->setCellText(2, 7, QStringLiteral("真值"));
pHeader->setMinimumHeight(90);
for (int i = 0; i < 3; ++i)
pHeader->setRowHeight(i, 30);
//m_pHeader->setMinimumHeight(60);
pHeader->setSectionsClickable(false);
pHeader->setCellBackgroundColor(0, 0, 0xffcfcf);
pHeader->setCellBackgroundColor(0, 4, 0xcfcfcf);
pHeader->setCellBackgroundColor(1, 0, 0xcfcfcf);
pHeader->setCellBackgroundColor(1, 2, 0xcfcfcf);
pHeader->setCellBackgroundColor(1, 4, 0xcfcfcf);
pHeader->setCellBackgroundColor(1, 6, 0xcfcfcf);
for (int i = 0; i < 8; i++)
{
pHeader->setCellBackgroundColor(2, i, 0xcfcfcf);
}
int rowCount = 10;
auto m_pDataModel = new QStandardItemModel;
for (int i = 0; i < rowCount; i++)
{
QList<QStandardItem*> items;
for (int j = 0; j < 8; j++)
{
items.append(new QStandardItem);
}
m_pDataModel->appendRow(items);
}
pView->setModel(m_pDataModel);
pView->setHorizontalHeader(pHeader);
}
else
{
auto pHeader = new MultiLevelHeaderView(Qt::Vertical, 8, 3, pView);
pHeader->setCellSpan(0, 0, 4, 1);
pHeader->setCellSpan(4, 0, 4, 1);
pHeader->setCellSpan(0, 1, 2, 1);
pHeader->setCellSpan(2, 1, 2, 1);
pHeader->setCellSpan(4, 1, 2, 1);
pHeader->setCellSpan(6, 1, 2, 1);
for (int i = 0; i < 8; i++)
{
pHeader->setCellSpan(i, 2, 1, 1);
}
//一级
pHeader->setCellText(0, 0, QString(u8"横\n向\n尺\n寸"));
pHeader->setCellText(4, 0, QString(u8"纵\n向\n尺\n寸"));
//二级
pHeader->setCellText(0, 1, QStringLiteral("极耳宽度"));
pHeader->setCellText(2, 1, QStringLiteral("极耳高度"));
pHeader->setCellText(4, 1, QStringLiteral("极片宽度"));
pHeader->setCellText(6, 1, QStringLiteral("极耳间距"));
//三级
pHeader->setCellText(0, 2, QStringLiteral("CCD测量值"));
pHeader->setCellText(1, 2, QStringLiteral("真值"));
pHeader->setCellText(2, 2, QStringLiteral("CCD测量值"));
pHeader->setCellText(3, 2, QStringLiteral("真值"));
pHeader->setCellText(4, 2, QStringLiteral("CCD测量值"));
pHeader->setCellText(5, 2, QStringLiteral("真值"));
pHeader->setCellText(6, 2, QStringLiteral("CCD测量值"));
pHeader->setCellText(7, 2, QStringLiteral("真值"));
pHeader->setMinimumHeight(90);
pHeader->setMinimumWidth(30);
for (int i = 0; i < 3; ++i)
pHeader->setColumnWidth(i, 30);
for (int i = 0; i < 8; ++i)
pHeader->setRowHeight(i, 30);
//m_pHeader->setMinimumHeight(60);
pHeader->setSectionsClickable(false);
int rowCount = 8;
auto m_pDataModel = new QStandardItemModel;
for (int i = 0; i < rowCount; i++)
{
QList<QStandardItem*> items;
for (int j = 0; j < 6; j++)
{
items.append(new QStandardItem);
}
m_pDataModel->appendRow(items);
}
pView->setModel(m_pDataModel);
pView->setVerticalHeader(pHeader);
}
pView->show();
return a.exec();
}