自定义QComboBox下拉框,右对齐显示,下拉列表滑动操作

先看效果图:

自定义QComboBox下拉框,右对齐显示,下拉列表滑动操作_第1张图片

看源码:

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);

    //  设置下拉列表可以实现类似触屏的上下拖拽
    QListView* v = static_cast(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(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/10966082

吐槽一下:CSDN不让设置资源所需的下载积分,所以源码没法免费共享。

你可能感兴趣的:(qt)