QT5:嵌入式linux开发板调用键盘

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录​​​​​​​

前言

一、Buildroot构建QT环境

1.1 构建环境

1.2 检查qtvirtualkeyboard库

二、测试过程

2.1 直接调用qtvirtualkeyboard

1.测试代码

2.测试效果

2.2 运行QML示例

1.测试代码

2.测试效果

2.3 Qwidget 嵌套Qml

1.测试代码

 2.测试效果

2.4 第三方Qwidget库移植

1.第三方库地址QVirtualKeyboard: Qt5虚拟键盘支持中英文,仿qt官方的virtualkeyboard模块,但使用QWidget实现。 - Gitee.com

2.移植第三方库

3.测试代码

4.测试效果 

参考博客

 总结


前言

需要在嵌入式linux开发板上使用qt进行ui界面开发,因为使用的是触摸屏,所以需要使用虚拟键盘来进行输入。且因为是新手且只熟悉c语言,所以使用的qt架构为widgt,本来是以为将Qt Designer的代码直接移植到板子上就行,但不知道为什么在板子上一直无法弹出 qtvirtualkeyboard 键盘,因此最终还是选择暂时移植第三方库来完成键盘输入功能。本文主要对这一过程进行记录,也希望熟悉qt开发的大神不吝指教。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Buildroot构建QT环境

1.1 构建环境

开发板使用buildroot来构建系统,因此使用qt的话直接在buildroot选择qt支持即可,同时这里也加入了对qtvirtualkeyboard 的支持。

先在Target packages ->Graphic libraries and applications (graphic/text)->mesa3d 中开启openGL支持,然后在QT5中选择qtvirtualkeyboard支持。

make编译、烧录后即可在板子上使用qt。

1.2 检查qtvirtualkeyboard库

在板子的usr/lib目录下有生成的一些qt库,在 /usr/lib/qt/plugins/platforminputcontexts/ 目录下可以·看到生成的 libqtvirtualkeyboardplugin.so库,证明键盘库是存在的。


二、测试过程

2.1 直接调用qtvirtualkeyboard

在板子上的环境按如上方式构建完成后,首选方法当然是直接对官方qtvirtualkeyboard进行调用,因为这是在Qt Designer测试成功过的代码。然而在实际测试中,点击QLineEdit无法弹出键盘。

1.测试代码

main.cpp

#include "mainwindow.h"#include <QApplication>
#include <QMainWindow>int main(int argc, char *argv[])
{qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

mainwindow.h 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>#include <QLineEdit>
#include <QVBoxLayout>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;QLineEdit *lineEdit;QVBoxLayout *layout;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QWidget *centralWidget = new QWidget(this);setCentralWidget(centralWidget);centralWidget->setFixedSize(600,480);lineEdit = new QLineEdit(centralWidget);lineEdit->setGeometry(30,100,600,100);lineEdit->setFocusPolicy(Qt::StrongFocus); // 确保可以接收焦点
}MainWindow::~MainWindow()
{delete ui;
}

2.测试效果

点击文本框不能弹出·键盘。 


2.2 运行QML示例

在2.1的方式失败后,由于不清楚失败原因是什么,因此在网上搜索相关的解决方式,也按照一些方式进行了尝试,包括检查qtvirtualkeyboard库是否生成,相关库在板子上的路径,在板子上设置环境变量等,然而这些方式都未能起效。又因为看到qtvirtualkeyboard主要适配于qml构架,因此便尝试直接使用qml示例代码能否在板子上弹出键盘,而最终的结果也是成功的,使用qml示例可以正常使用键盘。

在buildroot启用quick:

1.测试代码

.pro文件:

QT += quick virtualkeyboardCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cppRESOURCES += qml.qrc# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

 main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);return app.exec();
}

main.qml:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.VirtualKeyboard 2.4
import QtQuick.Controls 2.12 // 这里的x应该替换为你使用的Qt版本对应的版本号Window {id: windowvisible: truewidth: 720height: 680title: "Hello World"flags: Qt.Window | Qt.FramelessWindowHintColumn {spacing: 10anchors.centerIn: parentTextField {id:textUserplaceholderText: qsTr("User name")}}InputPanel {id: inputPanelz: 99x: 0y: window.heightwidth: window.widthComponent.onCompleted: {VirtualKeyboardSettings.activeLocales = ["en_GB","zh_CN"]VirtualKeyboardSettings.locale = "en_GB"}states: State {name: "visible"when: inputPanel.activePropertyChanges {target: inputPanely: window.height - inputPanel.height}}transitions: Transition {from: ""to: "visible"reversible: trueParallelAnimation {NumberAnimation {properties: "y"duration: 250easing.type: Easing.InOutQuad}}}}TextField {anchors.top: parent.topanchors.horizontalCenter: parent.horizontalCenter}
}

2.测试效果

 点击文本框可弹出键盘进行烧录。


2.3 Qwidget 嵌套Qml

基于2.1与2.2的测试结果,qwidget无法调出键盘,qml成功弹出键盘说明问题应该不是出在buildroot构建的qt环境上,可能在嵌入式上qwidget 本身无法支持qtvirtualkeyboard,因此之后尝试的方法就是在qwidget内嵌入qml,看能否实现基于qwidget调用·qtvirtualkeyboard。

1.测试代码

.pro文件:

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11QT += quick virtualkeyboardQT += quickwidgets# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \qml.qrc

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>#include <QPushButton>
#include <QDialog>
#include <QQuickWidget>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;QDialog *qmlDialog;QQuickWidget *qmlWidget;QPushButton* btn;
};
#endif // MAINWINDOW_H

 mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QHBoxLayout>
#include <QVBoxLayout>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QQuickWidget *qmlWidget = new QQuickWidget(this);
//           qmlWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);qmlWidget->setSource(QUrl("qrc:/main.qml"));qmlWidget->show();this->setCentralWidget(qmlWidget);}MainWindow::~MainWindow()
{delete ui;
}

main.cpp:

#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[])
{qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}

main.qml:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.VirtualKeyboard 2.4
import QtQuick.Controls 2.12 // 这里的x应该替换为你使用的Qt版本对应的版本号Item {id: rootItem {id: appContaineranchors.left: parent.leftanchors.top: parent.topanchors.right: parent.rightanchors.bottom: inputPanel.top}InputPanel {id: inputPanely: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.heightanchors.left: parent.leftanchors.right: parent.right}
//    TextField {
//            id:appcontainer
//            focus: true
//            onPressed: {
//                vkb.visible = true; //当选择输入框的时候才显示键盘//            }
//    }
}

 2.测试效果

 不知道是否是哪里的嵌入qml有问题,可以看到屏幕最顶部有键盘的图案出现,但实际效果显示也和预期不符,最终也只能放弃此方案。


2.4 第三方Qwidget库移植

在上述方案验证之后,剩下的选择就只有把qt架构整体改为quick或者找个能在qwidget运行的键盘,最终选择了网上开源的第三方库。

1.第三方库地址QVirtualKeyboard: Qt5虚拟键盘支持中英文,仿qt官方的virtualkeyboard模块,但使用QWidget实现。 - Gitee.com

2.移植第三方库

参考库作者的使用说明及其它博客完成移植

git clone 下载库到本地

git clone https://gitee.com/yynestt/QVirtualKeyboard.git

先进入pinyin文件夹执行qmake生成Makefile文件,再执行make生成拼音库,返回上层文件夹执行相同操作,最终生成需要的libQt5SoftKeyboard.so库

cd QVirtualKeyboard/pinyin/
/home/amiliya/linux/buildroot/buildroot/output/host/bin/qmake  //qmake路径
make
cd ..
/home/amiliya/linux/buildroot/buildroot/output/host/bin/qmake  //qmake路径
make

最终生成的文件 

将生成的libQt5SoftKeyboard.so库文件拷贝到板子的/usr/lib/qt/plugins/platforminputcontexts/ 目录下

cp bin/plugins/platforminputcontexts/libQt5SoftKeyboard.so  ../linux/buildroot/buildroo
t/output/target/usr/lib/qt/plugins/platforminputcontexts/

这里我复制到buildroot的output文件下,然后通过buildroot打包到板子上。 

3.测试代码

将2.1的测试代码中的库引用进行替换·:

//    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));qputenv("QT_IM_MODULE",QByteArray("Qt5Input"));

4.测试效果 

可以弹出键盘,样式也和qtvirtualkeyboard差不多,后期也可以根据需要调整一下键盘大小,因此暂时便先使用此方案。


参考博客

在ARM板上实现qt虚拟键盘 Qwidget实现 官方虚拟键盘、第三方虚拟键盘qtvirtualkeyboard //Qwidget最简单但效果不是最好_qt 虚拟键盘-CSDN博客


 总结

记录下在嵌入式linux开发板上调用qt虚拟键盘的调试过程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3266129.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Golang | Leetcode Golang题解之第274题H指数

题目&#xff1a; 题解&#xff1a; func hIndex(citations []int) int {// 答案最多只能到数组长度left,right:0,len(citations)var mid intfor left<right{// 1 防止死循环mid(leftright1)>>1cnt:0for _,v:range citations{if v>mid{cnt}}if cnt>mid{// 要找…

.h264 .h265 压缩率的直观感受

1.资源文件 https://download.csdn.net/download/twicave/89579327 上面是.264 .265和原始的YUV420文件&#xff0c;各自的大小。 2.转换工具&#xff1a; 2.1 .h264 .h265互转 可以使用ffmpeg工具&#xff1a;Builds - CODEX FFMPEG gyan.dev 命令行参数&#xff1a; …

渗透测试——prime1靶场实战演练{常用工具}端口转发

文章目录 概要信息搜集 概要 靶机地址&#xff1a;https://www.vulnhub.com/entry/prime-1,358 信息搜集 nmap 扫网段存活ip及端口 找到除了网关外的ip&#xff0c;开放了80端口&#xff0c;登上去看看 是一个网站&#xff0c;直接上科技扫一扫目录 python dirsearch.py -u …

{Spring Boot 原理篇} Spring Boot自动装配原理

SpringBootApplication 1&#xff0c;Spring Boot 应用启动&#xff0c;SpringBootApplication标注的类就是启动类&#xff0c;它去实现配置类中的Bean的自动装配 SpringBootApplication public class SpringbootRedis01Application {public static void main(String[] args)…

GRE VPN和MGRE VPN综合练习

GRE VPN和MGRE VPN综合练习 实验拓扑 实验要求 1、R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址; 2、R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方; R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方; R3与R5之间使用HDLC封装;…

【JavaScript】深入理解 `let`、`var` 和 `const`

文章目录 一、var 的声明与特点二、let 的声明与特点三、const 的声明与特点四、let、var 和 const 的对比五、实战示例六、最佳实践 在 JavaScript 中&#xff0c;变量声明是编程的基础&#xff0c;而 let、var 和 const 是三种常用的变量声明方式。本文将详细介绍这三种变量声…

做一个能和你互动玩耍的智能机器人之一

2024年被很多人称为AI元年&#xff0c;其实AI元年的叫法由来以久&#xff0c;近年来每一次AI技术的进步&#xff0c;都有很多圈内人大呼AI元年&#xff0c;但不仅一直风声不大&#xff0c;雨点也偏小&#xff0c;都是小范围交流。 得益于软硬件的进步&#xff0c;AI今年开始侵…

秋招突击——7/23——百度提前批面试准备和正式面试

文章目录 引言一面准备面试预演一1、讲一下hashcode()和equals()关系2、equals()和有什么区别3、讲一下重载和重写的区别4、讲一下深拷贝、浅拷贝的区别5、讲一下Java异常的基类&#xff0c;运行时异常举几个例子&#xff0c;什么情况下会出现&#xff1f;6、讲一下Java中线程的…

pytorch前馈神经网络--手写数字识别

前言 具体内容就是&#xff1a; 输入一个图像&#xff0c;经过神经网络后&#xff0c;识别为一个数字。从而实现图像的分类。 资源&#xff1a; https://download.csdn.net/download/fengzhongye51460/89578965 思路&#xff1a; 确定输入的图像&#xff1a;会单通道灰度的…

基于dcm4chee搭建的PACS系统讲解(三)服务端使用Rest API获取study等数据

文章目录 DICOMWeb Support模块主要数据结构ER查询信息基本信息metadata信息统计信息 实践查询API及参数解析API返回的json数组定义VRObjectNodeObjectMapper解析显示指定tag并解析 后记 前期预研的PACS系统&#xff0c;近期要在项目中上线了。因为PACS系统采用无权限认证&…

【初阶数据结构】8.二叉树(3)

文章目录 4.实现链式结构二叉树4.1 前中后序遍历4.1.1 遍历规则4.1.2 代码实现 4.2 结点个数以及高度等4.3 层序遍历4.4 判断是否为完全二叉树4.5层序遍历和判断是否为完全二叉树完整代码 4.实现链式结构二叉树 用链表来表示一棵二叉树&#xff0c;即用链来指示元素的逻辑关系…

减轻幻觉新SOTA,7B模型自迭代训练效果超越GPT-4,上海AI lab发布

LLMs在回答各种复杂问题时&#xff0c;有时会“胡言乱语”&#xff0c;产生所谓的幻觉。解决这一问题的初始步骤就是创建高质量幻觉数据集训练模型以帮助检测、缓解幻觉。 但现有的幻觉标注数据集&#xff0c;因为领域窄、数量少&#xff0c;加上制作成本高、标注人员水平不一…

php反序列化--前置知识

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

文件共享功能无法使用提示错误代码0x80004005【笔记】

环境情况&#xff1a; 其他电脑可以正常访问共享端&#xff0c;但有一台电脑访问提示错误代码0x80004005。 处理检查&#xff1a; 搜索里输入“启用或关闭Windows功能”按回车键&#xff0c;在“启用或关闭Windows功能”里将“SMB 1.0/CIFS文件共享支持”勾选后&#xff08;故…

不同行情下算法的具体使用!

上一篇我们说到了不同公司算法交易的区分&#xff0c;有朋友提出了不同的行情下的算法交易应该怎么使用&#xff0c;小编今天就带大家了解下&#xff01;当然具体实际状况百出&#xff0c;这种可以实际为准&#xff08;韭菜修养全拼实际探讨交流&#xff09;&#xff01; 我们在…

qt做的分页控件

介绍 qt做的分页控件 如何使用 创建 Pagination必须基于一个QWidget创建&#xff0c;否则会引发错误。 Pagination* pa new Pagination(QWidget*);设置总页数 Pagination需要设置一个总的页数&#xff0c;来初始化页码。 pa->SetTotalItem(count);设置可选的每页数量…

Java 每日一题: for 与 foreach 的区别 ?

for 循环&#xff1a;是最基本的循环结构&#xff0c;可以通过初始化语句、循环条件和迭代语句来控制循环的执行。 foreach 循环&#xff08;也称为增强型 for 循环&#xff09;&#xff1a;用于遍历集合或数组中的元素&#xff0c;简化了遍历过程&#xff0c;没有显式地控制索…

[STM32]HAL库实现自己的BootLoader-BootLoader与OTA-STM32CUBEMX

目录 一、前言 二、BootLoader 三、BootLoader的实现 四、APP程序 五、效果展示 六、拓展 一、前言 听到BootLoader大家一定很熟悉&#xff0c;在很多常见的系统中都会存在BootLoader。本文将介绍BootLoader的含义和简易实现&#xff0c;建议大家学习前掌握些原理基础。 …

全链路追踪 性能监控,GO 应用可观测全面升级

作者&#xff1a;古琦 01 介绍 随着 Kubernetes 和容器化技术的普及&#xff0c;Go 语言不仅在云原生基础组件领域广泛应用&#xff0c;也在各类业务场景中占据了重要地位。如今&#xff0c;越来越多的新兴业务选择 Golang 作为首选编程语言。得益于丰富的 RPC 框架&#xff…

编程类精品GPTs

文章目录 编程类精品GPTs前言种类ChatGPT - GrimoireProfessional-coder-auto-programming 总结 编程类精品GPTs 前言 代码类的AI, 主要看以下要点: 面对含糊不清的需求是否能引导出完整的需求面对完整的需求是否能分步编写代码完成需求编写的代码是否具有可读性和可扩展性 …