手写输入和软键盘输入

Qt5开发虚拟软键盘插件,支持qt输入控件和浏览器输入控件自动弹出 一、前言 最近有个需求,需要在windows上开发一款软键盘,以支持触摸屏上输入文字。为了同时支持Qt编辑框和浏览器编辑框,软键盘以插件的形式开发。于是被集成的目标项目再无需额外的开发工作,直接添加依赖的文件和库即可使用。软键盘支持中文拼音输入和手写输入两种方式。我的开发环境是Qt5.10.1+vs2015。 二、先上效果图: 1、点击QLineEdit编辑框,自动弹出软键盘。使用默认的QLine... 阅读详情

今天项目需要完成一个支持手写和键盘都可以输入的功能,点击键盘切换到软键盘输入,此时按钮会变成手写,在点击就回到手写。按钮是checkbox。功能很简单。

这里写图片描述

   支持手写和键盘输入,其实并不难,就是布局麻烦点,还有就是画布麻烦点(我是网上找现成的),其他的都很简单。我注释写的很清楚就直接贴代码了。


 1.画布代码。
package example.caobin.com.myhandwrite;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;


/**
 * 绘制Path的View 用于手写签名
 */
@SuppressLint("ClickableViewAccessibility")
public class LinePathView extends View {

    private  static final String TAG=LinePathView.class.getSimpleName();

    private Context mContext;

    /**
     * 笔画X坐标起点
     */
    private float mX;
    /**
     * 笔画Y坐标起点
     */
    private float mY;
    /**
     * 手写画笔
     */
    private final Paint mGesturePaint = new Paint();
    /**
     * 路径
     */
    private final Path mPath = new Path();
    /**
     * 背景画布
     */
    private Canvas cacheCanvas;
    /**
     * 背景Bitmap缓存
     */
    private Bitmap cachebBitmap;
    /**
     * 是否已经签名
     */
    private boolean isTouched = false;


    /**
     * 画笔宽度 px;
     */
    private int mPaintWidth = 10;

    /**
     * 前景色
     */
    private int mPenColor = Color.BLACK;

    private int mBackColor= Color.TRANSPARENT;
    public LinePathView(Context context) {
        super(context);
        init(context);
    }

    public LinePathView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public LinePathView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void init(Context context) {
        this.mContext = context;
        mGesturePaint.setAntiAlias(true);
        mGesturePaint.setStyle(Style.STROKE);
        mGesturePaint.setStrokeWidth(mPaintWidth);
        mGesturePaint.setColor(mPenColor);

    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        cachebBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
        cacheCanvas = new Canvas(cachebBitmap);
        cacheCanvas.drawColor(mBackColor);
        isTouched=false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchDown(event);
                break;
            case MotionEvent.ACTION_MOVE:
                isTouched = true;
                touchMove(event);
                break;
            case MotionEvent.ACTION_UP:
                cacheCanvas.drawPath(mPath, mGesturePaint);
                mPath.reset();
                break;
        }
        // 更新绘制
        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawBitmap(cachebBitmap, 0, 0, mGesturePaint);
        // 通过画布绘制多点形成的图形
        canvas.drawPath(mPath, mGesturePaint);
    }

    // 手指点下屏幕时调用
    private void touchDown(MotionEvent event) {

        // mPath.rewind();
        // 重置绘制路线,即隐藏之前绘制的轨迹
        mPath.reset();
        float x = event.getX();
        float y = event.getY();

        mX = x;
        mY = y;
        // mPath绘制的绘制起点
        mPath.moveTo(x, y);
    }

    // 手指在屏幕上滑动时调用
    private void touchMove(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();

        final float previousX = mX;
        final float previousY = mY;

        final float dx = Math.abs(x - previousX);
        final float dy = Math.abs(y - previousY);

        // 两点之间的距离大于等于3时,生成贝塞尔绘制曲线
        if (dx >= 3 || dy >= 3) {
            // 设置贝塞尔曲线的操作点为起点和终点的一半
            float cX = (x + previousX) / 2;
            float cY = (y + previousY) / 2;

            // 二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点
            mPath.quadTo(previousX, previousY, cX, cY);

            // 第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值
            mX = x;
            mY = y;
        }
    }

    /**
     * 清除画板
     */
    public void clear() {
        if (cacheCanvas != null) {
            isTouched = false;
            mGesturePaint.setColor(mPenColor);
            cacheCanvas.drawColor(mBackColor, PorterDuff.Mode.CLEAR);
            mGesturePaint.setColor(mPenColor);
            invalidate();
        }
    }


    /**
     * 保存画板
     *
     * @param path 保存到路劲
     */

    public void save(String path) throws IOException {
        save(path, false, 0);
    }

    /**
     * 保存画板
     *
     * @param path       保存到路劲
     * @param clearBlank 是否清楚空白区域
     * @param blank  边缘空白区域
     */
    public void save(String path, boolean clearBlank, int blank) throws IOException {

        Bitmap bitmap=cachebBitmap;
        //BitmapUtil.createScaledBitmapByHeight(srcBitmap, 300);//  压缩图片
        if (clearBlank) {
            bitmap = clearBlank(bitmap, blank);
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
        byte[] buffer = bos.toByteArray();
        if (buffer != null) {
                File file = new File(path);
                if (file.exists()) {
                    file.delete();
                }
                OutputStream outputStream = new FileOutputStream(file);
                outputStream.write(buffer);
                outputStream.close();
        }
    }

    /**
     * 获取画板的bitmap
     * @return
     */
    public Bitmap getBitMap()
    {
        setDrawingCacheEnabled(true);
        buildDrawingCache();
        Bitmap bitmap=getDrawingCache();
        setDrawingCacheEnabled(false);
        return bitmap;
    }




    /**
     * 逐行扫描 清楚边界空白。
     *
     * @param bp
     * @param blank 边距留多少个像素
     * @return
     */
    private Bitmap clearBlank(Bitmap bp, int blank) {
        int HEIGHT = bp.getHeight();
        int WIDTH = bp.getWidth();
        int top = 0, left = 0, right = 0, bottom = 0;
        int[] pixs = new int[WIDTH];
        boolean isStop;
        for (int y = 0; y < HEIGHT; y++) {
            bp.getPixels(pixs, 0, WIDTH, 0, y, WIDTH, 1);
            isStop = false;
            for (int pix : pixs) {
                if (pix != mBackColor) {
                    top = y;
                    isStop = true;
                    break;
                }
            }
            if (isStop) {
                break;
            }
        }
        for (int y = HEIGHT - 1; y >= 0; y--) {
            bp.getPixels(pixs, 0, WIDTH, 0, y, WIDTH, 1);
            isStop = false;
            for (int pix : pixs) {
                if (pix != mBackColor) {
                    bottom = y;
                    isStop = true;
                    break;
                }
            }
            if (isStop) {
                break;
            }
        }
        pixs = new int[HEIGHT];
        for (int x = 0; x < WIDTH; x++) {
            bp.getPixels(pixs, 0, 1, x, 0, 1, HEIGHT);
            isStop = false;
            for (int pix : pixs) {
                if (pix != mBackColor) {
                    left = x;
                    isStop = true;
                    break;
                }
            }
            if (isStop) {
                break;
            }
        }
        for (int x = WIDTH - 1; x > 0; x--) {
            bp.getPixels(pixs, 0, 1, x, 0, 1, HEIGHT);
            isStop = false;
            for (int pix : pixs) {
                if (pix != mBackColor) {
                    right = x;
                    isStop = true;
                    break;
                }
            }
            if (isStop) {
                break;
            }
        }
        if (blank < 0) {
            blank = 0;
        }
        left = left - blank > 0 ? left - blank : 0;
        top = top - blank > 0 ? top - blank : 0;
        right = right + blank > WIDTH - 1 ? WIDTH - 1 : right + blank;
        bottom = bottom + blank > HEIGHT - 1 ? HEIGHT - 1 : bottom + blank;
        return Bitmap.createBitmap(bp, left, top, right - left, bottom - top);
    }

    /**
     * 设置画笔宽度 默认宽度为10px
     *
     * @param mPaintWidth
     */
    public void setPaintWidth(int mPaintWidth) {
        mPaintWidth = mPaintWidth > 0 ? mPaintWidth : 10;
        this.mPaintWidth = mPaintWidth;
        mGesturePaint.setStrokeWidth(mPaintWidth);

    }


    public void setBackColor(@ColorInt int backColor)
    {
        mBackColor=backColor;
    }


    /**
     * 设置画笔颜色
     *
     * @param mPenColor
     */
    public void setPenColor(int mPenColor) {
        this.mPenColor = mPenColor;
        mGesturePaint.setColor(mPenColor);
    }

    /**
     * 是否有签名
     *
     * @return
     */
    public boolean getTouched() {
        return isTouched;
    }
}
 2.布局代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--顶部布局-->
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:background="@drawable/register_list_top_bg">

        <Button
            android:id="@+id/btn_dialog_close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginBottom="3dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="3dp"
            android:background="@drawable/btn_close_selector" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="请签名"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <Button
            android:id="@+id/btn_save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="3dp"
            android:layout_marginRight="8dp"
            android:layout_marginTop="3dp"
            android:layout_toLeftOf="@+id/tv_empty"
            android:background="@drawable/save_note_selector" />

        <TextView
            android:id="@+id/tv_empty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="" />

    </RelativeLayout>
    <!--下部布局-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@drawable/register_bias_bg">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="8dp"
            android:background="#FCFBF9"
            android:orientation="vertical">

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="0.84">

                <ImageView
                    android:id="@+id/img_view_hand_write_hint"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:src="@drawable/hand_write_name_hint_bg" />

                <example.caobin.com.myhandwrite.LinePathView
                    android:id="@+id/path_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:visibility="visible" />

                <EditText
                    android:id="@+id/edit_keyboard_register"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@null"
                    android:gravity="left|top"
                    android:imeOptions="flagNoExtractUi"
                    android:visibility="invisible" />
            </FrameLayout>

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:src="@drawable/bottom_dotted_line" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="0.1"
                android:gravity="center_vertical">

                <CheckBox
                    android:id="@+id/check_input_type"
                    android:layout_width="60dp"
                    android:layout_height="30dp"
                    android:layout_marginLeft="30dp"
                    android:checked="true"
                    android:button="@null"
                    android:background="@drawable/btn_keyboard_selector" />

                <Button
                    android:id="@+id/btn_clear_screen"
                    android:layout_width="60dp"
                    android:layout_height="30dp"
                    android:layout_marginLeft="10dp"
                    android:background="@drawable/btn_clear_screen_gray_bg" />

                <View
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="0.65" />

                <TextView
                    android:id="@+id/tv_date"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_marginRight="20dp"
                    android:gravity="center"
                    android:text="2016年15月15"
                    android:textColor="@color/black"
                    android:textSize="18sp" />

            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

3.mainActivity代码

package example.caobin.com.myhandwrite;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private LinePathView mLinePathView;//手写输入
    private Button clearBtn;//清屏按钮
    private EditText keyboardInputEdit;//键盘输入
    private CheckBox inputTypeCheckBox;//切换输入方式(手写/键盘)
    private int inputType = 1;//1手写(默认) 0键盘
    private ImageView inputHintView;//输入框提示背景图片

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initListener();
    }

    private void initView() {
        mLinePathView = (LinePathView) findViewById(R.id.path_view);
        clearBtn = (Button) findViewById(R.id.btn_clear_screen);
        keyboardInputEdit = (EditText) findViewById(R.id.edit_keyboard_register);
        inputTypeCheckBox = (CheckBox) findViewById(R.id.check_input_type);
        inputHintView = (ImageView) findViewById(R.id.img_view_hand_write_hint);
        findViewById(R.id.btn_dialog_close).setOnClickListener(this);
        findViewById(R.id.btn_save).setOnClickListener(this);
        keyboardInputEdit.setOnClickListener(this);
        clearBtn.setOnClickListener(this);
        //显示当前日期
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日", Locale.getDefault());
        ((TextView) findViewById(R.id.tv_date)).setText(sdf.format(c.getTime()));
    }

    /**
     * 监听事件
     */
    private void initListener() {
        //判断签名框是否有签名,改变清除按钮背景和隐藏签名提示背景
        mLinePathView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                inputHintView.setVisibility(View.INVISIBLE);
                clearBtn.setBackgroundResource(R.drawable.btn_clear_screen_selector);
                return false;
            }
        });
        //切换输入方式
        inputTypeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                cleanScreen();
                //true手写  false键盘
                if (isChecked) {
                    keyboardInputEdit.setVisibility(View.INVISIBLE);
                    mLinePathView.setVisibility(View.VISIBLE);
                    inputType = 1;
                } else {
                    keyboardInputEdit.setVisibility(View.VISIBLE);
                    mLinePathView.setVisibility(View.INVISIBLE);
                    inputType = 0;
                }
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_dialog_close: {
                //关闭
                finish();
            }
            break;
            case R.id.edit_keyboard_register: {
                //edittext点击
                inputHintView.setVisibility(View.INVISIBLE);
                clearBtn.setBackgroundResource(R.drawable.btn_clear_screen_selector);
            }
            break;
            case R.id.btn_save: {
                //保存
                save();
            }
            break;
            case R.id.btn_clear_screen: {
                //清屏
                cleanScreen();
            }
            break;
            default:
                break;
        }
    }

    /**
     * 清屏
     */
    private void cleanScreen() {
        mLinePathView.clear();
        keyboardInputEdit.setText(null);
    }


    private String name = "";//键盘输入姓名,当然你可以自定义保存的方式

    /**
     * 保存信息
     */
    private void save() {
        if (inputType == 1) {
            //手写
            if (!mLinePathView.getTouched()) {
                //没有输入就点击保存,给用户提示
                toast("请签写你的姓名!");
            } else {
                //如果已经签写内容,进行保存
                saveImage("image");
            }

        } else {
            //键盘
            if (TextUtils.isEmpty(keyboardInputEdit.getText())) {
                //没有输入就点击保存,给用户提示
                toast("请输入你的姓名!");
            } else {
                //如果已经签写内容,进行保存,保存的方式可以自定义,这里就只保存在类变量里。
                name = keyboardInputEdit.getText().toString();
                toast("保存的姓名为:" + name);
            }
        }
    }

    /**
     * 保存签字图片
     *
     * @param imageName 保存的名称
     */
    private void saveImage(String imageName) {
        //图片保存的路径. 我的手机是小米
        //图片在data/saveImagePath目录下
        String imagePath = Constants.FilePath + File.separator + imageName + ".png";
        try {
            mLinePathView.save(imagePath, false, 0);
            toast("保存成功!");
            //保存成功后清屏
            cleanScreen();
        } catch (IOException e) {
            toast("保存失败!");
        }
    }

    /**
     * Toast任何类型的数据
     *
     * @param object
     */
    private void toast(Object object) {
        Toast.makeText(this, object.toString(), Toast.LENGTH_SHORT).show();
    }
}

4.当然还有一些资源文件,太零碎了。想要的直接从github上clone吧。
我的git

Android软键盘softboard(1) 从SDK 1.5版本以后,Android就开放它的IMF(Input Method Framework),让我们能够开发自己的输入法。而开发输入法最好的参考就是Android自带的Sample-SoftKeyboard,虽然这个例子仅包含英文和数字输入,但是它本身还算完整和清楚,对我们开始Android开发实战有很大帮助。 什么是IMF:        IMF(Input Method Fra 阅读详情

相关推荐

Qt实现输入法(附完整源码)

Qt实现输入法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1887

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

QT集成Windows手写输入法关键词:qt、手写输入法、顾客签名此 Demo 是利用 windows Tablet_PC_SDK 版本,实现的在Windows下实现手写识别,截签名按钮是将签名的区域截取保存成png图片,整体效果如下: 参考下载链接 http://blog.hyrscloud.com/topic/index?id=8 简介此Demo使用QT Creator 4.11.0, Bas...

weixin_29268385的博客 1192

C#实现 手写输入功能 (附完整源码)

C#实现 手写输入功能 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 733

输入法(纯手写)

def main(p2hzfile,profile): p2hz = {} ngramprob = {} pyinit(p2hz , p2hzfile) ngraminit(ngramprob , profile) while 1: pinyin = input("请输入") if pinyin == 'q': ...

weixin_43780551的博客 640

JavaScript 通过注册表的形式调用搜狗输入法的手写输入功能

背景 最近在做一个项目,在屏幕上需要使用手写功能,填写对某些菜品的评价,想想这种接入手写外设多简单的事情,奈何老板为了节省成本,不愿购买外设,更何况考虑到设备版本以及电脑主板兼容性的问题,放弃了外设的想法,想到屏幕是触摸屏是可以用手指自己手动比比划划的。于是想到了输入法有这种手写输入的功能。但是项目采用的web实现,如何调用起输入法的手写功能呢? 回顾迅雷 小伙伴们一定用过迅雷这款神奇,它是如何在网页上点击下载按钮就能调用迅雷软件进行下载的呢? 我们来F12看下如何实现的 这是个什么协议呢,从来没有见过

老骆驼的博客 1097

在Android Studio中实现自定义软键盘的全过程

是Android系统提供的一个抽象类,它继承自Service,主要用于创建自定义的输入法。负责管理输入法窗口的显示和隐藏,接收用户的输入事件,并将其转换成文本。自定义输入法可以处理各种输入模式,比如键盘输入、手写输入、语音输入等。它还负责显示候选词、自动完成、语法纠正等辅助功能,提高用户体验。通过监听用户的输入动作,比如点击键盘上的键,然后将这些动作转换成文本输入到当前的文本输入框中。

weixin_36064575的博客 639

Qt软键盘程序源码分享:Qt环境下的中文输入解决方案

Qt软键盘程序源码分享:Qt环境下的中文输入解决方案 去发现同类优质开源项目:https://gitcode.com/ 项目核心功能/场景 为Qt应用程序提供便捷的中文输入及手写输入功能。 项目介绍 在现代软件开发中,用户交互体验至关重要。尤其是在国内市场,中文输入功能不可或缺。Qt软键盘程序源码分享项目正是为了满足这一需求而诞生的。该项目提供了一个基于Qt环境,使用谷歌拼音引擎实现的软键盘程序源...

gitblog_06706的博客 1025

百度手写输入法源码 v1.0

百度手写输入法源码,无需下载客户端直接在线使用,目前网络上此类源码大多不能用了。

支持拼音和五笔的js软键盘,仿iphone风格,神一样的大作

原文地址:提供一款支持拼音和五笔的js软键盘,仿iphone风格,超级好用。 http://download.youkuaiyun.com/detail/iceman1983/2656585     最近找一款大触摸屏的输入法,用于 chrome 浏览器,尝试各种软键盘的安装与卸载,几乎快要放弃下载,打算自己重写一个的时候,遇到了这个神一样的大作,极力推荐。 当然如果有大牛加上手写输入法就更完美了。 ...

cnmqw的专栏 464

百度手写输入法源代码

百度手写输入法源码,无需下载客户端直接在线使用,目前网络上此类源码大多不能用了,。

AutoSAR开发实战:如何用Matlab/Simulink从零搭建SWC组件(附完整代码示例)

本文详细介绍了使用Matlab/Simulink从零开发AutoSAR SWC组件的全流程,包括环境配置、ARXML文件导入、算法模型开发、代码生成与集成验证等关键步骤。通过实战案例和完整代码示例,帮助开发者掌握AutoSAR标准下的软件开发技术,提升汽车电子系统的开发效率。

weixin_29093017的博客 256

MiniGUI输入法模块mGi软键盘使用实例

mGi 是飞漫软件提供的一个输入法组件,该组件目前提供了软键盘输入法和手写输入法框架,并提供给用户管理输入法的容器,通过这个容器,用户还可以添加自定义的输入法。此外,对于软键盘输入法,用户可以自定义显示的键盘位图,并可添加不同的输入翻译方式(自带中文全拼输入法)。 mGi 现在已随着MiniGUI 3.0.12 版本一起开源, 可以在http://www.minigui.org/downlo

奋斗中拥有 7278

【实战】ComfyUI-Impact-Subpack插件安装与UltralyticsDetectorProvider节点修复全流程

本文详细解析了ComfyUI中UltralyticsDetectorProvider节点缺失的原因,并提供了完整的ComfyUI-Impact-Subpack插件安装与修复全流程。核心在于Impact Pack插件架构调整导致节点被拆分至子插件包。指南涵盖手动安装、依赖安全配置、模型文件管理及深度排错步骤,帮助用户彻底解决节点缺失问题,恢复工作流正常运行。

weixin_29290947的博客 437

QtEmbedded软键盘输入法实战(附例子)

本站所有文章由本站和原作者保留一切权力,仅在保留本版权信息、原文链接、原文作者的情况下允许转载,转载请勿删改原文内容, 并不得用于商业用途。 谢谢合作。 原文链接:http://www.cuteqt.com/blog/?p=889 (本文基于qte4.5, 其他版本酌情阅读,呵呵)最近看到很多人讨论关于QtEmbedded软键盘的问题, 问的最多的主要集中在以下方面:1、怎

weizi422的专栏 2664

RocketMq面板访问异常 com.alibaba.fastjson.JSONException: not close json text, token : string

rocketmq JSONException: not close json text, token : string 问题解决

qq_21067307的博客 5573

【异常】安装hermes-agent时Git克隆大仓库报错:error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CAN

摘要:本文分析了Ubuntu服务器执行Git递归克隆时出现的网络传输中断错误(HTTP/2流异常关闭、数据截断)。主要原因是网络限制、协议兼容问题和缓冲区不足。提供了四种解决方案:1)扩大Git HTTP缓冲区;2)切换为HTTP/1.1协议;3)采用浅克隆+分步拉取子模块;4)网络优化措施。重点推荐浅克隆分步拉取作为最有效方案,所有方法无需重启即可生效,可快速解决大仓库递归克隆失败问题。

奶爸的编程之路,也就一周冷个三天 670

Qt软键盘程序源码分享

Qt软键盘程序源码分享 去发现同类优质开源项目:https://gitcode.com/ 简介 本文档提供了Qt环境下使用谷歌拼音制作的软键盘程序的全部源码。该程序旨在为Qt应用程序提供一种便捷的中文输入方式,同时支持手写输入功能。 特性 Qt版本兼容:支持Qt 5.0及以上版本。 中文输入:支持中文输入,方便开发者在Qt应用程序中实现本地化。 手写输入:提供手写输入功能,满足不同用户的需求。 ...

gitblog_06717的博客 220

USB_TYPE-C 母座电路设计

本文详细介绍了USB Type-C接口(C2765186)的电路设计要点,重点解析了电源、识别和数据三部分的关键连接方案。电源部分需并联VBUS和GND引脚并加宽走线以承载3A电流;识别部分必须为CC1/CC2引脚配置5.1kΩ±1%精度的下拉电阻,这是触发PD充电的核心条件;数据部分通过短接正反插引脚实现盲插功能。文档还提供了完整的引脚对照表,并强调PCB布局需注意ESD防护、差分走线阻抗控制等要点,为Type-C接口设计提供了实用指导。

在读研究生,FPGA电路设计与功能开发。 586

android获得键盘高度,Android获取软键盘高度

在 Android 里我们是无法直接获取软键盘高度的,但是在某些场景下,我们又需要获取软键盘的高度。我们可以使用 ViewTreeObserver.OnGlobalLayoutListener来监听窗口大小的变化,当软键盘弹出时,窗口高度会变小,使用原始窗口高度减去当前窗口高度,就可以得出软键盘的高度了。//记录原始窗口高度private int mWindowHeight = 0;private...

weixin_32591379的博客 3791

【知识分享】IBIS 建模指南 03

本文介绍了差分缓冲器的数据提取方法,重点分析了差分系统与单端系统的核心差异。文章详细阐述了差分接收机和驱动器的结构特点、工作原理及建模方法,指出全差分结构具有优异的电源噪声抑制能力。针对IBIS建模规范,作者提出了三维I-V曲面数据提取技术,并介绍了共模/差模电流分离、片上端接处理以及V-T表生成的解决方案。文章还探讨了差分电容(C_diff)的测量方法和数据简化策略,为复杂差分缓冲器的精确建模提供了系统化的技术路径。

一只豌豆象的博客 1282

在鸿蒙中使用AVPlayer完成视频的播放【坚果派】

播放的全流程包含:创建AVPlayer,设置播放资源和窗口,设置播放参数(音量/倍速/缩放模式),播放控制(播放/暂停/跳转/停止),重置,销毁资源。5.准备播放:调用prepare(),AVPlayer进入prepared状态,此时可以获取duration,设置缩放模式、音量等。8.退出播放:调用release()销毁实例,AVPlayer进入released状态,退出播放。6.视频播控:播放play(),暂停pause(),跳转seek(),停止stop() 等操作。今天我们来看一下视频如何正常播放。

坚果的博客 4057

易维触摸屏全能输入系统

同时支持触摸屏手写输入与虚拟软键盘输入的触摸屏输入法系统。 主要功能介绍   在触摸屏软件设计等一些没有鼠标、键盘的情况下进行资料输入或防止木马盗取输入信息。程序提供与各类其它程序的接口,可集成到需要的程序中。   MyTouch易维全能输入系统包括MyTouch易维软键盘与MyTouch易维手写输入系统的两个软件的所有功能。   界面美观,方便,易用。默认两种风格的界面,适应

触摸屏手写输入法 1795

RH850从0搭建Autosar开发环境【7】- Davinci Configurator之CanTp模块配置详解(上)

RH850从0搭建Autosar开发环境【7】- Davinci Configurator之CanTp模块配置详解(上)

weixin_42412049的博客 2297

wince手写输入法以及软键盘拼音输入法的问题

wince手写输入法以及软键盘拼音输入法的问题

qq_44884287的博客 619

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

popupwindow 中 EditText与软键盘的问题与探索

遇到一个问题, 情况是这样的: 一个Activity,上面只有一个录音按钮。 一个popupWindow,点击录音按钮,发出命令,弹出popupwindow。 popwindow里面有一个EditText,点击文本框,就要弹出软键盘,进行手写输入。点击喇叭,就可以切换到语音输入。从手写输入到语音录入切换的时候不能 关闭popupwindow,否则前面输入的内容就没了。 现在有一个矛盾:

我的专栏 5286

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

android 获取输入法高度,Android获取软键盘高度

在 Android 里我们是无法直接获取软键盘高度的,但是在某些场景下,我们又需要获取软键盘的高度。我们可以使用 ViewTreeObserver.OnGlobalLayoutListener来监听窗口大小的变化,当软键盘弹出时,窗口高度会变小,使用原始窗口高度减去当前窗口高度,就可以得出软键盘的高度了。//记录原始窗口高度private int mWindowHeight = 0;private...

weixin_31067223的博客 904
上一篇: 滑动到尽头时去掉阴影效果
下一篇: list中按钮点击事件在activity中处理
Yogurt丶
博客等级 码龄11年 36粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值