【Qt编程】基于Qt的词典开发系列十四自动补全功能

2024-03-24 15:08

本文主要是介绍【Qt编程】基于Qt的词典开发系列十四自动补全功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    最近写了一个查单词的类似有道词典的软件,里面就有一个自动补全功能(即当你输入一个字母时,就会出现几个候选项)。这个自动补全功能十分常见,百度搜索关键词时就会出现。不过它们这些补全功能都是与你输入的进行首字匹配,有时也会不方便。例如,如果我输入一个“好”,如果是首字匹配的话会出现下图:


如果是句中匹配的话,则是这种情况:


你可以根据自己的要求进行选择哪一种模式。
    Qt中自带QCompleter类来实现上面的自动补全功能,读者可以在Qt自带的demo中很容易的学会该类的使用。下面我要讲的是自己构造一个比QCompleter更强大的类。有人会说,为什么有现成的不用,要自己写一个类呢?因为,我用QCompleter类的时候发现,它只有句首匹配模式(可能是我没仔细看文档,不知道可以改变模式),其次,当我的词库非常大的时候,有的时候就不会出现下拉自动补全列表,具体原因也不清楚。所以自己写了一个类,来实现QCompleter类所没有功能。废话不多说,直接见代码(代码注解比较详细,就不仔细讲解了,widget.ui文件也不给出了,就是一个空的界面):
1、widget.h
#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


2.completelineedit.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


3.widget.cpp
#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();
}


4.completelineedit.cpp
#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();
}


5.main.cpp
#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的词典开发系列

  1. 词典框架设计及成品展示
  2. 本地词典的设计
  3. 开始菜单的设计
  4. 无边框窗口的缩放与拖动
  5. 无边框窗口的拖动
  6. 界面美化设计
  7. 调用网络API
  8. 用户登录及API调用的实现
  9. JSON数据解析
  10. 国际音标的显示
  11. 系统托盘的显示
  12. 调用讲述人
  13. 音频播放
  14. 自动补全功能
  15. HTML特殊字符及正则表达式
  16. 后序
作品下载地址(发布版)http://download.csdn.net/detail/tengweitw/8548767
作品下载地址(绿色版)http://download.csdn.net/detail/tengweitw/8830495
源码下载地址http://download.csdn.net/detail/tengweitw/8830503


原文:http://blog.csdn.net/tengweitw/article/details/38689745

作者:nineheadedbird




这篇关于【Qt编程】基于Qt的词典开发系列十四自动补全功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841967

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

Java实现预览与打印功能详解

《Java实现预览与打印功能详解》在Java中,打印功能主要依赖java.awt.print包,该包提供了与打印相关的一些关键类,比如PrinterJob和PageFormat,它们构成... 目录Java 打印系统概述打印预览与设置使用 PageFormat 和 PrinterJob 类设置页面格式与纸张

MySQL 8 中的一个强大功能 JSON_TABLE示例详解

《MySQL8中的一个强大功能JSON_TABLE示例详解》JSON_TABLE是MySQL8中引入的一个强大功能,它允许用户将JSON数据转换为关系表格式,从而可以更方便地在SQL查询中处理J... 目录基本语法示例示例查询解释应用场景不适用场景1. ‌jsON 数据结构过于复杂或动态变化‌2. ‌性能要

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自