重写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;
}
相关推荐
晓纪同学2 小时前
QT-简单视觉框架代码
开发语言·qt
威桑2 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服2 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
fyzy2 小时前
Qt获取本地计算的CPU温度
qt
cbdg37572 小时前
Qt 6 QML Settings location 不创建指定路径文件
qt
了一li2 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
杨德杰2 小时前
QT网络(一):主机信息查询
网络·qt
黄金右肾3 小时前
Qt之串口设计-线程实现(十二)
qt·thread·serialport
别NULL4 小时前
机试题——疯长的草
数据结构·c++·算法
飞飞-躺着更舒服4 小时前
【QT】实现电子飞行显示器(改进版)
开发语言·qt