提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
一、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虚拟键盘的调试过程。