重写QComboBox委托paint方法后文本省略但背景尺寸未适配问题
问题诱因与背景管控说明
下拉项背景管控对象
下拉项背景由Qt的QStyle体系负责绘制,默认使用控件/应用绑定的QStyle实例,通过QStyle::drawControl(QStyle::CE_ItemViewItem, ...)接口完成背景、选中态、文本等全要素的绘制,绘制尺寸完全依赖传入的QStyleOptionViewItem::rect参数。而这个rect的初始值是由下拉项所属的QAbstractItemView(QComboBox默认下拉视图为QListView),根据委托的sizeHint()返回值计算分配的。
问题诱因
你当前只在paint方法中修改了绘制阶段的opt.rect宽度,但没有重写委托的sizeHint()方法返回适配的尺寸:视图在布局阶段仍使用默认sizeHint的计算结果给每一项分配背景区域,导致你绘制的文本区域和实际分配的背景区域尺寸不匹配。此外直接使用父QComboBox的宽度赋值,未考虑下拉列表滚动条、内边距的偏移,也会加剧尺寸适配问题。
可行解决建议
- 优先重写委托的
sizeHint()方法,返回和你需求匹配的宽度,保证视图布局阶段分配的项区域和绘制区域一致,无需在paint中硬改rect参数:
QSize myDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize originSize = QStyledItemDelegate::sizeHint(option, index); // 计算适配宽度,减去滚动条、内边距的预留尺寸 int styleMargin = 2 * option.widget->style()->pixelMetric(QStyle::PM_FocusFrameHMargin); int scrollBarWidth = option.widget->style()->pixelMetric(QStyle::PM_ScrollBarExtent); int targetWidth = _parentComboRect->width() - scrollBarWidth - styleMargin; return QSize(targetWidth, originSize.height()); }
- 若仅需要下拉列表整体宽度适配QComboBox,无需修改委托,直接给下拉视图设置固定宽度即可:
// 在QComboBox初始化逻辑中添加 comboBox->view()->setFixedWidth(comboBox->width());
- 若需要保留默认委托的其他绘制逻辑,仅需文本右侧省略,无需自定义
paint方法,直接给下拉视图设置文本省略模式即可:
comboBox->view()->setTextElideMode(Qt::ElideRight);
内容的提问来源于stack exchange,提问作者Mykola Tetiuk
相关产品推荐
相关产品推荐

