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里面使用自定义控件

这里写图片描述
这里写图片描述

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