逛奔的蜗牛

我不聪明,但我会很努力

   ::  :: 新随笔 ::  ::  :: 管理 ::

-------------------------------------CompleteLineEdit.h-------------------------------------

#ifndef COMPLETELINEEDIT_H

#define COMPLETELINEEDIT_H


#include <QtGui/QLineEdit>

#include <QStringList>


class QListView;

class QStringListModel;

class QModelIndex;


class CompleteLineEdit : public QLineEdit {

    Q_OBJECT

public:

    CompleteLineEdit(QStringList words, QWidget *parent = 0);


public slots:

    void setCompleter(const QString &text); // 动态的显示完成列表

    void completeText(const QModelIndex &index); // 点击完成列表中的项,使用此项自动完成输入的单词


protected:

    virtual void keyPressEvent(QKeyEvent *e);

    virtual void focusOutEvent(QFocusEvent *e);


private:

    QStringList words; // 整个完成列表的单词

    QListView *listView; // 完成列表

    QStringListModel *model; // 完成列表的model

};


#endif // COMPLETELINEEDIT_H


-------------------------------------CompleteLineEdit.cpp-------------------------------------

#include "CompleteLineEdit.h"

#include <QKeyEvent>

#include <QtGui/QListView>

#include <QtGui/QStringListModel>

#include <QDebug>


CompleteLineEdit::CompleteLineEdit(QStringList words, QWidget *parent)

    : QLineEdit(parent), words(words) {

    listView = new QListView(this);

    model = new QStringListModel(this);

    listView->setWindowFlags(Qt::ToolTip);


    connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(setCompleter(const QString &)));

    connect(listView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(completeText(const QModelIndex &)));

}


void CompleteLineEdit::focusOutEvent(QFocusEvent *e) {

    //listView->hide();

}


void CompleteLineEdit::keyPressEvent(QKeyEvent *e) {

    if (!listView->isHidden()) {

        int key = e->key();

        int count = listView->model()->rowCount();

        QModelIndex currentIndex = listView->currentIndex();


        if (Qt::Key_Down == key) {

            // 按向下方向键时,移动光标选中下一个完成列表中的项

            int row = currentIndex.row() + 1;

            if (row >= count) {

                row = 0;

            }


            QModelIndex index = listView->model()->index(row, 0);

            listView->setCurrentIndex(index);

        } else if (Qt::Key_Up == key) {

            // 按向下方向键时,移动光标选中上一个完成列表中的项

            int row = currentIndex.row() - 1;

            if (row < 0) {

                row = count - 1;

            }


            QModelIndex index = listView->model()->index(row, 0);

            listView->setCurrentIndex(index);

        } else if (Qt::Key_Escape == key) {

            // 按下Esc键时,隐藏完成列表

            listView->hide();

        } else if (Qt::Key_Enter == key || Qt::Key_Return == key) {

            // 按下回车键时,使用完成列表中选中的项,并隐藏完成列表

            if (currentIndex.isValid()) {

                QString text = listView->currentIndex().data().toString();

                setText(text);

            }


            listView->hide();

        } else {

            // 其他情况,隐藏完成列表,并使用QLineEdit的键盘按下事件

            listView->hide();

            QLineEdit::keyPressEvent(e);

        }

    } else {

        QLineEdit::keyPressEvent(e);

    }

}


void CompleteLineEdit::setCompleter(const QString &text) {

    if (text.isEmpty()) {

        listView->hide();

        return;

    }


    if ((text.length() > 1) && (!listView->isHidden())) {

        return;

    }


    // 如果完整的完成列表中的某个单词包含输入的文本,则加入要显示的完成列表串中

    QStringList sl;

    foreach(QString word, words) {

        if (word.contains(text)) {

            sl << word;

        }

    }


    model->setStringList(sl);

    listView->setModel(model);


    if (model->rowCount() == 0) {

        return;

    }


    // Position the text edit

    listView->setMinimumWidth(width());

    listView->setMaximumWidth(width());


    QPoint p(0, height());

    int x = mapToGlobal(p).x();

    int y = mapToGlobal(p).y() + 1;


    listView->move(x, y);

    listView->show();

}


void CompleteLineEdit::completeText(const QModelIndex &index) {

    QString text = index.data().toString();

    setText(text);

    listView->hide();

}


-------------------------------------main.cpp----------------------------------

#include <QtGui/QApplication>

#include "CompleteLineEdit.h"

#include <QtGui>

#include <QCompleter>

#include <QStringList>


int main(int argc, char *argv[]) {

    QApplication a(argc, argv);


    QStringList sl = QStringList() << "Biao" << "Bin" << "Huang" << "Hua" << "Hello" << "BinBin" << "Hallo";

    QWidget widgetw;

    CompleteLineEdit * edit= new CompleteLineEdit(sl);

    QPushButton *button = new QPushButton("Button");

    QHBoxLayout *layout = new QHBoxLayout();

    layout->addWidget(edit);

    layout->addWidget(button);

    widgetw.setLayout(layout);


    widgetw.show();


    CompleteLineEdit e(sl);

    e.show();


    return a.exec();

}


posted on 2009-10-31 02:09 逛奔的蜗牛 阅读(8731) 评论(1)  编辑 收藏 引用 所属分类: Qt

评论

# re: Qt:自动完成的QLineEdit(非使用QCompleter版)[未登录] 2012-02-25 17:39 tony
这个代码感觉bug比较多,我自己写了一个稍微好一点的:http://download.csdn.net/detail/jyxpm/4089691  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理