重写QComboBox

效果:

cpp 复制代码
//头文件
#ifndef CUTOMCOMBOBOX_H
#define CUTOMCOMBOBOX_H
#include <QObject>
#include <QWidget>
#include <QComboBox>
#include <QEvent>
#include <QListWidget>
#include <QPushButton>
#include <QVBoxLayout>
class CutomComboBox;
class CustomFrame : public QFrame
{
    Q_OBJECT
public:
    CustomFrame(QWidget* parent = nullptr);
    void popShow();
    void setItemList(const QStringList &value);
protected:
    bool eventFilter(QObject *obj, QEvent *event) override;

signals:
    void sendIndex(int index);
private:
    bool isDropDown = false;
    QStringList itemList;
    int curIndex = 0;
#define FRAME_QSS R"(QFrame { border-radius: 100px; background-color: white; border:none;})"
#define BTNSEL_QSS R"(
    QPushButton:hover{background-color:#f5f7fa;border:none;font-family:Arial;font-size: 15px; font-weight: bold; }
    QPushButton{background-color:#f5f7fa;color:#409eff;border:none;font-family:Arial;font-size: 15px;font-weight: bold; }
    )"
#define BTNUNSET_QSS R"(
    QPushButton:hover{background-color:#f5f7fa;border:none;font-family:Arial;font-size: 15px;font-weight: bold; }
    QPushButton{background-color:#ffffff;color:black;border:none;font-family:Arial;font-size:15px;font-weight: bold; }
    )"
};

class CutomComboBox : public QComboBox
{
    Q_OBJECT
public:
    CutomComboBox(QWidget *parent = nullptr);
public slots:
    void setList(QStringList list);
protected:
    void paintEvent(QPaintEvent *e) override;
    void enterEvent(QEvent *event) override;
    void leaveEvent(QEvent *event) override;
    void showPopup() override;
private:
    bool isHover = false;
    bool isDropDown = false;
    int  itemH = 10;
    CustomFrame popFrame;
    void drawOutLine(QPainter* painter);
    void drawText(QPainter* painter);
    void drawArrow(QPainter* painter, bool up);
#define DROPTRI_QSS R"(
    QComboBox {
    border: 1px solid gray;
    border-radius: 5px;
    padding: 5px;
    background-color: white;
    }
    QComboBox::drop-down {
    border: none;
    width: 30px;
    background: transparent;
    }
    QComboBox::down-arrow {
    image: url(':/png/png/drop-down.png');
    width: 15px;
    height: 15px;
    }
    )"
};

#endif // CUTOMCOMBOBOX_H
cpp 复制代码
//源文件
#include "cutomcombobox.h"
#include <QPainter>
#include <QDebug>
#include <QPropertyAnimation>
#include <QMetaObject>

CutomComboBox::CutomComboBox(QWidget *parent):QComboBox(parent)
{
    this->setStyleSheet(DROPTRI_QSS);
    connect(&popFrame,&CustomFrame::sendIndex,[=](int index){
        this->setCurrentIndex(index);
    });
}

void CutomComboBox::setList(QStringList list)
{
    this->addItems(list);
    popFrame.setItemList(list);

}

void CutomComboBox::paintEvent(QPaintEvent *e)
{
    QComboBox::paintEvent(e);
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    drawOutLine(&painter);
    drawText(&painter);
}

void CutomComboBox::enterEvent(QEvent *event)
{
    isHover = true;
    update();
    QComboBox::enterEvent(event);
}

void CutomComboBox::leaveEvent(QEvent *event)
{
    isHover = false;
    update();
    QComboBox::leaveEvent(event);
}

void CutomComboBox::showPopup()
{
    QPoint pos = this->mapToGlobal(QPoint(0, this->height()));
    popFrame.setFixedWidth(this->width());
    popFrame.move(pos);
    popFrame.popShow();
}

void CutomComboBox::drawOutLine(QPainter* painter)
{
    painter->save();
    QRect rect = this->rect();
    QColor clr = isHover?QColor("#409EFF"):Qt::gray;
    QPen pen(clr);
    pen.setWidth(1);
    painter->setPen(pen);
    painter->setBrush(QColor("#ffffff"));
    painter->drawRoundedRect(rect.adjusted(0, 0, -30,0), 1, 1);
    painter->restore();
}

void CutomComboBox::drawText(QPainter *painter)
{
    painter->save();
    QFont font("Arial", 10);
    painter->setFont(font);
    painter->setPen(QColor("#409eff"));
    QRect rect = this->rect();
    QString text = this->currentText();
    if(text.isEmpty()){
        text = "请输入内容";
        painter->setPen(Qt::gray);
    }
    QTextOption textOption;
    textOption.setAlignment(Qt::AlignCenter);
    painter->drawText(rect,text,textOption);
    painter->restore();
}


CustomFrame::CustomFrame(QWidget *parent):QFrame(parent)
{
    this->setFrameShape(QFrame::Panel);
    this->setWindowFlags(Qt::FramelessWindowHint);
    this->setStyleSheet(FRAME_QSS);
    this->adjustSize();
    this->installEventFilter(this);
};


void CustomFrame::setItemList(const QStringList &value)
{
    itemList = value;
}

bool CustomFrame::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type()==QEvent::WindowDeactivate){
        this->hide();
    }
    return QFrame::eventFilter(obj,event);
};

void CustomFrame::popShow()
{
    if(this->layout()!=nullptr){
        delete this->layout();
    }
    QVBoxLayout* vLay = new QVBoxLayout;
    vLay->setContentsMargins(0,0,0,0);
    vLay->setSpacing(0);
    for(int c=0;c<itemList.size();++c){
        QPushButton* btn = new QPushButton(itemList.at(c));
        btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        btn->setFixedHeight(60);
        btn->setFlat(true);
        if(c==curIndex){
            btn->setStyleSheet(BTNSEL_QSS);
        }else
        {
            btn->setStyleSheet(BTNUNSET_QSS);
        }
        connect(btn,&QPushButton::clicked,[=](){
            this->curIndex = c;
            emit sendIndex(c);
            this->hide();
            isDropDown = false;
        });
        vLay->addWidget(btn);
    }
    this->setLayout(vLay);
    this->show();
    isDropDown = true;
}
相关推荐
南岩亦凛汀20 分钟前
在Linux下使用wxWidgets进行跨平台GUI开发
c++·跨平台·gui·开源框架·工程实战教程
曦月逸霜43 分钟前
第34次CCF-CSP认证真题解析(目标300分做法)
数据结构·c++·算法
galaxy_strive1 小时前
绘制饼图详细过程
开发语言·c++·qt
Unpredictable2222 小时前
【VINS-Mono算法深度解析:边缘化策略、初始化与关键技术】
c++·笔记·算法·ubuntu·计算机视觉
PingdiGuo_guo3 小时前
C++智能指针的知识!
开发语言·c++
Chuncheng's blog3 小时前
CentOS 7如何编译安装升级gcc至7.5版本?
linux·运维·c++·centos
愚润求学5 小时前
【C++】类型转换
开发语言·c++
@我漫长的孤独流浪5 小时前
数据结构测试模拟题(4)
数据结构·c++·算法
csdnzzt5 小时前
从内存角度透视现代C++关键特性
c++
jie188945758666 小时前
C++ 中的 const 知识点详解,c++和c语言区别
java·c语言·c++