123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- #include "tableviewex.h"
- #include <QScrollBar>
- #include <QTimer>
- #include <QHeaderView>
- TableViewEx::TableViewEx(QWidget *parent)
- : QTableView(parent)
- {
- //设置model
- setModel(&m_model);
- //设置所有单元格不可编辑(注意: 设计器里不能设置, 否则这里的设置不生效, 因为在setupUi里先执行了构造函数再执行设置方法)
- setEditTriggers(QAbstractItemView::NoEditTriggers);
- //设置右键菜单模式(注意: 设计器里不能设置, 否则这里的设置不生效, 因为在setupUi里先执行了构造函数再执行设置方法)
- setContextMenuPolicy(Qt::CustomContextMenu);
- //禁用滚动条右键菜单
- verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
- horizontalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
- //冻结横向滚动条, 否则点击未完全显示的单元格时, 表格会自动滚动来让单元格完全显示
- // setHorizontalScrollBar(new FrozenScrollBar(this));
-
- //选中时选中一行
- setSelectionBehavior(QAbstractItemView::SelectRows);
- //SetDragEnable(false);
- }
- void TableViewEx::ClearModel()
- {
- m_model.clear();
- SetHeaders();
- //m_model.ClearHTMLContent();
- }
- bool TableViewEx::RemoveRow(int row)
- {
- bool isSelected = (currentIndex().row() == row);
-
- //这里使用model()来删除, 如果使用了代理model, 删除代理model的时候, 源model的行也会被删除
- model()->removeRow(row);
-
- if(isSelected && model()->rowCount() != 0)
- {
- SetCurrentRow(0);
- }
- if(m_verticalScrollBar != nullptr)
- {
- QModelIndex topLeft = model()->index(row, 0);
- QModelIndex bottomRight = model()->index(row, model()->columnCount() - 1);
- emit model()->dataChanged(topLeft, bottomRight);
- }
- return true;
- }
- bool TableViewEx::RemoveRow(const QModelIndex &index)
- {
- return RemoveRow(index.row());
- }
- bool TableViewEx::IsEmpty(bool forSourceModel)
- {
- QAbstractItemModel *pModel = GetModel(forSourceModel);
- return (pModel->rowCount() == 0);
- }
- void TableViewEx::SetCurrentRow(int row)
- {
- /*----------------------------------------------------------------
- * 这里必须要使用model()->index(..)来获取index, 因为model()取到的才是实际的model
- * 假如这个tableview使用了代理model, 则model()是代理的model, 而m_model则是源model
- ----------------------------------------------------------------*/
- setCurrentIndex(model()->index(row, 0));
- }
- QAbstractItemModel *TableViewEx::GetModel(bool sourceModel)
- {
- return sourceModel?(&m_model):model();
- }
- void TableViewEx::OnScrollBarDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
- {
- Q_UNUSED(topLeft);
- Q_UNUSED(bottomRight);
- Q_UNUSED(roles);
- if(m_verticalScrollBar != nullptr)
- {
- //获取视图的大小
- QSize viewportSize = viewport()->size();
- //获取总行数
- int nRowCount = model()->rowCount();
- int nTotalRowHeight = 0;
- //计算总行高
- for(int row = 0; row < nRowCount; ++row)
- {
- nTotalRowHeight += rowHeight(row);
- }
- //判断是否需要显示滚动条
- bool bNeedScrollBar = nTotalRowHeight > viewportSize.height();
- QTimer::singleShot(0, this, [=]() {
- if(bNeedScrollBar)
- {
- //判断表头是否显示
- if(horizontalHeader()->isVisible())
- {
- //在布局完成后设置垂直滚动条范围
- m_verticalScrollBar->resize(QSize(6, height() - 48));
- m_verticalScrollBar->move(width() - 6, 48);
- m_verticalScrollBar->setRange(this->verticalScrollBar()->minimum(), this->verticalScrollBar()->maximum());
- m_verticalScrollBar->show();
- }
- else
- {
- //在布局完成后设置垂直滚动条范围
- m_verticalScrollBar->resize(QSize(6, height()));
- m_verticalScrollBar->move(width() - 6, 0);
- m_verticalScrollBar->setRange(this->verticalScrollBar()->minimum(), this->verticalScrollBar()->maximum());
- m_verticalScrollBar->show();
- }
- }
- else
- {
- m_verticalScrollBar->hide();
- }
- });
- }
- if(m_horizontalScrollBar != nullptr)
- {
- //获取视图的大小
- QSize viewportSize = viewport()->size();
- //获取总列数
- int nColCount = model()->columnCount();
- QTimer::singleShot(0, this, [=]() {
- int nTotalColWidth = 0;
- //计算总列宽
- for(int col = 0; col < nColCount; ++col)
- {
- nTotalColWidth += columnWidth(col);
- }
- //判断是否需要显示滚动条
- bool bNeedScrollBar = nTotalColWidth > viewportSize.width();
- if(bNeedScrollBar)
- {
- //在布局完成后设置横向滚动条范围
- m_horizontalScrollBar->resize(QSize(width(), 6));
- m_horizontalScrollBar->move(0, height() - 6);
- m_horizontalScrollBar->setRange(this->horizontalScrollBar()->minimum(), this->horizontalScrollBar()->maximum());
- m_horizontalScrollBar->show();
- }
- else
- {
- m_horizontalScrollBar->hide();
- }
- });
- }
- }
- void TableViewEx::OnModelReset()
- {
- if(m_verticalScrollBar)
- {
- m_verticalScrollBar->hide();
- }
- if(m_horizontalScrollBar)
- {
- m_horizontalScrollBar->hide();
- }
- }
- void TableViewEx::SetVerticalScrollBar(bool bIsNeed)
- {
- if(bIsNeed && m_verticalScrollBar == nullptr)
- {
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- //自定义滚动条
- m_verticalScrollBar = new QScrollBar(Qt::Orientation::Vertical, this);
- connect(this->verticalScrollBar(), &QScrollBar::valueChanged, m_verticalScrollBar, &QScrollBar::setValue);
- connect(m_verticalScrollBar, &QScrollBar::sliderMoved, this->verticalScrollBar(), &QScrollBar::setSliderPosition);
- connect(m_verticalScrollBar, &QScrollBar::valueChanged, this->verticalScrollBar(), &QScrollBar::setValue);
- m_verticalScrollBar->hide();
- m_verticalScrollBar->setContextMenuPolicy(Qt::NoContextMenu);
- connect(model(), &QAbstractItemModel::dataChanged, this, &TableViewEx::OnScrollBarDataChanged, Qt::UniqueConnection);
- connect(model(), &QAbstractItemModel::modelReset, this, &TableViewEx::OnModelReset, Qt::UniqueConnection);
- }
- else
- {
- if(m_verticalScrollBar != nullptr)
- {
- delete m_verticalScrollBar;
- m_verticalScrollBar = nullptr;
- }
- }
- }
- void TableViewEx::SetHorizontalScrollBar(bool bIsNeed)
- {
- if(bIsNeed && m_horizontalScrollBar == nullptr)
- {
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- //自定义滚动条
- m_horizontalScrollBar = new QScrollBar(Qt::Orientation::Horizontal, this);
- connect(this->horizontalScrollBar(), &QScrollBar::valueChanged, m_horizontalScrollBar, &QScrollBar::setValue);
- connect(m_horizontalScrollBar, &QScrollBar::sliderMoved, this->horizontalScrollBar(), &QScrollBar::setSliderPosition);
- connect(m_horizontalScrollBar, &QScrollBar::valueChanged, this->horizontalScrollBar(), &QScrollBar::setValue);
- m_horizontalScrollBar->hide();
- m_horizontalScrollBar->setContextMenuPolicy(Qt::NoContextMenu);
- connect(model(), &QAbstractItemModel::dataChanged, this, &TableViewEx::OnScrollBarDataChanged, Qt::UniqueConnection);
- connect(model(), &QAbstractItemModel::modelReset, this, &TableViewEx::OnModelReset, Qt::UniqueConnection);
- }
- else
- {
- if(m_horizontalScrollBar != nullptr)
- {
- delete m_horizontalScrollBar;
- m_horizontalScrollBar = nullptr;
- }
- }
- }
|