QComboBox美化

美化QComboBox

Qt還是很強大的,美化QComboBox只需要使用QSS就可以,如下:

QComboBox{ border:1px solid gray;  border-radius:3px;  padding: 5px; min-width:4em;}
QComboBox::drop-down{subcontrol-origin:padding; subcontrol-position:top right; width:20px; border-left-width:1px;border-left-color:darkgray; border-left-style:solid; border-top-right-radius:3px; border-bottom-right-radius:3px;}
QComboBox QAbstractItemView{border: 2px solid #4E6D8C;}
QComboBox::down-arrow{image: url(:/image/arrow-drop.png);}

按照上面的樣式就可以美化QComboBox,效果圖如下:
這裏寫圖片描述

去掉虛線

上面QComboBox含有去不掉的虛線,那麼我們可以指定它的View/Model,然後指定List的委託:

    //設置委託、去除虛線框
    m_list->setItemDelegate(new NoFocusFrameDelegate(this));
    ui->chooseComboBox->setModel(m_list->model());
    ui->chooseComboBox->setView(m_list);

看看NoFocusFrameDelegate:

#ifndef NOFOCUSFRAMEDELEGATE_H
#define NOFOCUSFRAMEDELEGATE_H

#include <QStyledItemDelegate>

/**
 * 去除虛線框
 */
class NoFocusFrameDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit NoFocusFrameDelegate(QWidget *parent = 0);

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

signals:

public slots:

};

#endif // NOFOCUSFRAMEDELEGATE_H

NoFocusFrameDelegate.cpp:

#include "nofocusframedelegate.h"
#include <QPainter>
#include <QDebug>

NoFocusFrameDelegate::NoFocusFrameDelegate(QWidget *parent) :
    QStyledItemDelegate(parent)
{
}

void NoFocusFrameDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem itemOption(option);
    if( itemOption.state & QStyle::State_HasFocus)
    {
        itemOption.state ^= QStyle::State_HasFocus;
    }
    QStyledItemDelegate::paint(painter, itemOption, index);
}

原理就是不讓ListWidget有QStyle::State_HasFocus這個狀態,因爲虛線是在這個狀態下繪製出來的,就像hover狀態繪製hover狀態該有的東西。定義了List和Model,再接着美化List的Item項:

 QListView{border:1px solid gray}
 QListView::item{height:30px;}
 QListView::item{background:white;}
 QListView::item:hover{background: #BDD7FD;}

看效果:

這裏寫圖片描述

繪製顯示文字

從上面看來已經好看很多了,但是下拉框選中了item之後QComboBox並不會顯示選中了哪一項,所以我們得繼承QComboBox並重寫它的QComboBox::paintEvent()方法來重回文字,ComboBox.h:

#ifndef COMBOBOX_H
#define COMBOBOX_H

#include <QComboBox>
#include <QWidget>

class QListWidgetItem;

class ComboBox : public QComboBox
{
    Q_OBJECT
public:
    explicit ComboBox(QWidget *parent = 0);

    void paintEvent(QPaintEvent *e);

    void setCurrentItem(QString item);

signals:

public slots:
    //ListWidget的item項選擇變換
    void currentItemChanged_slot(QListWidgetItem * current, QListWidgetItem * previous);

private :
    QString m_currentItem;

};

#endif // COMBOBOX_H

ComboBox.cpp:

#include "combobox.h"
#include <QPainter>
#include <QDebug>
#include <QListWidgetItem>
#include <QListWidget>
#include "comboboxitem.h"

ComboBox::ComboBox(QWidget *parent) :
    QComboBox(parent)
{
    m_currentItem = "文件夾";
}

void ComboBox::paintEvent(QPaintEvent *e)
{
//qDebug() << "I'm comboBox!";
    QComboBox::paintEvent(e);
    QPainter paint(this);
    paint.setRenderHint(QPainter::Antialiasing);
    //繪製文字
    paint.drawText(5, 23, m_currentItem);
}

void ComboBox::currentItemChanged_slot(QListWidgetItem *current, QListWidgetItem *previous)
{
    QListWidget *list = current->listWidget();
    ComboBoxItem * c = static_cast<ComboBoxItem *>(list->itemWidget(current));
    m_currentItem = c->getLabelString();
}

void ComboBox::setCurrentItem(QString item)
{
    m_currentItem = item;
}

在painter中繪製出來item項就可以了,,然後讓自定的ComboBox連接ListWidget的currentItemChanged信號:

connect(m_list, SIGNAL(currentItemChanged(QListWidgetItem,QListWidgetItem)), ui->chooseComboBox,            SLOT(currentItemChanged_slot(QListWidgetItem,QListWidgetItem)));

效果:
這裏寫圖片描述

在widget.ui裏面使用自定義控件

這裏寫圖片描述
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章