本文主要是介绍【Qt编程】基于Qt的词典开发系列十四自动补全功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近写了一个查单词的类似有道词典的软件,里面就有一个自动补全功能(即当你输入一个字母时,就会出现几个候选项)。这个自动补全功能十分常见,百度搜索关键词时就会出现。不过它们这些补全功能都是与你输入的进行首字匹配,有时也会不方便。例如,如果我输入一个“好”,如果是首字匹配的话会出现下图:
如果是句中匹配的话,则是这种情况:
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QMouseEvent>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void mousePressEvent(QMouseEvent *event);
private:Ui::Widget *ui;
signals:void movesignal();
};#endif // WIDGET_H
#ifndef COMPLETELINEEDIT_H
#define COMPLETELINEEDIT_H
#include <QLineEdit>
#include <QStringList>
#include<QFile>
#include<QTextCodec>
#include<QDebug>
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 slots:void replyMoveSignal();
private:QStringList words; // 整个完成列表的单词QListView *listView; // 完成列表QStringListModel *model; // 完成列表的model
};
#endif // COMPLETELINEEDIT_H
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}void Widget::mousePressEvent(QMouseEvent *event)
{emit movesignal();
}
#include "CompleteLineEdit.h"
#include <QKeyEvent>
#include <QListView>
#include <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::replyMoveSignal()
{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;}//填充模式二
// if(word.indexOf(text,0,Qt::CaseInsensitive)==0)//必需与句首内容相同
// sl<<word;}model->setStringList(sl);listView->setModel(model);if (model->rowCount() == 0){return;}// 设置列表的显示位置及大小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();
}
#include <QApplication>
#include "CompleteLineEdit.h"
#include"widget.h"
int main(int argc, char *argv[]) {QApplication a(argc, argv);QStringList sl;QFile *inFile=new QFile ("input.txt");//这个是你自己的词库if(!inFile->open(QIODevice::ReadOnly|QIODevice::Text)){qDebug()<<"cannot read!";}while(!inFile->atEnd()){QByteArray line = inFile->readLine();QTextCodec* gbk_codec = QTextCodec::codecForName("GBK");QString gbk_string = gbk_codec->toUnicode(line);if (!line.isEmpty())sl << gbk_string.trimmed();//将文件中的词汇输入到sl中}inFile->close();//关闭文件sl<< "你好" << "好的" << "好吗" << "你的" << "真好啊" << "天真" << "你好吗";Widget *w= new Widget();CompleteLineEdit * edit= new CompleteLineEdit(sl,w);w->show();// QObject::connect(w,SIGNAL(movesignal()),edit,SLOT(replyMoveSignal()));return a.exec();
}
最后放两张查单词软件用到的自动补全功能的截图:
基于Qt的词典开发系列
- 词典框架设计及成品展示
- 本地词典的设计
- 开始菜单的设计
- 无边框窗口的缩放与拖动
- 无边框窗口的拖动
- 界面美化设计
- 调用网络API
- 用户登录及API调用的实现
- JSON数据解析
- 国际音标的显示
- 系统托盘的显示
- 调用讲述人
- 音频播放
- 自动补全功能
- HTML特殊字符及正则表达式
- 后序
原文:http://blog.csdn.net/tengweitw/article/details/38689745
作者:nineheadedbird
这篇关于【Qt编程】基于Qt的词典开发系列十四自动补全功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!