QTableView之二:常用用法
效果图
代码下载
GitHub 下载地址:https://github.com/confidentFeng/QtAppProject
添加项
void addItem(QString name); // 添加项
// 添加项
void Widget::addItem(QString name)
{
// 准备数据模型
QList<QStandardItem *> listItems;
// 名称(包括勾选框)
QStandardItem *pItemName = new QStandardItem(name);
pItemName->setCheckable(true);
pItemName->setCheckState(Qt::Unchecked);
// 年龄
QStandardItem *pItemAge = new QStandardItem("25");
// 图标
QStandardItem *pItemIcon = new QStandardItem(QIcon(":/Image/icon_camera_checked.png"), "");
// 添加到数据模型
listItems << pItemName << pItemAge << pItemIcon;
m_pMyTableView->getModel()->appendRow(listItems); // 加载一行数据
// 设置各列的宽度
if(m_pMyTableView->getModel()->rowCount() > ITEM_MAX_COUNT)
m_pMyTableView->setColumnWidth(0, 200-8);
else
m_pMyTableView->setColumnWidth(0, 200);
m_pMyTableView->setColumnWidth(1, 60);
m_pMyTableView->setColumnWidth(2, 60);
}
实时获取选中的复选框数目
// 复选框改变也会触发itemChanged信号
connect(m_pMyTableView->getModel(), &QStandardItemModel::itemChanged, [=](QStandardItem *item) {
// 实时获取选中的复选框数目
int checkedCount = 0;
for(int i=0; i < m_pMyTableView->getModel()->rowCount(); i++)
if(m_pMyTableView->getModel()->item(i, 0)->isEnabled() &&
Qt::Checked == m_pMyTableView->getModel()->index(i, 0).data(Qt::CheckStateRole))
checkedCount++;
//qDebug() << "QStandardItemModel::itemChanged: " << checkedCount;
// 复选框选中时,同时选中当前行
m_pMyTableView->selectRow(item->index().row());
});
获取多选的item
void getMultiCheckItem(); // 获取多选的item
// 获取多选的item
void MainWidget::getMultiCheckItem()
{
QStandardItemModel *standardModel = new QStandardItemModel(this);
QItemSelectionModel *selectModel = new QItemSelectionModel(standardModel);
// 第一种方法: 通过 QItemSelectionModel
if(!selectModel->hasSelection())
return;
QModelIndexList modelList1 = selectModel->selectedIndexes();
// 第二种方法: 通过tableView
QModelIndexList modelList2 = m_pMyTableView->selectionModel()->selectedIndexes();
foreach(QModelIndex index, modelList1)
{
QStandardItem *item = standardModel->itemFromIndex(index);
QFont font = item->font();
font.setBold(!font.bold());
item->setFont(font);
}
}
获取viewPort当前显示的可见的第一行和最后一行
int getViewFirstNumber(); // 获取viewPort当前显示的可见的第一行
int getViewLastNumber(); // 获取viewPort当前显示的可见的最后一行
// 获取viewPort当前显示的可见的第一行
int MainWidget::getViewFirstNumber()
{
return m_pMyTableView->verticalScrollBar()->value();
}
// 获取viewPort当前显示的可见的最后一行
int MainWidget::getViewLastNumber()
{
return m_pMyTableView->verticalScrollBar()->value() + m_pMyTableView->verticalScrollBar()->pageStep();
}
支持右键菜单
QAction *m_actionAdd;
QAction *m_actionDel;
QMenu *m_popMenu; // 右键菜单
// 创建多个动作
m_actionAdd = new QAction;
m_actionDel = new QAction;
m_actionAdd->setText(tr("添加数据"));
m_actionDel->setText(tr("删除数据"));
// 创建右键菜单
m_popMenu = new QMenu(m_pMyTableView);
m_popMenu->addAction(m_actionAdd);
m_popMenu->addAction(m_actionDel);
// QAction绑定槽函数,当点击QAction时触发
connect(m_actionAdd, &QAction::triggered, [=] {
addItem("王五");
});
connect(m_actionDel, &QAction::triggered, [=] {
m_pMyTableView->getModel()->removeRow(m_pMyTableView->currentIndex().row());
});
// m_pMyTableView设置可弹出右键菜单
m_pMyTableView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_pMyTableView, &QTableView::customContextMenuRequested, [=] {
// 检测是否有选中项 && 选中项是否有效
if (m_pMyTableView->selectionModel()->hasSelection() && m_pMyTableView->currentIndex().isValid())
m_popMenu->exec(QCursor::pos());
});
实现双击item功能
QTimer *m_pTimerMouseOut; // 鼠标双击超时检测定时器
int m_nCntDouble = 0; // 按键计数
QString m_userClicked = ""; // 第一次点击对应的用户
// 鼠标双击超时检测定时器
m_pTimerMouseOut = new QTimer(this);
m_pTimerMouseOut->setSingleShot(true);
connect(m_pTimerMouseOut, &QTimer::timeout, [=]{
m_nCntDouble = 0;
m_pTimerMouseOut->stop();
m_userClicked = "";
});
// 双击
connect(m_pMyTableView, &QTableView::clicked, [=](const QModelIndex &index){
//qDebug() << "clicked: " << index.row() << m_pMyTableView->getModel()->item(m_pMyTableView->getModel()->index(index.row(), 0))->statusTip();
QString curText = m_pMyTableView->getModel()->item(index.row(), 0)->text();
if(m_userClicked != curText)
m_pTimerMouseOut->start(400);
m_nCntDouble++;
if(m_nCntDouble >= 2) {
m_nCntDouble = 0;
m_pTimerMouseOut->stop();
// 如果item已被禁用,则返回
if(!m_pMyTableView->getModel()->item(index.row(), 0)->isEnabled())
return;
// 如果两次点击的用户名都相同
if(m_userClicked == curText) {
qDebug() << "double clicked Success";
// 进行双击操作
}
m_userClicked = "";
return;
}
m_userClicked = curText;
});
支持上下方向、Home、End、翻页键功能
int m_curScrollPos = 0; // 翻页时的当时滑动条位置
int m_pageHeight = 39*10; // 一页的高度(39为一行的高度,10为一页的行数)
// 键盘按下事件
void Widget::keyPressEvent(QKeyEvent *event)
{
// 自定义实现QTableView的上下方向键功能
if(event->key() == Qt::Key_Up) {
int curRow = m_pMyTableView->currentIndex().row();
curRow--;
if(curRow < 0)
curRow = m_pMyTableView->model()->rowCount()-1;
QModelIndex nextIndex = m_pMyTableView->model()->index(curRow, 0);
m_pMyTableView->setCurrentIndex(nextIndex);
return;
}
if(event->key() == Qt::Key_Down) {
int curRow = m_pMyTableView->currentIndex().row();
curRow++;
if(curRow > m_pMyTableView->model()->rowCount()-1)
curRow = 0;
QModelIndex nextIndex = m_pMyTableView->model()->index(curRow, 0);
m_pMyTableView->setCurrentIndex(nextIndex);
return;
}
if(event->key() == Qt::Key_Home) { // Home键跳转到第一行
QModelIndex nextIndex = m_pMyTableView->model()->index(0, 0);
m_pMyTableView->setCurrentIndex(nextIndex);
return;
}
if(event->key() == Qt::Key_End) { // End键跳转到最后一行
QModelIndex nextIndex = m_pMyTableView->model()->index(m_pMyTableView->model()->rowCount()-1, 0);
m_pMyTableView->setCurrentIndex(nextIndex);
return;
}
if(event->key() == Qt::Key_PageUp) { // PageUp键向上翻页
m_curScrollPos = m_pMyTableView->verticalScrollBar()->value();
if(m_curScrollPos > 0)
m_pMyTableView->verticalScrollBar()->setSliderPosition(m_curScrollPos - m_pageHeight);
return;
}
if(event->key() == Qt::Key_PageDown) { // PageUp键向下翻页
int maxValue = m_pMyTableView->verticalScrollBar()->maximum(); // 当前scroller最大显示值
m_curScrollPos = m_pMyTableView->verticalScrollBar()->value(); // 获得当前scroller值
if(m_curScrollPos < maxValue)
m_pMyTableView->verticalScrollBar()->setSliderPosition(m_pageHeight + m_curScrollPos);
return;
}
else
event->ignore(); // 不加上这句,其它键盘事件会失效
}
设置单元格内边距
// 子类化QProxyStyle,重写pixelMetric函数,已实现内边距(qss设置内边距不生效)
class TableItemSpaceStyleName : public QProxyStyle
{
public:
explicit TableItemSpaceStyleName(QWidget *parent = nullptr) { Q_UNUSED(parent); };
int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const
{
switch (metric) {
case PM_FocusFrameHMargin:
return 6; // 设置内边距为6
default:
break;
}
return QProxyStyle::pixelMetric(metric, option, widget);
}
};
m_pMyTableView->setStyle(new TableItemSpaceStyleName); // 设置单元格内边距
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2018-09-30 C语言小项目-火车票订票系统