今天碰到一个有意思的问题,在QComboBox弹出下拉的listView之后,你选中一个,上下拖动,然后你移出listview的控件范围,竟然不会hide,这样的话如果在item较小时,喜欢拖动的用户简直崩溃,所以我看了一下QComboBox的show和hide,最终重写了一下showPopup和hidePopup,触摸屏竟然识别不到QEvent::Leave事件,我退而求其次。为了能让弹出的listview自动消失,加了一个定时器判断
#ifndef DYECOMBOBOX_H
#define DYECOMBOBOX_H
#include <QTimer>
#include <QEvent>
#include <QDebug>
#include <QWidget>
#include <QComboBox>
#include <QAbstractItemView>
class dyeComboBox : public QComboBox
{
Q_OBJECT
public:
explicit dyeComboBox(QWidget *p);
~dyeComboBox();
signals:
void currentIndexChanged(int index);
protected:
virtual void showPopup();
virtual void hidePopup();
virtual bool eventFilter(QObject * o, QEvent * e);
private slots:
void slotUpdate();
private:
QTimer *myTimer;
int view_x_leftpos;
int view_y_rightpos;
};
#endif // DYECOMBOBOX_H
#include "dyecombobox.h"
dyeComboBox::dyeComboBox(QWidget *p):QComboBox(p)
{
/* 开启鼠标追踪 */
setMouseTracking(true);
myTimer = new QTimer(this);
connect(myTimer,SIGNAL(timeout()),this,SLOT(slotUpdate()));
view_x_leftpos = -1;
view_y_rightpos = -1;
}
dyeComboBox::~dyeComboBox()
{
}
/* 下拉view的调用显示函数 */
void dyeComboBox::showPopup()
{
/*1、默认弹出view,不改变 */
QComboBox::showPopup();
/*2、获取view的parent */
QWidget *popup = this->findChild<QFrame*>();
if(popup != NULL){
view_x_leftpos = popup->x();
view_y_rightpos = popup->x()+popup->width();
/*3、设置QFrame的name,其实有没有没区别,为了严谨 */
popup->setObjectName("popup");
/*4、加入事件过滤 */
popup->installEventFilter(this);
}
}
/* 下拉view的调用隐藏函数 */
void dyeComboBox::hidePopup()
{
/*1、清除之前的配置 */
QWidget *popup = this->findChild<QFrame*>();
if(popup != NULL){
popup->setObjectName("");
popup->removeEventFilter(this);
view_x_leftpos = -1;
view_y_rightpos = -1;
}
/*2、隐藏 */
QComboBox::hidePopup();
emit currentIndexChanged(currentIndex());
}
bool dyeComboBox::eventFilter(QObject *o, QEvent *e)
{
if(o->objectName() == "popup"){
if(e->type() == QEvent::Leave){
if(view() != NULL){
/* 没有这一句会默认你显示前的index */
int curIndex = view()->currentIndex().row();
setCurrentIndex(curIndex);
}
hidePopup();
return true;
}else if(e->type() == QEvent::UpdateRequest){
if(myTimer->isActive()){
myTimer->start();
}else{
myTimer->start(100);
}
if(view() != NULL){
int curIndex = view()->currentIndex().row();
setCurrentIndex(curIndex);
}
}
}
return QComboBox::eventFilter(o,e);
}
void dyeComboBox::slotUpdate()
{
myTimer->stop();
if(QCursor::pos().x() < view_x_leftpos || QCursor::pos().x() > view_y_rightpos ){
// qDebug() << "fouse out ";
hidePopup();
}else{
// qDebug() << "fouse in ";
}
}