当前位置:网站首页>自定义QComboBox下拉框,右对齐显示,下拉列表滑动操作
自定义QComboBox下拉框,右对齐显示,下拉列表滑动操作
2022-06-25 22:00:00 【北极熊的奋斗史】
先看效果图:

看源码:
1. 设置基本样式:
MComboBox::MComboBox(QWidget *parent) : QComboBox(parent)
{
// 设置样式表,修改下拉框的样式,同时修改下拉列表中的滚动条样式
setStyleSheet(QString("QComboBox{ "
"background:transparent; "
"border:1px solid #009ae7; "
"color:rgb(255,255,255); "
"font-size:20px; "
"} "
"QComboBox::drop-down { "
" width: 20px; "
" border:none; "
"} "
"QComboBox::down-arrow { "
" width:14px; "
" height:8px; "
" border-image: url(:/img/cbArrow.png); "
"} "
"QComboBox::down-arrow:on { "
" top: 1px; "
" left: 1px; "
"} "
"QComboBox QFrame{ "
" background-color:#4be26e; "
" border:none; "
"} "
"QComboBox QAbstractItemView "
"{ "
" outline:0px; "
"} "
"QComboBox QAbstractItemView::item "
"{ "
" height: 54px; "
" color: #ffffff; "
" border-bottom: 1px solid #009ae7; "
"} "
"QComboBox QAbstractItemView::item:selected"
"{ "
" background:transparent; "
"} "
"QScrollBar::vertical{ background:transparent; margin: 0px 0px 0px 0px; width: 8px; } "
"QScrollBar::handle:vertical{ border-image: url(:/img/scroll.png); } "
"QScrollBar::add-line:vertical{ height: 0px; } "
"QScrollBar::sub-line:vertical{ height: 0px; } "
"QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;} "
));
// 嵌入一个编辑框,调整下拉框显示的文字为右对齐
QLineEdit* edt = new QLineEdit();
edt->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
edt->setReadOnly(true);
// 取消编辑框双击选中的效果
connect(edt, &QLineEdit::selectionChanged, [=](){edt->setSelection(edt->text().length() - 1, 0);});
// 使用事件过滤器添加编辑框点击,显示下拉框的效果
edt->installEventFilter(this);
setLineEdit(edt);
//用于下拉框item的样式美化,使用改代理后,上面的样式表可以完成下拉表的样式展示
QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
setItemDelegate(itemDelegate);
//下面两句可以设置下拉背景为透明
view()->parentWidget()->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground);
// 设置下拉列表可以实现类似触屏的上下拖拽
QListView* v = static_cast<QListView*>(view());
v->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
// ui->lstUserList->verticalScrollBar()->setSingleStep(10);
QScroller::grabGesture(v, QScroller::LeftMouseButtonGesture);
v->setFlow(QListView::TopToBottom);
// 设置最大显示5条内容
setMaxVisibleItems(5);
}2. 下拉列表自适应宽度,同时调整下拉项的文字右对齐
void MComboBox::adjustItemWidth()
{
if(count() <= 0)
return;
QStandardItemModel* md = static_cast<QStandardItemModel*>(view()->model());
int max_len=0;
QString max_str;
QFont ft = font();
ft.setPixelSize(22);
QFontMetrics fm(ft);
// 计算下拉列表应该占用的宽度
for(int i=0; i < count(); i++)
{
int len = fm.width(itemText(i));
if(max_len < len)
{
max_len = len;
max_str = itemText(i);
}
// 调整下拉列表的item子项右对齐
md->item(i)->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
}
// 防止内容太长,超出显示屏,导致无法正常显示
int x = mapToGlobal(rect().topRight()).x();
max_len = (max_len <= x ? max_len : x);
// 设置下拉列表的固定宽度
view()->parentWidget()->setFixedWidth(max_len);
}3. 重写父类的showPopup函数,调整下拉列表位置。
void MComboBox::showPopup()
{
// 显示前调整下拉列表
adjustItemWidth();
QComboBox::showPopup();
// 获取下拉列表窗口对象
QWidget* fm = view()->parentWidget();
// 获取下拉列表显示的全局位置
QPoint fmPt = fm->mapToGlobal(fm->pos());
// qDebug() << fmPt;
// 将下来框移动到右对齐的位置
QPoint pt = fm->mapFromGlobal( QPoint(fmPt.x() - (fm->width() - width()), fmPt.y()) );
// qDebug() << pt;
fm->move(pt);
}4. 过滤编辑框的点击事件,响应点击编辑框时,显示下拉列表
bool MComboBox::eventFilter(QObject *obj, QEvent *event)
{
bool b = QComboBox::eventFilter(obj, event);
// 过滤编辑框点击事件,在编辑框点击时显示下拉列表
QLineEdit* ed = lineEdit();
if(obj == ed && event->type() == QEvent::MouseButtonRelease)
{
if(!view()->isVisible())
{
showPopup();
}
else
{
hidePopup();
}
}
return b;
}以上为全部效果实现方式,在使用时提升QComboBox为自定义的MComboBox即可。
附上软件源码下载地址:https://download.csdn.net/download/chenxipu123/10966933
吐槽一下:CSDN不让设置资源所需的下载积分,所以源码没法免费共享。
边栏推荐
- 【opencv450 samples】创建图像列表yaml
- Beacon realizes asset management and indoor positioning based on 5.2 ultra-low power Bluetooth module efr32 (bg22ax)
- Es7/es9 -- new features and regularities
- Pit resolution encountered using East OCR (compile LAMS)
- [opencv450 samples] read the image path list and maintain the proportional display
- Leetcode(435)——无重叠区间
- Repoptimizer: it's actually repvgg2
- Ue4 Ue5 combine le plug - in de reconnaissance vocale de bureau pour la reconnaissance vocale
- LM小型可编程控制器软件(基于CoDeSys)笔记十七:pto脉冲功能块
- Multi modal data can also be Mae? Berkeley & Google proposed m3ae to conduct Mae on image and text data! The optimal masking rate can reach 75%, significantly higher than 15% of Bert
猜你喜欢

Utilisation de la classe Ping d'Unity

What is Unified Extensible Firmware Interface (UEFI)?

24class static member

character string

元宇宙标准论坛成立

The applet draws a simple pie chart

Rk3568+ Hongmeng industrial control board industrial gateway video gateway solution

What aspects should we start with in the feasibility analysis of dry goods?

STM32开发板+机智云AIoT+家庭监测控制系统

Idea shortcut
随机推荐
#23class介绍
Xinchida nd04 nd04c nrf52832 (52810) ble module (low power Bluetooth communication module) at command test
汇编语言核心要点
Svn icon disappearing solution
After xampp restarts, the MySQL service cannot be started.
[opencv450 samples] create image list yaml
Unity的Ping類使用
【opencv450 samples】创建图像列表yaml
首个大众可用PyTorch版AlphaFold2复现,哥大开源OpenFold,star量破千
建立自己的网站(15)
为什么OpenCV计算的帧率是错误的?
【opencv450-samples】读取图像路径列表并保持比例显示
cookie、session、token
2. What is the geometric meaning of a vector multiplying its transpose?
RepOptimizer: 其实是RepVGG2
Fastjson deserialization randomness failed
[opencv450 samples] inpaint restores the selected region in the image using the region neighborhood
[untitled] open an item connection. If it cannot be displayed normally, Ping the IP address
STM32开发板+机智云AIoT+家庭监测控制系统
NLP pre training model-2018:bert dictionary