|  | @@ -0,0 +1,176 @@
 | 
	
		
			
				|  |  | +#include "searchcombobox.h"
 | 
	
		
			
				|  |  | +#include "wordtopinyin.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <QStyleFactory>
 | 
	
		
			
				|  |  | +#include <QListView>
 | 
	
		
			
				|  |  | +#include <QApplication>
 | 
	
		
			
				|  |  | +#include <QGraphicsDropShadowEffect>
 | 
	
		
			
				|  |  | +#include <QTimer>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +SearchComboBox::SearchComboBox(QWidget *parent)
 | 
	
		
			
				|  |  | +    : QComboBox(parent)
 | 
	
		
			
				|  |  | +    , m_autoquery(false)
 | 
	
		
			
				|  |  | +    , m_showPopup(false)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    setStyle(QStyleFactory::create("Windows"));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    QTimer::singleShot(0, this, [=]
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        view()->setMinimumWidth(width() + LISTVIEW_MARGIN * 2);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    setEditable(true);
 | 
	
		
			
				|  |  | +    setCompleter(nullptr);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //输入后,开始查询
 | 
	
		
			
				|  |  | +    connect(this, (void (QComboBox::*)(const QString &))&QComboBox::currentIndexChanged, this, &SearchComboBox::OnCurrentIndexChanged);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +SearchComboBox::~SearchComboBox()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +//    qDebug()<<__func__;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::showPopup()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    // QComboBox::showPopup();
 | 
	
		
			
				|  |  | +    // QWidget *popup = findChild<QFrame*>();
 | 
	
		
			
				|  |  | +    // popup->move(mapToGlobal(QPoint( - LISTVIEW_MARGIN, height() - LISTVIEW_MARGIN)));
 | 
	
		
			
				|  |  | +    // m_showPopup = true;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    QComboBox::showPopup();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (nullptr != view()) {
 | 
	
		
			
				|  |  | +        view()->setMinimumWidth(width() + LISTVIEW_MARGIN * 2);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    QWidget *popup = findChild<QFrame*>();
 | 
	
		
			
				|  |  | +    if (nullptr != popup) {
 | 
	
		
			
				|  |  | +        popup->move(mapToGlobal(QPoint(-LISTVIEW_MARGIN, height() - LISTVIEW_MARGIN + 4)));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    m_showPopup = true;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::hidePopup()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    QComboBox::hidePopup();
 | 
	
		
			
				|  |  | +    m_showPopup = false;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* 设置下拉框阴影 */
 | 
	
		
			
				|  |  | +void SearchComboBox::setViewShadowEffect()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    setView(new QListView());
 | 
	
		
			
				|  |  | +    view()->window()->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
 | 
	
		
			
				|  |  | +    view()->window()->setAttribute(Qt::WA_TranslucentBackground);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //取消拉下动画
 | 
	
		
			
				|  |  | +    QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //设置阴影
 | 
	
		
			
				|  |  | +    QGraphicsDropShadowEffect *pShadowEffect = new QGraphicsDropShadowEffect(this);
 | 
	
		
			
				|  |  | +    pShadowEffect->setBlurRadius(10); // 模糊度
 | 
	
		
			
				|  |  | +    pShadowEffect->setColor(QColor(0, 0, 0, 60)); // 阴影的颜色
 | 
	
		
			
				|  |  | +    pShadowEffect->setOffset(0, 0); // 水平和垂直偏移量
 | 
	
		
			
				|  |  | +    view()->setGraphicsEffect(pShadowEffect);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::wheelEvent(QWheelEvent *e)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    Q_UNUSED(e);
 | 
	
		
			
				|  |  | +    //屏蔽鼠标滚动
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +bool SearchComboBox::event(QEvent *event)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    //添加一个鼠标滚轮拦截来禁用combox滚轮改变CurrentIndex
 | 
	
		
			
				|  |  | +    if(event->type()==QEvent::Wheel)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        return true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else if(event->type() == QEvent::KeyPress)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        QKeyEvent* ev = (QKeyEvent*)event;
 | 
	
		
			
				|  |  | +        if(ev->key() == Qt::Key_Enter || ev->key() == Qt::Key_Return){//回车开始查找匹配的数据
 | 
	
		
			
				|  |  | +            if(isEditable()){
 | 
	
		
			
				|  |  | +                autoquery();
 | 
	
		
			
				|  |  | +                m_autoquery = false;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else if(event->type() == QEvent::MouseButtonPress)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //点击下拉框,恢复到源数据集
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else if(event->type() == QEvent::FocusOut)
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //离开焦点时,编辑框自动填充当前选择项的文本
 | 
	
		
			
				|  |  | +        if(!m_showPopup)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            if(!m_currentText.isEmpty())
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                setCurrentText(m_currentText);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                int index = currentIndex();
 | 
	
		
			
				|  |  | +                if(index >= 0 && index < m_items.count())
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    setCurrentText(m_items[index].text);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            update();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return QComboBox::event(event);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::OnCurrentIndexChanged(const QString &text)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    m_currentText = text;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::addItem(const QString &text, const QVariant &userData)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    ItemData item;
 | 
	
		
			
				|  |  | +    item.text = text;
 | 
	
		
			
				|  |  | +    item.userdata = userData;
 | 
	
		
			
				|  |  | +    item.alphbat = WordToPinyin::firstPinyin(item.text);
 | 
	
		
			
				|  |  | +    m_items.append(item);
 | 
	
		
			
				|  |  | +    QComboBox::addItem(item.text, item.userdata);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::clear()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    m_items.clear();
 | 
	
		
			
				|  |  | +    QComboBox::clear();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void SearchComboBox::autoquery()
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +    QString text = currentText().toLower();
 | 
	
		
			
				|  |  | +    QComboBox::clear();
 | 
	
		
			
				|  |  | +    if(text.isEmpty())
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //显示源数据集
 | 
	
		
			
				|  |  | +        foreach(ItemData item,m_items)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            QComboBox::addItem(item.text, item.userdata);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +        //显示匹配的数据集
 | 
	
		
			
				|  |  | +        foreach(ItemData item, m_items)
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            if(item.alphbat.toLower().contains(text) || item.text.toLower().contains(text))
 | 
	
		
			
				|  |  | +            {
 | 
	
		
			
				|  |  | +                QComboBox::addItem(item.text, item.userdata);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //没匹配到任何数据
 | 
	
		
			
				|  |  | +        //....
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    showPopup();
 | 
	
		
			
				|  |  | +}
 |