效果:
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;
}