C++代码扩展QtQuick 控件 TextArea-QuickTextArea 的功能及使用

5 篇文章 0 订阅

Qml (QtQuick)控件和 Widgets 控件都可以通过类继承 扩展其功能。

下面以扩展qml的TextArea 功能为例,其实现类QQuickTextArea 。

 

1.添加 QquickTextArea QQuickTextControl头文件

1.1通过搜索可知俩个类的头文件分别是:

Qt5.9.8\5.9.8\mingw53_32\include\QtQuickTemplates2\5.9.8\QtQuickTemplates2\private\ qquicktextarea_p.h

Qt5.9.8\5.9.8\mingw53_32\include\QtQuick\5.9.8\QtQuick\private\qquicktextcontrol_p.h

所以如果想要在源码中引用 上面的private头文件

.pro文件中需要添加

QT_PRIVATE += quick-private

QT_PRIVATE += quicktemplates2-private

 

1.1.1 qquicktextarea 在QtQuickTemplates2 模块还可以从

Qt5.9.8\5.9.8\mingw53_32\qml\QtQuick\Controls.2\TextArea.qml

中看出:

…
import QtQuick.Templates 2.2 as T
T.TextArea {
…

1.2 引用头文件

#include <QtQuickTemplates2/private/qquicktextarea_p.h>
#include <QtQuickTemplates2/private/qquicktextarea_p_p.h>
#include <QtQuick/private/qquicktextcontrol_p.h>

2.源码分析

2.1d指针

#include <QtQuickTemplates2/private/qquicktextarea_p.h>
#include <QtQuickTemplates2/private/qquicktextarea_p_p.h>

class QuickTextAreaEx : public QQuickTextArea{
…
private:
Q_DECLARE_PRIVATE(QQuickTextArea)//使用 QQuickTextArea 的d指针
…
}

使用d指针是因为用到的 QQuickTextAreaPrivate *d_ptr 中的control指针QquickTextControl,比如获取游标

QTextCursor cursor = d->control->textCursor();

2.2为TextArea 增加一种只能输入十六进制字符(Hex)的状态。

原理是文档的每次改变都判断下增加的内容是否是Hex字符,否则删除。

在构造函数中添加

connect(this->textDocument()->textDocument(),&QTextDocument::contentsChange,this,&QuickTextAreaEx::contentsChange);

并实现void contentsChange(int from, int charsRemoved, int charsAdded);函数

 

3.解决问题

3.1. undefined reference to QQuickTextControl::textCursor

参考:

https://forum.qt.io/topic/82772/undefined-reference-to-qquicktextcontrol-textcursor-const

原因是因为QQuickTextControl的声明如下

class Q_AUTOTEST_EXPORT QQuickTextControl : public QInputControl{…}

而Q_AUTOTEST_EXPORT定义为

在调用和源码编译时都如上图,没有导入和导出动态库

解决方法是 修改qquicktextcontrol_p.h和qquicktextcontrol_p_p.h文件

#include <private/qtquickglobal_p.h>
class Q_QUICK_PRIVATE_EXPORT QQuickTextControl : public QInputControl{…}
#include <private/qtquickglobal_p.h>
class Q_QUICK_PRIVATE_EXPORT QQuickTextControlPrivate : public QobjectPrivate{…}

然后重新编译 qtdeclarative模块生成 Qt5Quick动态库,替换对应编译环境的动态库文件

qtdeclarative下载地址 http://download.qt.io/archive/qt/5.9/5.9.8/submodules/

MinGW:

Qt5Quick.dll Qt5Quick.a Qt5Quickd.dll Qt5Quickd.a

MSVC:

armeabi_v7a:

libQt5Quick.so (libQt5Quick.a 不需要)

 

3.1.1 armeabi_v7a 环境 qtdeclarative模块的编译

MinGW和MSVC 环境的编译,可以直接用Qt Creator打开pro文件编译,armeabi_v7a 环境在Qt Creator中编译则会报错。

我的做法是在 Cygwin 模拟终端中编译(在windows cmd终端应该也可以)。

环境变量设置和编译命令是从 构建设置获得的。

3.1.1.1环境变量:设置

export ANDROID_HOME=E:/ProgramFiles/Tools/Android/android-sdk
export ANDROID_NDK_HOST=windows-x86_64
export ANDROID_NDK_PLATFORM=android-16
export ANDROID_NDK_ROOT=D:/ProgramFiles/android-ndk-r17c
export ANDROID_SDK_ROOT=E:/ProgramFiles/Tools/Android/android-sdk


export PATH=${PATH/mingw53_32/android_armv7}
export PATH=/cygdrive/d/ProgramFiles/android-ndk-r17c/prebuilt/windows-x86_64/bin:/cygdrive/d/ProgramFiles/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64/bin:/cygdrive/d/ProgramFiles/Qt5.9.8/5.9.8/android_armv7/bin/:$PATH

3.1.1.2 进入 qtdeclarative-opensource-src-5.9.8 目录 执行:

qmake qtquickcontrols.pro -spec android-g++ "CONFIG+=debug" "CONFIG+=qml_debug" && make.exe qmake_all

然后再执行:

make -j4

3.1.1.3 examples 子模块可以删除去掉。编译过程中虽然仍有报错,但最终会生成libQt5Quick.so

3.1.2虽然 能够成功编译出Qt5Quick 动态库,但生成的文件比原有的文件大很多,不知道哪里设置的原因。

 

3.2 正确的在qml中使用扩展的 TextAreaEx

3.2.1 一般在qml中使用使用 C++类,需要在main 函数里注册:

QQmlApplicationEngine engine;
qmlRegisterType< QuickTextAreaEx >("qtproject.extern", 1, 1, "TextEditEx");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

在qml中添加

import qtproject.extern 1.1;

即可使用 TextEditEx

3.2.2 只注册QuickTextAreaEx无法使用QquickTextEdit,和QQuickTextArea 中被 “REVISION n”修饰的Q_PROPERTY 属性。比如 QquickTextEdit 一些属性:

Q_PROPERTY(qreal padding READ padding WRITE setPadding RESET resetPadding NOTIFY paddingChanged REVISION 6)
Q_PROPERTY(qreal topPadding READ topPadding WRITE setTopPadding RESET resetTopPadding NOTIFY topPaddingChanged REVISION 6)
Q_PROPERTY(qreal leftPadding READ leftPadding WRITE setLeftPadding RESET resetLeftPadding NOTIFY leftPaddingChanged REVISION 6)
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)

Q_SIGNALS:
Q_REVISION(6) void editingFinished();
Q_REVISION(6) void paddingChanged();
Q_REVISION(6) void topPaddingChanged();
Q_REVISION(6) void leftPaddingChanged();
Q_REVISION(6) void rightPaddingChanged();
Q_REVISION(6) void bottomPaddingChanged();

运行时会报错"TextAreaEx.leftPadding" is not available in qtproject.extern 1.1.”

 

解决方法是将 注册方法改为下面这样:

qmlRegisterType<QQuickTextEdit,7>("qtproject.extern", 1, 1, "QTextEdit");
qmlRegisterType<QQuickTextArea,7>("qtproject.extern", 1, 1, "QTextArea");
qmlRegisterType<QuickTextAreaEx,7>("qtproject.extern", 1, 1, "TextAreaEx");

qmlRegisterType <**,n> 数字n 只要大于等于 “REVISION n” 中的n即可

参考:https://stackoverflow.com/questions/56699204/q-revision-meaning-in-qt-class

 

4.将QuickTextAreaEx做成qml plugin插件使用

参考https://blog.csdn.net/yizhou2010/article/details/87620776

https://blog.csdn.net/u013411873/article/details/95936614

 

4.1生成动态库

4.1.1新建插件项目:

4.1.2配置 .pro文件

.

4.1.3qmldir 内容

module QuickTextAreaEx

plugin quicktextareaexplugin

 

4.1.4 QuickTextAreaEx 类内容同3

4.1.5 修改QuickTextareaExPluginPlugin 构造函数

void QuickTextareaExPluginPlugin::registerTypes(const char *uri){
    qmlRegisterType<QuickTextAreaEx>(uri, 1, 0, "TextareaEx");
    qmlRegisterType<QQuickTextEdit,7>(uri, 1, 0, "QTextEdit");
    qmlRegisterType<QQuickTextArea,7>(uri, 1, 0, "QTextArea");
}

4.1.6 编译生成动态库插件

4.2使用 plugin 插件

4.2.1 生成 plugin.qmltypes 文件

4.2.1.1 如下图将dll 、.a、qmldir、放在 QuickTextareaEx文件夹下,

就是4.1.3 qmldir 内容“module QuickTextAreaEx

4.2.1.2 生成qmltypes文件

参考 qmltypes文件生成及作用

打开Qt 5.9.8 (MinGW 5.3.0 32-bit),

执行命令 (一定要绝对路径)

qmlplugindump -nonrelocatable QuickTextAreaEx 1.0 D:\ > D:\QuickTextAreaEx\plugin.qmltypes

 

4.3plugin插件的使用

4.3.1 .pro配置

“QML_IMPORT_PATH = $$PWD/imports/”是在编译时路径

运行时只需将 dll和 qmltypes放在对应位置即可

./ HexTextArea2.exe

./QuickTextAreaEx/qmldir

./QuickTextAreaEx/quicktextareaexplugin.dll

4.4 对于 “module QuickTextAreaEx” 需配合 https://blog.csdn.net/u013411873/article/details/95936614 理解

5.源码

https://github.com/dragonfly1208/QuickTextareaEx

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值