Qt自定义Combobox实现列表上拉展示

废话

由于最近项目需要,想用一个能够上拉的Combobox,但是试了各种方法发现QCombobox并不能达到我需要的效果,所以决定自己写一个。

方法

其实很简单,combobox可认为是按钮和一个列表组成,按钮由QPushButton来实现,列表由QListView代替。

先来看看效果

![这里写图片描述](https://img-blog.csdn.net/20170609204717828?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDY1NTI4OA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

代码

.h文件
#ifndef PUSHCOMBOX_H
#define PUSHCOMBOX_H
#include 
#include 
#include 
#include 
#include 
class pushcombox : public QPushButton
{
    Q_OBJECT
public:
    pushcombox(QWidget *widget=0);
    Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
    Q_PROPERTY(QString currentText READ currentText WRITE setCurrentText NOTIFY currentTextChanged)
    void addtextItem(QString );
    void addtextItems(QStringList);
    int currentIndex(){return  m_currindex;}
    QString currentText(){return m_currenttext;}
    void setCurrentIndex(int i);
    void setCurrentText(QString  str);
signals:
    void    activated(int index);
    void    activated(const QString & text);
    void    currentIndexChanged(int index);
    void    currentTextChanged(const QString text);
public slots:
    void    on_clicked();
    void    on_showPopup();
private:
    QListView *listview;
    QStringListModel *model;
    int m_currindex;
    QString m_currenttext;
    QWidget *widt;
    int parentwith;
    int parentheight;
};

#endif // PUSHCOMBOX_H
.cpp文件
#include "pushcombox.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QDesktopWidget>
pushcombox::pushcombox(QWidget *widget) : QPushButton(widget)
{
    m_currindex=0;
    m_currenttext="";
    widt=new QWidget(widget);
    listview=new QListView;
    QVBoxLayout *layout=new QVBoxLayout;
    layout->addWidget(listview);
    layout->setContentsMargins(0,0,0,0);
    widt->setLayout(layout);
    model=new QStringListModel;
    listview->setModel(model);
    listview->setEditTriggers(QAbstractItemView::NoEditTriggers);
    widt->hide();
    connect(listview,SIGNAL(clicked(QModelIndex)),SLOT(on_clicked()));
    connect(this,SIGNAL(clicked(bool)),this,SLOT(on_showPopup()));
}
void pushcombox::addtextItem(QString str)
{
    QStringList list;
    list=model->stringList();
    list+=str;
    model->setStringList(list);
    this->setText(list.at(m_currindex));
}
void pushcombox::on_clicked()
{
    QStringList list;
    list=model->stringList();
    this->setText(list.at(listview->currentIndex().row()));
    setCurrentIndex(listview->currentIndex().row());
    setCurrentText(list.at(listview->currentIndex().row()));
    widt->hide();
}
void pushcombox::on_showPopup()
{
    if(!widt->isHidden())
    {
        widt->hide();
        return;
    }
    int height=20*listview->model()->rowCount();
    if(height>window()->height()-this->y())
        height=this->y();
    widt->resize(this->width(),height);
    widt->move(this->x(),this->y()-height);
    widt->show();
}
void pushcombox::addtextItems(QStringList list)
{
    model->setStringList(list);
    this->setText(list.at(m_currindex));
}
void pushcombox::setCurrentIndex(int i)
{
    if(i==m_currindex)
        return;
    m_currindex=i;
    QStringList list;
    list=model->stringList();
    this->setText(list.at(m_currindex));
    emit currentIndexChanged(m_currindex);
}
void pushcombox::setCurrentText(QString str)
{
    if(str==m_currenttext)
        return;
    m_currenttext=str;
    emit currentTextChanged(m_currenttext);
}
测试
 pushcombox *com=new pushcombox(this);
 QStringList list;
 list<<"1"<<"2"<<"3"<<"4"<<"a"<<"b"<<"c"<<"d"<<"e"<<"f"<<"h";
 QStringListModel *model=new QStringListModel;
 model->setStringList(list);
 ui->listView->setModel(model);
 com->addtextItems(list);
 com->addtextItem("5");
 com->addtextItem("6");
 connect(com,SIGNAL(currentIndexChanged(int)),this,SLOT(on_mycombobx(int)));
 connect(com,SIGNAL(currentTextChanged(QString)),this,SLOT(on_mycombobx(QString)));

最后

关于上拉Combobox就这些,其他方向(下拉、侧拉),光标移动时候按钮上文字也跟随光标,控件失去焦点时关闭控件等等由于时间关系没有完善,在这先做个记录希望有时间了会来完成吧!

你可能感兴趣的:(Qt)