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

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


前言

需要在嵌入式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_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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 virtualkeyboard

CONFIG += 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.0

SOURCES += \
        main.cpp

RESOURCES += 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: window
    visible: true
    width: 720
    height: 680
    title: "Hello World"

    flags: Qt.Window | Qt.FramelessWindowHint

        Column {
            spacing: 10
            anchors.centerIn: parent
            TextField {
                id:textUser
                placeholderText: qsTr("User name")
            }
        }

    InputPanel {
        id: inputPanel
        z: 99
        x: 0
        y: window.height
        width: window.width

        Component.onCompleted: {
                    VirtualKeyboardSettings.activeLocales = ["en_GB","zh_CN"]
                    VirtualKeyboardSettings.locale = "en_GB"
                }

        states: State {
            name: "visible"
            when: inputPanel.active
            PropertyChanges {
                target: inputPanel
                y: window.height - inputPanel.height
            }
        }
        transitions: Transition {
            from: ""
            to: "visible"
            reversible: true
            ParallelAnimation {
                NumberAnimation {
                    properties: "y"
                    duration: 250
                    easing.type: Easing.InOutQuad
                }
            }
        }
    }



        TextField {
            anchors.top: parent.top
            anchors.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 gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

QT += quick virtualkeyboard

QT += 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.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    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_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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: root
    Item {
        id: appContainer
        anchors.left: parent.left
        anchors.top: parent.top
        anchors.right: parent.right
        anchors.bottom: inputPanel.top
    }

    InputPanel {
        id: inputPanel
        y: Qt.inputMethod.visible ? parent.height - inputPanel.height : parent.height
        anchors.left: parent.left
        anchors.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虚拟键盘的调试过程。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值