一、简介
在QGraphicsItem下使用QListWidget实现下拉列表的功能,并显示所有的选项,便于浏览和查询数据。
二、详解
1、部分代码
(1)clusterlistwidget.h
- #ifndef CLUSTERLISTWIDGET_H
- #define CLUSTERLISTWIDGET_H
- #include <QWidget>
- #include <QtGui>
- #include "custombtn.h"
- #include "pagenumbercontrol.h"
- class SearchLineEdit;
- enum TYPE{cluster=0,host,vm};
- class ClusterListWidget : public QWidget
- {
- Q_OBJECT
- public:
- explicit ClusterListWidget(TYPE type = cluster,QWidget *parent = 0);
- void setListWidget();
- void setTitle(QString title);
- void listInit();
- signals:
- public slots:
- void textChange(QString text);
- void pageChange(int currentnumber);
- void editClicked();
- void btnClicked();
- void itemEnteredSlot(QListWidgetItem * i);
- void itemClickedSlot(QListWidgetItem * i);
- void rowChanged(int row);
- protected:
- //bool eventFilter(QObject * obj, QEvent *e);
- void paintEvent(QPaintEvent *e);
- void showEvent(QShowEvent *e);
- void keyPressEvent(QKeyEvent *e);
- private:
- void setImgs(const QString &normal,const QString &abnormal,const QString &error);
- void setVmImgs(const QString &linux_normal,const QString &linux_abnormal,const QString &linux_error,const QString &linux_off,
- const QString &windows_normal,const QString &windows_abnormal,const QString &windows_error,const QString &windows_off);
- private:
- //QString _icon;
- QPixmap backGroundPix;
- QStringList NameList;
- QStringList _searchList;
- QStringList _list;
- QLabel *lb1;
- QLabel *lb2;
- PageNumberControl *_page;
- int _maxNum;
- int _currentNum;
- int _searchNUm;
- SearchLineEdit *_searchLineEdit;
- QListWidget * _cluster;
- QPushButton *_btn;
- int _n;//记录键盘 上下见
- int _x;
- int _y;
- QPixmap _enterPixmap;
- bool _enter;
- QString _title;
- QString _normal;
- QString _abnormal;
- QString __error;
- TYPE _type;
- QString _linux_normal;
- QString _linux_abnormal;
- QString _linux_error;
- QString _linux_off;
- QString _windows_normal;
- QString _windows_abnormal;
- QString _windows_error;
- QString _windows_off;
- };
- class SearchLineEdit : public QLineEdit
- {
- Q_OBJECT
- public:
- explicit SearchLineEdit(QWidget *parent = 0);
- signals:
- void pressed();
- protected:
- void focusInEvent(QFocusEvent *e);
- void focusOutEvent(QFocusEvent *e);
- private:
- };
- #endif // CLUSTERLISTWIDGET_H
- #include "clusterlistwidget.h"
- ClusterListWidget::ClusterListWidget(TYPE type,QWidget *parent) :
- QWidget(parent,Qt::FramelessWindowHint)
- ,_maxNum(0)
- ,_searchNUm(0)
- ,_n(-1)
- ,_x(0)
- ,_y(0)
- ,_enter(false)
- {
- NameList<<"a"<<"b"<<"c"<<"d"<<"e"<<"a"<<"b"<<"c"<<"d"<<"e"
- <<"a"<<"b"<<"c"<<"d"<<"e"<<"a"<<"b"<<"c"<<"d"<<"e"
- <<"a"<<"b"<<"c"<<"d"<<"e"<<"a"<<"b"<<"c"<<"d"<<"e"
- <<"a"<<"b"<<"c"<<"d"<<"e"<<"a"<<"b"<<"c"<<"d"<<"e"<<"hjhjha";
- backGroundPix = QPixmap(":/images/handleMenu_bg.png");
- resize(backGroundPix.width(), backGroundPix.height());
- qDebug()<<backGroundPix.width()<<backGroundPix.height();
- QPalette pal = palette();
- pal.setColor(QPalette::Background, QColor(0xFF,0xFF,0xFF,0x00));
- setPalette(pal);
- _list= NameList;
- _type = type;
- lb1 = new QLabel(this);
- lb1->setPixmap(QPixmap(":/images/handleMenu_allClusters.png"));
- lb1->move(10,12);
- lb2 = new QLabel(this);
- lb2->move(33,12);
- lb2->setStyleSheet("color:#b4e5fd");
- _page = new PageNumberControl(this);
- _page->setCluster(true);
- _maxNum = (_list.count() - 1) / 16 +1;
- _currentNum = 1;
- _page->setTotalPage(_maxNum);
- _page->move(145,12);
- _searchLineEdit = new SearchLineEdit(this);
- // _searchLineEdit->setImgs(":/images/handleMenu_searchInput.png",":/images/handleMenu_searchInput_click.png",
- // ":/images/handleMenu_searchInput.png",":/images/handleMenu_searchInput.png");
- _searchLineEdit->setStyleSheet("background-image:url(:/images/handleMenu_searchInput.png);border:1px solid #536874;");
- _searchLineEdit->move(8,38);
- _searchLineEdit->resize(168,23);
- _searchLineEdit->installEventFilter(this);
- //_searchLineEdit->setFocusPolicy(Qt::NoFocus);
- _btn = new QPushButton(this);
- _btn->resize(14,14);
- _btn->move(155,41);
- _btn->setStyleSheet("QPushButton{background-color:transparent;border:0px;}");
- _btn->setFocusPolicy(Qt::NoFocus);
- _btn->setVisible(false);
- connect(_btn,SIGNAL(clicked()),this,SLOT(btnClicked()));
- _cluster = new QListWidget(this);
- _cluster->show();
- setListWidget();
- _cluster->setMouseTracking(true);
- _cluster->setFocusPolicy(Qt::NoFocus);
- //_cluster->installEventFilter(this);
- connect(_searchLineEdit,SIGNAL(textChanged(QString)),this,SLOT(textChange(QString)));
- connect(_page,SIGNAL(currentPageChanged(int)),this,SLOT(pageChange(int)));
- connect(_searchLineEdit,SIGNAL(pressed()),this,SLOT(editClicked()));
- connect(_cluster,SIGNAL(itemEntered(QListWidgetItem*)),this,SLOT(itemEnteredSlot(QListWidgetItem*)));
- connect(_cluster,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(itemClickedSlot(QListWidgetItem*)));
- connect(_cluster,SIGNAL(currentRowChanged(int)),this,SLOT(rowChanged(int)));
- //this->setFocus();
- //this->installEventFilter(this);
- }
- void ClusterListWidget::setListWidget()
- {
- _cluster->setStyleSheet("QListWidget{background-color:transparent;color:#19649F;border:0px solid gray;}"
- "QListWidget::item{background-color:transparent;border:0px solid gray;padding-left:28px;color:#b4e5fd}"
- //"QListWidget::item:!selected{border:0px solid gray;padding-left:28px;color:#b4e5fd}"
- //"QListWidget::item:selected:active{background-image:url(:/images/handleMenu_lixt_bg_selected.png);color:#b4e5fd;border-width:0;}"
- "QListWidget::item:selected{background-image:url(:/images/handleMenu_lixt_bg_selected.png);}"
- );
- _cluster->move(0,62);
- _cluster->resize(183,540);
- _cluster->clear();
- pageChange(1);
- }
- void ClusterListWidget::setTitle(QString title)
- {
- lb2->setText(title);
- }
- void ClusterListWidget::setImgs(const QString &normal, const QString &abnormal, const QString &error)
- {
- _normal = normal;
- _abnormal = abnormal;
- __error = error;
- }
- void ClusterListWidget::setVmImgs(const QString &linux_normal,
- const QString &linux_abnormal,
- const QString &linux_error,
- const QString &linux_off,
- const QString &windows_normal,
- const QString &windows_abnormal,
- const QString &windows_error,
- const QString &windows_off)
- {
- _linux_normal = linux_normal;
- _linux_abnormal = linux_abnormal;
- _linux_error = linux_error;
- _linux_off = linux_off;
- _windows_normal = windows_normal;
- _windows_abnormal = windows_abnormal;
- _windows_error = windows_error;
- _windows_off = windows_off;
- }
- void ClusterListWidget::editClicked()
- {
- _searchLineEdit->setStyleSheet("background-image:url(:/images/handleMenu_searchInput_click.png);border:1px solid #536874;");
- _searchLineEdit->update();
- _btn->setVisible(true);
- }
- void ClusterListWidget::btnClicked()
- {
- _searchLineEdit->clear();
- _searchLineEdit->setStyleSheet("background-image:url(:/images/handleMenu_searchInput.png);border:1px solid #536874;");
- this->setFocus();
- }
- void ClusterListWidget::itemEnteredSlot(QListWidgetItem *i)
- {
- _n = _cluster->row(i);
- if(_n == _cluster->currentRow())
- {
- _enter = false;
- }else{
- _enter = true;}
- _x = 0;
- _y = _cluster->row(i)*33 +62;
- _enterPixmap = QPixmap(":/images/handleMenu_lixt_bg_hover.png");
- _cluster->update();
- }
- void ClusterListWidget::itemClickedSlot(QListWidgetItem *i)
- {
- int row =_cluster->row(i);
- qDebug()<< (_currentNum -1)*16 + row;
- _enter = false;//选中跟悬停 只显示选中背景图片
- _cluster->update();
- }
- void ClusterListWidget::rowChanged(int row)
- {
- //qDebug()<< (_currentNum -1)*16 + row;
- _enter = false;//选中跟悬停 只显示选中背景图片
- _cluster->update();
- _n = row;
- }
- //bool ClusterListWidget::eventFilter(QObject *obj, QEvent *e)
- //{
- // if(obj == _cluster){
- // if(e->type() == QEvent::Leave)
- // {
- // _enter = false;
- // _cluster->update();
- // _n = _cluster->currentRow();
- // return true;
- // }
- // }
- // return false;
- // QWidget::eventFilter(obj,e);
- //}
- void ClusterListWidget::textChange(QString text)
- {
- _cluster->clear();
- _list.clear();
- _searchList.clear();
- for(int i = 0;i < NameList.count();i++){
- if(NameList.at(i).contains(text))
- {
- _searchList.append(NameList.at(i));
- }
- }
- _list = _searchList;
- _maxNum = (_list.count() - 1) / 16 +1;
- _currentNum = 1;
- _page->setTotalPage(_maxNum);
- pageChange(1);
- _cluster->update();
- }
- void ClusterListWidget::pageChange(int currentnumber)
- {
- _currentNum = currentnumber;
- _cluster->clear();
- switch (_type) {
- case 0:
- setTitle(tr("all cluster"));
- setImgs(":/images/handleMenu_clusters.png",
- ":/images/handleMenu_clusters_abnormal.png",":/images/handleMenu_clusters_error.png");
- if(_currentNum != _maxNum)
- {
- for(int i= (_currentNum -1) * 16;i <(_currentNum) * 16 ;i++ )
- {
- QListWidgetItem *item = new QListWidgetItem;
- item->setSizeHint(QSize(183,33));
- item->setText(" "+_list.at(i));
- item->setIcon(QIcon(_normal));
- _cluster->addItem(item);
- }
- }else{
- for(int i = (_currentNum -1) * 16;i < _list.count();i++)
- {
- QListWidgetItem *item = new QListWidgetItem;
- item->setSizeHint(QSize(183,33));
- item->setText(" "+_list.at(i));
- item->setIcon(QIcon(__error));
- _cluster->addItem(item);
- }
- }
- break;
- case 1:
- setImgs(":/images/handleMenu_host.png",
- ":/images/handleMenu_host_abnormal.png",":/images/handleMenu_host_error.png");
- if(_currentNum != _maxNum)
- {
- for(int i= (_currentNum -1) * 16;i <(_currentNum) * 16 ;i++ )
- {
- QListWidgetItem *item = new QListWidgetItem;
- item->setSizeHint(QSize(183,33));
- item->setText(" "+_list.at(i));
- item->setIcon(QIcon(_abnormal));
- _cluster->addItem(item);
- }
- }else{
- for(int i = (_currentNum -1) * 16;i < _list.count();i++)
- {
- QListWidgetItem *item = new QListWidgetItem;
- item->setSizeHint(QSize(183,33));
- item->setText(" "+_list.at(i));
- item->setIcon(QIcon(__error));
- _cluster->addItem(item);
- }
- }
- break;
- case 2:
- setVmImgs(":/images/handleMenu_vm.png",":/images/handleMenu_vm_linux_abnormal.png",":/images/handleMenu_vm_linux_error.png",
- ":/images/handleMenu_vm_linux_shutdown.png",":/images/handleMenu_vm_windows.png",":/images/handleMenu_vm_windows_abnormal.png",
- ":/images/handleMenu_vm_windows_error.png",":/images/handleMenu_vm_windows_shutdown.png");
- if(_currentNum != _maxNum)
- {
- for(int i= (_currentNum -1) * 16;i <(_currentNum) * 16 ;i++ )
- {
- QListWidgetItem *item = new QListWidgetItem;
- item->setSizeHint(QSize(183,33));
- item->setText(" "+_list.at(i));
- item->setIcon(QIcon(_linux_abnormal));
- _cluster->addItem(item);
- }
- }else{
- for(int i = (_currentNum -1) * 16;i < _list.count();i++)
- {
- QListWidgetItem *item = new QListWidgetItem;
- item->setSizeHint(QSize(183,33));
- item->setText(" "+_list.at(i));
- item->setIcon(QIcon(_windows_error));
- _cluster->addItem(item);
- }
- }
- break;
- default:
- break;
- }
- _cluster->setCurrentRow(0);
- }
- void ClusterListWidget::paintEvent(QPaintEvent *e)
- {
- QPainter painter(this);
- painter.drawPixmap(0, 0, backGroundPix.width(), backGroundPix.height(), backGroundPix);
- if(_enter)
- {
- painter.drawPixmap(_x,_y,183,33,_enterPixmap);
- }
- //painter.setPen(QColor("#b4e5fd"));
- }
- void ClusterListWidget::showEvent(QShowEvent *e)
- {
- setListWidget();
- }
- void ClusterListWidget::keyPressEvent(QKeyEvent *e)
- {
- qDebug()<<"aaaaaaaaaaaaaaaaaaaaaa"<<_n;
- //n = _cluster->currentRow();
- if(e->key() == Qt::Key_Up)
- {
- if(_n > 0)
- {
- _n -= 1;
- }
- itemEnteredSlot(_cluster->item(_n));
- //_cluster->setCurrentRow(n);
- return;
- }
- if(e->key() == Qt::Key_Down)
- {
- if( _n < _cluster->count() -1){
- _n += 1;
- itemEnteredSlot(_cluster->item(_n));
- }
- //_cluster->setCurrentRow(n);
- return;
- }
- if(e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)
- {
- qDebug()<<"777777777777777";
- _cluster->setCurrentRow(_n);
- return;
- }
- QWidget::keyPressEvent(e);
- }
- SearchLineEdit::SearchLineEdit(QWidget *parent)
- :QLineEdit(parent)
- {
- }
- void SearchLineEdit::focusInEvent(QFocusEvent *e)
- {
- emit pressed();
- QLineEdit::focusInEvent(e);
- }
- void SearchLineEdit::focusOutEvent(QFocusEvent *e)
- {
- QLineEdit::focusInEvent(e);
- }
- #ifndef CLUSTERLISTITEM_H
- #define CLUSTERLISTITEM_H
- #include <QGraphicsItem>
- #include "graphicsitembutton.h"
- #include "clusterlistwidget.h"
- #include <QPalette>
- #include <QtGui>
- class clusterListItem : public QObject, public QGraphicsItem
- {
- Q_OBJECT
- public:
- explicit clusterListItem(QGraphicsItem *parent = 0);
- QRectF boundingRect() const;
- signals:
- protected:
- void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
- bool eventFilter(QObject *obj, QEvent *event);
- private slots:
- void slotBtnClicked();
- private:
- int _width;
- int _height;
- GraphicsItemButton * _listBtn;
- ClusterListWidget * _clusterWidget;
- QGraphicsProxyWidget *_proxy;
- bool _show;
- bool _focus;
- };
- #endif // CLUSTERLISTITEM_H
- #include "clusterlistitem.h"
- clusterListItem::clusterListItem(QGraphicsItem *parent) :
- QGraphicsItem(parent)
- ,_show(false)
- {
- setFiltersChildEvents(true);
- //setAcceptedMouseButtons(Qt::LeftButton);
- //setAcceptHoverEvents(true);
- _width = 22;
- _height =21;
- _listBtn = new GraphicsItemButton(":/images/handleMenu_icon.png",
- ":/images/handleMenu_icon_hover.png",
- ":/images/handleMenu_icon_hover.png",
- "",
- GraphicsItemButton::normal,this);
- _listBtn->setSize(22,21);
- _listBtn->setPos(0,0);
- _listBtn->installEventFilter(this);
- _clusterWidget = new ClusterListWidget(cluster);
- _proxy = new QGraphicsProxyWidget(this);
- _proxy->setWidget(_clusterWidget);
- _proxy->setPos(0,21);
- _proxy->setVisible(_show);
- _clusterWidget->installEventFilter(this);
- //this->installEventFilter(this);
- connect(_listBtn,SIGNAL(clicked()),this,SLOT(slotBtnClicked()));
- }
- QRectF clusterListItem::boundingRect() const
- {
- return QRectF(0, 0, _width, _height);
- }
- void clusterListItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
- {
- //painter->fillRect(QRectF(0, 0, _width, _height), QColor("#FF0000"));
- }
- bool clusterListItem::eventFilter(QObject *obj, QEvent *event)
- {
- if (event->type() == QEvent::FocusIn) {
- qDebug() << "QEvent::FocusIn---" << obj;
- }
- if (event->type() == QEvent::FocusOut) {
- qDebug() << "QEvent::FocusOut---" << obj;
- }
- if (event->type() == QEvent::MouseButtonPress) {
- qDebug() << obj;
- if (obj == _clusterWidget) {
- return true;
- }
- else {
- if (_show == true) {
- _listBtn->setCurrent(false);
- _show = false;
- //_clusterWidget->hide();
- QPropertyAnimation *animation = new QPropertyAnimation(_clusterWidget, "geometry");
- animation->setDuration(300);
- animation->setStartValue(QRect(0,21,183,602));
- animation->setEndValue(QRect(0,21,183,0));
- animation->start();
- }
- }
- }
- return QObject::eventFilter(obj, event);
- }
- void clusterListItem::slotBtnClicked()
- {
- this->setFocus();
- _listBtn->setCurrent(true);
- if(!_show){
- //_proxy->setVisible(!_show);
- _proxy->show();
- QPropertyAnimation *animation = new QPropertyAnimation(_clusterWidget, "geometry");
- animation->setDuration(300);
- animation->setStartValue(QRect(0,21,183,0));
- animation->setEndValue(QRect(0,21,183,602));
- animation->start();
- _show = true;
- }
- else{
- QPropertyAnimation *animation = new QPropertyAnimation(_clusterWidget, "geometry");
- animation->setDuration(300);
- animation->setStartValue(QRect(0,21,183,602));
- animation->setEndValue(QRect(0,21,183,0));
- animation->start();
- _show = false;
- }
- }
- #include "clusterlistwidget.h"
- #include <QApplication>
- #include <QTextCodec>
- #include <QtGui>
- #include "clusterlistitem.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
- QGraphicsView view;
- //view.resize(300,800);
- QGraphicsScene scene;
- scene.setSceneRect(-100, -300, 200, 600);
- view.setScene(&scene);
- view.setSceneRect(0, 0, 200, 600);
- //view.setCacheMode(QGraphicsView::CacheBackground);
- //view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
- clusterListItem *item = new clusterListItem;
- scene.addItem(item);
- item->setPos(0, 0);
- view.resize(314, 814);
- view.show();
- view.installEventFilter(item);
- return a.exec();
- }
三、总结
(1)可以在eventFilter的QEvent::FocusIn和QEvent::FocusOut增加当鼠标移出菜单后自动回收的功能。其他的功能还需进一步完善。(2)原文链接:http://blog.csdn.net/taiyang1987912/article/details/51002420