一、简介
在QComboBox中重新定义QListWidget的样式,并通过QListWidgetItem的setItemWidget设置自定义的下拉项。
二、详解
1、部分代码
(1)login.h
class AccountComboBoxItem : public QWidget
{
Q_OBJECT
public:
explicit AccountComboBoxItem(const QString &account, QWidget *parent = 0);
~AccountComboBoxItem();
QString getAccountName() const;
void setAccountName(const QString& name);
protected:
bool eventFilter(QObject *obj, QEvent *event);
signals:
void sigDelAccount(AccountComboBoxItem *item);
void sigPopList(bool flag);
private slots:
void slotDelAccount();
private:
bool mousePress;
QPixmap delPixmap;
CustomBtn *delBtn;
QLabel *nameLabel;
};
class AccountComboBox : public QComboBox
{
Q_OBJECT
public:
AccountComboBox(QWidget *parent = 0, QString hint = "");
~AccountComboBox();
void addAccount(const QString &accountName);
void setHint(const QString &hint) {
_hint = hint;
repaint();
}
void setError(const bool &error);
bool isError() { return _error; }
//void setImgs(QImage *strLeft, QImage *strCenter,QImage *strRight);
void setDefaultText(const QString &text) { _defaultText = text; }
QString defaultText() { return _defaultText; }
void setDefault() { setCurrentIndex(-1); }
void resizeWidth(const int &width) { resize(width, height()); }
void hidePopup() {QComboBox::hidePopup();}
void setToolTipFlag(bool tipFlag = false) {_tipFlag = tipFlag;}
protected:
void paintEvent(QPaintEvent *event);
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
void enterEvent ( QEvent * event );
void leaveEvent ( QEvent * event );
private:
void setImgs(QImage *img);
signals:
void sigDelItem(const QString &itemName);
private slots:
void slotItemEntered(QListWidgetItem *item);
void slotDelAccount(AccountComboBoxItem *item);
void slotPopList(bool flag);
private:
QImage *_input;
QImage *_hover;
QImage *_errorImg;
QImage *_dropDownButton;
QImage *_showImg;
QString _defaultText;
QString _hint;
bool _error;
bool _focusFlag;
bool _tipFlag;
QList<QString>textList;
QListWidget *accountListWidget;
bool showListFlag;
};
(2)login.cpp
#include "login.h"
AccountComboBox::AccountComboBox(QWidget *parent, QString hint)
:QComboBox(parent)
,_error(false)
,_hint(hint)
,_focusFlag(false)
,_tipFlag(false)
, showListFlag(false)
{
setEditable(true);
_input = new QImage(":/resources/images/loginInput_bg_hover.png");
_hover = new QImage(":/resources/images/loginInput_bg_focus.png");
_errorImg = new QImage(":/resources/images/loginInput_bg_abnormal-.png");
_dropDownButton = new QImage(":/resources/images/mode_warn.png");
setImgs( _input);
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_drop_down_disabled.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
accountListWidget = new QListWidget(this);
accountListWidget->setMouseTracking(true);
accountListWidget->setFocusPolicy(Qt::NoFocus);
accountListWidget->setStyleSheet("QListWidget{font-size: 11px;background-color: #ffffff;border:1px solid #2794CA;}"
"QListWidget::item{border:0px solid gray;padding:-1px;height:35px;color:transparent}"
//"QListWidget::item:!selected{padding-left:4px;background-color: #FFFFFF}"
//"QListWidget::item:selected{background-color: #1275c3}"
"QListWidget::item:hover{background-color: #86ACD9;padding:-1px -2px -2px -2px}"
"QScrollArea{background:transparent}"
"QScrollBar::vertical{background:#126691;border:1px #126691;width:15px;}"
"QScrollBar::horizontal{background:#126691;border:1px #126691;}"
);
connect(accountListWidget,SIGNAL(itemEntered(QListWidgetItem*)),this,SLOT(slotItemEntered(QListWidgetItem*)));
setModel(accountListWidget->model());
setView(accountListWidget);
this->setMaxVisibleItems(3);
_defaultText.clear();
}
AccountComboBox::~AccountComboBox()
{
}
void AccountComboBox::addAccount(const QString &accountName)
{
AccountComboBoxItem *accountItem = new AccountComboBoxItem(accountName, this);
connect(accountItem, SIGNAL(sigDelAccount(AccountComboBoxItem *)), this, SLOT(slotDelAccount(AccountComboBoxItem *)));
connect(accountItem, SIGNAL(sigPopList(bool)), this, SLOT(slotPopList(bool)));
QListWidgetItem* item = new QListWidgetItem(accountListWidget);
item->setData(Qt::DisplayRole, accountName);
accountListWidget->setItemWidget(item, accountItem);
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_down.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
void AccountComboBox::setError(const bool &error)
{
_error = error;
if (_error)
setImgs( _errorImg);
else
setImgs( _input);
}
void AccountComboBox::paintEvent(QPaintEvent *event)
{
QComboBox::paintEvent(event);
QPainter painter(this);
if (currentIndex() == -1)
painter.drawText(10, height()/2 + 5, _defaultText);
*_showImg = _showImg->scaled(width()+7, height()+2);
painter.drawImage(QRect(-4,-2,width()+7, height()+4), *_showImg);
if (currentIndex() != -1 && !currentText().isEmpty())
return;
if (!currentText().isEmpty()) return;
QRect rt = rect();
painter.setPen(QPen(QColor("#999999")));
painter.drawText(rt.translated(50,0), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextHideMnemonic, _hint);
}
void AccountComboBox::setImgs(QImage *img)
{
_showImg = img;
repaint();
}
void AccountComboBox::slotItemEntered(QListWidgetItem *item)
{
if (_tipFlag == true) {
if (accountListWidget->row(item) < textList.size()) {
QToolTip::showText(QCursor::pos() + QPoint(5, -15), textList.at(accountListWidget->row(item)));
}
}
}
void AccountComboBox::slotDelAccount(AccountComboBoxItem *item)
{
for (int index = 0; index < accountListWidget->count(); index++) {
QListWidgetItem *listItem = accountListWidget->item(index);
AccountComboBoxItem *accountItem = qobject_cast<AccountComboBoxItem *>(accountListWidget->itemWidget(listItem));
if (accountItem == item) {
accountListWidget->takeItem(index);
emit sigDelItem(accountItem->getAccountName());
delete listItem;
listItem = NULL;
break;
}
}
if (accountListWidget->count() == 0) {
hidePopup();
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_drop_down_disabled.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
}
void AccountComboBox::slotPopList(bool flag)
{
showListFlag = flag;
if (flag) {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_top_hover.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
else {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_down_hover.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
}
void AccountComboBox::focusInEvent(QFocusEvent *event)
{
if (!_error) setImgs(_hover);
_focusFlag = true;
QComboBox::focusInEvent(event);
}
void AccountComboBox::focusOutEvent(QFocusEvent *event)
{
if(showListFlag) {
if (!_error) setImgs(_hover);
_focusFlag = true;
}
else {
if (!_error) setImgs( _input);
_focusFlag = false;
}
if (!showListFlag) {
if (accountListWidget->count() == 0) {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_drop_down_disabled.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
else {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_down.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
}
QComboBox::focusOutEvent(event);
}
void AccountComboBox::enterEvent ( QEvent * event )
{
if (!_error) setImgs(_hover);
setCursor(Qt::PointingHandCursor);
if (!showListFlag) {
if (currentIndex() != -1) {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_down_hover.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
else {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_drop_down_disabled.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
}
QComboBox::enterEvent(event);
}
void AccountComboBox::leaveEvent ( QEvent * event )
{
if (!_error) {
if(_focusFlag == true) setImgs(_hover);
else setImgs(_input);
}
setCursor(Qt::ArrowCursor);
if (!showListFlag) {
if (currentIndex() != -1) {
if (_focusFlag) {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_down_hover.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
else {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_pull_down.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
}
else {
setStyleSheet("QComboBox{margin-left:48px;margin-right:20px;border: 0px;background:rgba(255,255,255,0);"
"border-style:flat;color:#19649f;}QComboBox::drop-down{image:url(:/resources/images/input_drop_down_disabled.png);"
"border-style:flat;position: relative;top: 17px; left: 6px;}"
"QComboBox QAbstractItemView::item{max-width: 60px;min-height: 20px}");
}
}
QComboBox::leaveEvent(event);
}
/*****************************/
AccountComboBoxItem::AccountComboBoxItem(const QString &account, QWidget *parent)
: QWidget(parent)
, mousePress(false)
{
delPixmap = QPixmap(":/resources/images/delete.png");
nameLabel = new QLabel(this);
nameLabel->setFont(QFont("arial", 10, QFont::Normal));
nameLabel->setAlignment(Qt::AlignVCenter);
nameLabel->setStyleSheet("color:#666666");
nameLabel->setText(account);
nameLabel->resize(280, 35);
nameLabel->move(45, 0);
delBtn = new CustomBtn(nameLabel);
delBtn->setCursor(Qt::PointingHandCursor);
delBtn->SetImgs(":/resources/images/close_client_icon_hover.png",
":/resources/images/close_client_icon.png",
":/resources/images/close_client_icon.png",
":/resources/images/close_client_icon.png");
delBtn->resize(25, 25);
delBtn->move(213, 12);
connect(delBtn, SIGNAL(clicked()), this, SLOT(slotDelAccount()));
this->installEventFilter(this);
}
AccountComboBoxItem::~AccountComboBoxItem()
{
}
QString AccountComboBoxItem::getAccountName() const
{
return nameLabel->text();
}
void AccountComboBoxItem::setAccountName(const QString &name)
{
nameLabel->setText(name);
}
bool AccountComboBoxItem::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::Enter) {
nameLabel->setFont(QFont("arial", 12, QFont::Normal));
nameLabel->setStyleSheet("color:#FFFFFF");
}
else if (event->type() == QEvent::Leave){
nameLabel->setFont(QFont("arial", 10, QFont::Normal));
nameLabel->setStyleSheet("color:#666666");
}
else if (event->type() == QEvent::Show) {
emit sigPopList(true);
}
else if (event->type() == QEvent::Hide) {
emit sigPopList(false);
}
return QWidget::eventFilter(obj, event);
}
void AccountComboBoxItem::slotDelAccount()
{
emit sigDelAccount(this);
}
(3)测试运行
当下拉列表数据过多时,会显示滚动条:
三、总结
(1)上述代码还调用了其他的封装函数,需要借鉴的可以复制其中的代码。因一些因素在此只提供了部分代码。
(2)若有问题或建议,请留言,在此感谢!