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://www.mzph.cn/diannao/50154.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm2024 专业版激活设置中文

PyCharm2024 专业版激活设置中文 官网下载最新版&#xff1a;https://www.jetbrains.com/zh-cn/pycharm/download 「hack-jet激活idea家族.zip」链接&#xff1a;https://pan.quark.cn/s/4929a884d8fe 激活步骤&#xff1a; 官网下载安装PyCharm &#xff1b;测试使用的202…

细说MCU用DMA改变DAC输出信号频率和改善输出波形质量的方法

目录 一、参考硬件 二、修改定时器参数改变输出波形频率 三、改善波形质量 四、代码修改 五、查看结果 一、参考硬件 本项目的软件硬件工程参考作者的其他文章&#xff1a;细说MCU用DMA实现DAC输出的方法-CSDN博客 https://wenchm.blog.csdn.net/article/details/14065…

VUE3——001(02)、开发环境配置(vs code与git和gitee)

一、配置 Git 路径 系统装好&#xff0c;差不多的该安装的都安装了&#xff0c;剩下就是不用安装配置一下系统变量就行了&#xff08;当然&#xff0c;不想配变量重新安装一遍也是可以的&#xff09;。 记得配好了 git 的变量&#xff0c;在 vs code 中总是刷不出来&#xff0c…

一篇文章讲清楚html css js三件套之html

目录 HTML HTML发展史 HTML概念和语法 常见的HTML标签: HTML 调试 错误信息分析 HTML文档结构 HTML5的新特性 结论 HTML HTML是网页的基础&#xff0c;它是一种标记语言&#xff0c;用于定义网页的结构和内容。HTML标签告诉浏览器如何显示网页元素&#xff0c;例如段落…

【轨物方案】成套开关柜在线监测物联网解决方案

随着物联网技术的发展&#xff0c;电力设备状态监测技术也得到了迅速发展。传统的电力成套开关柜设备状态监测方法主要采用人工巡检和定期维护的方式&#xff0c;这种方法不仅效率低下&#xff0c;而且难以保证设备的实时性和安全性。因此&#xff0c;基于物联网技术的成套开关…

photoshop学习笔记——选区

选区工具快捷键&#xff1a;M shift M 切换 矩形/椭圆选区工具 基本用法 选区框选出的地方被激活&#xff08;其后进行的操作&#xff0c;仅在选区中生效&#xff09; 选区工具选择后&#xff08;以矩形选区为例&#xff09; 按下鼠标左键拖动&#xff0c;画出一块矩形区…

最新篇 接口测试工具Postman 企业常规面试题出炉~(附答案)

面试题目录 说下你对Postman的了解&#xff1f; Postman你在工作中使用流程是什么样的&#xff1f; Postman 你使用了哪些功能&#xff1f; Postman 里面如何管理测试环境&#xff1f; Postman如何设置关联&#xff1f; postman参数化有哪几种方式&#xff1f; 在postman中&…

Android平台RTSP|RTMP直播播放器技术接入说明

技术背景 大牛直播SDK自2015年发布RTSP、RTMP直播播放模块&#xff0c;迭代从未停止&#xff0c;SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述&#xff0c;全自研内核&#xff0c;行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台…

浏览器【WebKit内核】渲染原理【QUESTION-1】

浏览器【WebKit内核】渲染原理【QUESTION】 1.浏览器输入一个网址&#xff08;域名之后&#xff09;,浏览器会呈现一个新的页面&#xff0c;中间的过程是怎么实现的&#xff1f; 输入一个网址之后&#xff0c;首先DNS服务器会解析这个域名&#xff0c;将这个域名解析成IP地址&…

.NET 相关概念

.NET 和 .NET SDK .NET 介绍 .NET 是一个由 Microsoft 开发和维护的广泛用于构建各种类型应用程序的开发框架。它是一个跨平台、跨语言的开发平台&#xff0c;提供了丰富的类库、API和开发工具&#xff0c;支持开发者使用多种编程语言&#xff08;如C#、VB.NET、F#等&#xf…

09 算术运算符

① 运算符除了用于算数加法以外&#xff0c;还可以用于列表、元组、字符串的连接&#xff0c;但不支持不同类型的对象之间的相加或连接。 print([1, 2, 3] [4, 5, 6]) # 连接两个列表 print((1, 2, 3) (4,)) # 连接两个元组 print(hello 123) # 连接字符串 print(Fa…

开发桌面程序-Electron入门

Electron是什么 来自官网的介绍 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。 总…

与Bug较量:Codigger之软件项目体检Software Project HealthCheck来帮忙

在软件工程师的世界里&#xff0c;与 Java 小程序中的 Bug 作战是一场永不停歇的战役。每一个隐藏在代码深处的 Bug 都像是一个狡猾的敌人&#xff0c;时刻准备着给我们的项目带来麻烦。 最近&#xff0c;我就陷入了这样一场与 Java 小程序 Bug 的激烈较量中。这个小程序原本应…

wget下载github文件得到html文件

从github/gitee下载源文件&#xff0c;本来是22M下载下来只有11k 原因&#xff1a; Github会提供html页面&#xff0c;包括指定的文件、上下文与相关操作。通过wget或者curl下载时&#xff0c;会下载该页面 解决方式&#xff1a; github点击Code一栏的raw按钮&#xff0c;获得源…

【论文复现】Vision Transformer(ViT)

1. Transformer结构 1.1 编码器和解码器 翻译这个过程需要中间体。也就是说&#xff0c;编码&#xff0c;解码之间需要一个中介&#xff0c;英文先编码成一个意思&#xff0c;再解码成中文。 那么查字典这个过程就是编码和解码的体现。首先我们的大脑会把它编码&#xff0c;编…

遍历dom元素下面的子元素的方法,vue中原始标签的ref得到是该元素的dom及下面包含的子dom,与组件ref是引用不同

研究到这个的目的来源是 想用div 遍历方式 替代之前的table tr td 那种框选功能&#xff0c;觉得div灵活&#xff0c;可以随便在外面套层&#xff0c;td与tr之间就不能加div加了布局就乱&#xff0c;然后使用之前的原理&#xff08; const cellList tableIdR.value.querySelec…

【反转链表 II】python刷题记录

印象中&#xff0c;这是遍历r2了&#xff0c;还好没放弃。 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def reverseBetween(self, head: Optional…

了解Selenium中的WebElement

Selenium中到处都使用WebElement来执行各种操作。什么是WebElement&#xff1f;这篇文章将详细讨论WebElement。 Selenium中的WebElement是一个表示网站HTML元素的Java接口。HTML元素包含一个开始标记和一个结束标记&#xff0c;内容位于这两个标记之间。 HTML元素的重命名 …

SCADA系统易用性的重要性

对于中小企业而言&#xff0c;SCADA系统的易用性至关重要&#xff0c;因为它直接影响到系统的实施效率、员工的接受程度和培训成本。一个易用的SCADA系统可以减少员工对新技术的学习曲线&#xff0c;加快系统的部署速度&#xff0c;并降低长期的维护成本。此外&#xff0c;易用…

Parameter index out of range (2 > number of parameters, which is 1【已解决】

文章目录 1、SysLogMapper.xml添加注释导致的2、解决方法3、总结 1、SysLogMapper.xml添加注释导致的 <!--定义一个查询方法&#xff0c;用于获取日志列表--><!--方法ID为getLogList&#xff0c;返回类型com.main.server.api.model.SysLogModel,参数类型为com.main.se…