ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

QTableWidget 实战:自动换行且行高自适应的完整方案

QTableWidget 实战:自动换行且行高自适应的完整方案 QTableWidget 实战让最后一列自动换行且行高自适应的完整方案场景表格最后一列是长文本如学习感悟每条 100~200 字要求文字超宽自动换行、行高自动撑开、所有列宽可拖动、拖动后换行即时重排、且不出现横向滚动条。环境Qt5Qt4 兼容写法附后MSVC。一、先看坑只设setWordWrap(true)是不够的很多人以为给表格加上一句m_table-setWordWrap(true);长文本就会自动换行显示完整。实际跑起来会发现两种翻车文字被省略号截断…—— 行高还是单行高度超出的部分被 elide 掉了拖动列宽后版式错乱—— 换行是换行了但行高停留在旧值要么文字被切掉一半要么大片空白。原因wordWrap只负责绘制时换行行高不会随列宽变化自动重算。Qt 的行高来自sizeHintForRow()它只在内容变化时主动刷新列宽变化时不会。所以要得到正确效果需要一套组合拳。二、完整实现步骤步骤 1开启换行 行高按内容自适应m_table-setWordWrap(true);// 单元格文字允许换行QTableView 默认就是 true显式写出更稳妥// 行高跟随内容含换行后的实际高度#ifQT_VERSIONQT_VERSION_CHECK(5,0,0)m_table-verticalHeader()-setSectionResizeMode(QHeaderView::ResizeToContents);#elsem_table-verticalHeader()-setResizeMode(QHeaderView::ResizeToContents);// Qt4 旧接口#endifResizeToContents让每一行的高度等于该行的sizeHint——当wordWrap开启时委托delegate会按当前列宽把文本折行后再计算所需高度这是整套方案的依据。步骤 2列宽策略——全部可拖动最后一列吃满剩余宽度QHeaderView*hHeaderm_table-horizontalHeader();#ifQT_VERSIONQT_VERSION_CHECK(5,0,0)hHeader-setSectionResizeMode(QHeaderView::Interactive);// 三列都可拖动调宽#elsehHeader-setResizeMode(QHeaderView::Interactive);#endifhHeader-setStretchLastSection(true);// 最后一列占满剩余宽度消灭横向滚动条m_table-setColumnWidth(0,100);// 学号列初始宽m_table-setColumnWidth(1,100);// 姓名列初始宽两个要点不要用ResizeToContents做列宽模式它会在内容变化时自动重设列宽把用户手动拖的宽度冲掉setStretchLastSection(true)让表格总宽始终贴合可视区这是不出现横向滚动条的关键。用户仍然可以拖动最后一列只是窗口尺寸变化时它会重新伸缩。步骤 3新增数据后刷新行高constintrowm_table-rowCount();m_table-insertRow(row);m_table-setItem(row,2,newQTableWidgetItem(longText));m_table-resizeRowToContents(row);// 让新行立刻获得正确高度步骤 4核心列宽被拖动后手动触发行高重算这就是解决翻车现场 2的关键——Qt不会在列宽变化时自动重算行高要自己接信号connect(hHeader,SIGNAL(sectionResized(int,int,int)),this,SLOT(OnSectionResized(int,int,int)));voidStudyNotesWnd::OnSectionResized(int,int,int){m_table-resizeRowsToContents();// 按新列宽重新折行、重算所有行高}拖动松手的瞬间sectionResized触发全部行按新宽度重新排版。步骤 5窗口尺寸变化同样要重算最后一列是 stretch 列窗口拉伸时它的宽度会变但不会发sectionResized那是程序内部改宽不是用户拖段所以要在resizeEvent里补一刀voidStudyNotesWnd::resizeEvent(QResizeEvent*event){DCFWidget::resizeEvent(event);// 先交基类if(m_table)m_table-resizeRowsToContents();}三
返回列表