Qt浅谈之三十八下拉列表框

一、简介

        在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)测试运行
Qt浅谈之三十八下拉列表框_第1张图片
当下拉列表数据过多时,会显示滚动条:

三、总结

(1)上述代码还调用了其他的封装函数,需要借鉴的可以复制其中的代码。因一些因素在此只提供了部分代码。
(2)若有问题或建议,请留言,在此感谢!

你可能感兴趣的:(linux,qt)