热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python手写输入法开发_QT手写输入法程序员狗蛋的个人空间OSCHINA中文开源技术交流社区...

QT集成Windows手写输入法关键词:qt、手写输入法、顾客签名此Demo是利用windowsTablet_PC_SDK版本,实现的在Windows下

QT集成Windows手写输入法

关键词:qt、手写输入法、顾客签名

此 Demo 是利用 windows Tablet_PC_SDK 版本,实现的在Windows下实现手写识别,截签名按钮是将签名的区域截取保存成png图片,整体效果如下: 参考下载链接 http://blog.hyrscloud.com/topic/index?id=8

be893b03144160b5c07e5a98ebf1e5f9.gif

简介

此Demo使用QT Creator 4.11.0, Based on Qt 5.14.0 编写,大部分qt版本均适用。

开发编译时,需要安装 Tablet_PC_SDK,开发完毕后,实际部署时,不需要安装此SDK。

Demo源码链接在本文最后提供。

使用步骤

Tablet_PC_SDK_v1.7.exe 安装此文件,此工程将此文件安装到了C:\MicrosoftTablet目录下,文件是开发SDK,开发完毕编译后,在部署的机器上不需要安装此文件;安装过程中,选择用户自定义安装 Custom,安装路径不要使用默认的,选择C:\MicrosoftTablet(没有则新建)。

此SDK可在以下链接中下载,或在本文最后提供的链接上下载。 https://getintopc.com/softwares/development/microsoft-tablet-pc-sdk-free-download/

在.pro中加入: QT += axcontainer

INCLUDEPATH +=C:\MicrosoftTablet\Include //此为SDK安装地址,注意不要使用默认的,因为有的QT不支持中文的()

在头文件中需包含以下头文件: Windows_handwriting\hand\handsinput.h 头文件中包含了C:\MicrosoftTablet\Include 中的以下头文件:

#include

#include

直接编译会出错,需要注释掉以下文件中的两行: C:\MicrosoftTablet\Include\msinkaut.h 中的:

475行://void * __RPC_USER MIDL_user_allocate(size_t);

C:\MicrosoftTablet\Include\tpcshrd.h 中的:

59行://void * __RPC_USER MIDL_user_allocate(size_t);

编译通过后,即可运行。

核心代码

此Demo的核心代码如下,可以根据SDK自行编码调试,或下载源码修改调试:

void handsInput::inputInit(HWND hwnd)

{

// 初始化 COM 接口

CoInitialize(NULL);

HRESULT hr;

// 使用默认的识别器创建一个识别上下文

// 这个上下文会被所有的识别对象使用

hr = CoCreateInstance(CLSID_InkRecognizerContext,NULL, CLSCTX_INPROC_SERVER,IID_IInkRecognizerContext,(void **) &g_pIInkRecoContext);

if (FAILED(hr)) {

qDebug() <<"没有安装手写识别软件&#61;";

return ;

}

// 创建一个墨迹收集对象

hr &#61; CoCreateInstance(CLSID_InkCollector,NULL, CLSCTX_INPROC_SERVER,IID_IInkCollector,(void **) &g_pIInkCollector);

if (FAILED(hr))

return ;

// 获取墨迹对象的指针

hr &#61; g_pIInkCollector->get_Ink(&g_pIInkDisp);

if (FAILED(hr))

return ;

// 将墨迹对象关联一个 hWnd 的窗口

hr &#61; g_pIInkCollector->put_hWnd((long)hwnd);

if (FAILED(hr))

return ;

// 设置颜色

IInkDrawingAttributes* p;

if (SUCCEEDED(g_pIInkCollector->get_DefaultDrawingAttributes(&p)))

{

p->put_Color(RGB(0,0,255));

}

// 打开墨迹输入的开关

hr &#61; g_pIInkCollector->put_Enabled(VARIANT_TRUE);

if (FAILED(hr))

return ;

#if 1

//设置手写只识别为一个字

IInkRecognizerGuide *RecognizerGuide;

hr &#61; CoCreateInstance(CLSID_InkRecognizerGuide,NULL, CLSCTX_INPROC_SERVER,IID_IInkRecognizerGuide,(void **) &RecognizerGuide);

if (FAILED(hr))

return;

InkRecoGuide recoguide;

RECT rect;

rect.bottom &#61; 2;//不能为1

rect.left &#61; 0;

rect.right &#61; 2;//不能为1

rect.top &#61; 0;

recoguide.rectWritingBox &#61; rect;

recoguide.rectDrawnBox &#61; rect;

recoguide.cRows &#61; 1;//不要过大

recoguide.cColumns &#61; 1;

recoguide.midline &#61; -1;

RecognizerGuide->put_GuideData(recoguide);

g_pIInkRecoContext->putref_Guide(RecognizerGuide);

#endif

}

void handsInput::RegDataEx(InPutRltS &Rlts)

{

// 将鼠标变为沙漏

//HCURSOR hCursor &#61; ::SetCursor(::LoadCursor(NULL, IDC_WAIT));

// 获取指向墨迹收集器的指针

// 这个收集器是整个墨迹的快照

if (!Rlts.empty())

{

Rlts.clear();

}

IInkStrokes* pIInkStrokes &#61; NULL;

HRESULT hr &#61; g_pIInkDisp->get_Strokes(&pIInkStrokes);

if (SUCCEEDED(hr))

{

// 将笔触收集器传递给识别器

hr &#61; g_pIInkRecoContext->putref_Strokes(pIInkStrokes);

if (SUCCEEDED(hr))

{

// 识别

IInkRecognitionResult* pIInkRecoResult &#61; NULL;

InkRecognitionStatus RecognitionStatus &#61; IRS_NoError;

hr &#61; g_pIInkRecoContext->Recognize(&RecognitionStatus, &pIInkRecoResult);

if (SUCCEEDED(hr) && (pIInkRecoResult!&#61; NULL))

{

// 枚举可能的所有结果

// CComPtr spIInkRecoAlternates;

IInkRecognitionAlternates* spIInkRecoAlternates;

hr &#61; pIInkRecoResult->AlternatesFromSelection(

0, // in: selection start

-1, // in: selection length; -1 means "up to the last one"

10,// in: the number of alternates we&#39;re interested in

&spIInkRecoAlternates // out: the receiving pointer

);

long lCount &#61; 0;

if (SUCCEEDED(hr) && SUCCEEDED(spIInkRecoAlternates->get_Count(&lCount)))

{

// 获取所有的识别结果

IInkRecognitionAlternate* pIInkRecoAlternate &#61; NULL;

for (LONG iItem &#61; 0; (iItem

{

// Get the alternate string if there is one

if (SUCCEEDED(spIInkRecoAlternates->Item(iItem, &pIInkRecoAlternate)))

{

BSTR bstr &#61; NULL;

if (SUCCEEDED(pIInkRecoAlternate->get_String(&bstr)))

{

InputRlt temp &#61; {0};

QString str &#61; QString::fromWCharArray(bstr);

//qDebug() <<"字体&#61;" <

strcpy(temp.rlt, str.toUtf8().data());

Rlts.push_back(temp);

}

pIInkRecoAlternate->Release();

}

}

//枚举结束&#xff0c;显示出来

}

}

// 重置识别器内容

g_pIInkRecoContext->putref_Strokes(NULL);

}

pIInkStrokes->Release();

}

// 重置鼠标

//::SetCursor(hCursor);

}

参考链接



推荐阅读
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 开发日志:高效图片压缩与上传技术解析 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 卓盟科技:动态资源加载技术的兼容性优化与升级 | Android 开发者案例分享
    随着游戏内容日益复杂,资源加载过程已不仅仅是简单的进度显示,而是连接玩家与开发者的桥梁。玩家对快速加载的需求越来越高,这意味着开发者需要不断优化和提升动态资源加载技术的兼容性和性能。卓盟科技通过一系列的技术创新,不仅提高了加载速度,还确保了不同设备和系统的兼容性,为用户提供更加流畅的游戏体验。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
author-avatar
高桥惜员_136
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有