当前位置:网站首页>如何通过CMake为QML创建插件
如何通过CMake为QML创建插件
2022-07-20 03:02:00 【v俊逸】
由于比较习惯使用CMake,所以在添加QML插件时遇到了一点问题,在寻找问题的过程中发现这个博客写的不错,为了防止失联,所以将他的文章转载了过来,原文链接
Creating C++ plugins for QML with CMake
Jul 29, 2021
How to create C++ plugins for QML with CMake
Why this post?
So far, Qt Creator allows you to create a new C++ plugin project for QML, but with qmake. This post will show you how to do it with CMake.
I recommend reading the following links for more details:
Starting
In:
- Welcome - Projects - New or File Menu - New File or Project
- Choose Library, C++ Library
- Choose where the project will be created and project name: UserRegister
- In Define Build System
- Build System: CMake
- In Define Project Details
- Type: Shared Library
- Class name: UserRegisterPlugin
- Header file: userregister_plugin.h
- Source file: userregister_plugin.cpp
- Qt module: Core
- Kit Selection
- Choose Qt version
Qt Creator creates a very basic project. We’ll do some customizations.
Remove the UserRegister_global.h
file
In CMakeLists.txt, it looked like this:
cmake_minimum_required(VERSION 3.14)
project(Register VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Quick Qml REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick QuickControls2 REQUIRED)
set(PROJECT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/userregister_plugin.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/userregister_plugin.h
${CMAKE_CURRENT_SOURCE_DIR}/src/register.h
${CMAKE_CURRENT_SOURCE_DIR}/src/register.cpp
${CMAKE_CURRENT_SOURCE_DIR}/resources/qml/qmldir
)
add_library(${PROJECT_NAME}
SHARED
${PROJECT_SOURCES}
)
target_compile_definitions(${PROJECT_NAME}
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>
)
target_link_libraries(${PROJECT_NAME}
PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Quick
Qt${QT_VERSION_MAJOR}::QuickControls2
Qt${QT_VERSION_MAJOR}::Qml
)
set(PLUGIN_PATH ${QT_DIR}/../../../qml/User/${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME} DESTINATION ${PLUGIN_PATH})
install(FILES resources/qml/qmldir DESTINATION ${PLUGIN_PATH})
Note the structure of the files and the
qmldir
file created.
Contents of qmldir file:
module User.Register
plugin Register
In the class created by Qt Creator, in my case MyPlugin, leave it as:
File: userregister_plugin.h
#pragma once
#include <QQmlExtensionPlugin>
class UserRegisterPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
void registerTypes(const char* uri) override;
};
File: userregister_plugin.cpp
#include "userregister_plugin.h"
void UserRegisterPlugin::registerTypes(const char* /*uri*/)
{
}
This is the basic structure of the files. But the plugin won’t be recognized yet because it doesn’t have any modules registered.
Create a class called Register
File: register.h
#pragma once
#include <QObject>
#include <QString>
class Register : public QObject
{
Q_OBJECT
Q_PROPERTY(QString firstName READ getFirstName WRITE setFirstName NOTIFY firstNameChanged)
Q_PROPERTY(QString lastName READ getLastName WRITE setLastName NOTIFY lastNameChanged)
Q_PROPERTY(QString nickname READ getNickname WRITE setNickname NOTIFY nicknameChanged)
public:
explicit Register(QObject* parent = nullptr);
const QString& getFirstName() const;
void setFirstName(const QString& newFirstName);
const QString& getLastName() const;
void setLastName(const QString& newLastName);
const QString& getNickname() const;
void setNickname(const QString& newNickname);
signals:
void firstNameChanged();
void lastNameChanged();
void nicknameChanged();
private:
QString m_firstName;
QString m_lastName;
QString m_nickname;
};
File: register.cpp
#include "register.h"
Register::Register(QObject* parent) : QObject(parent) { }
const QString& Register::getFirstName() const { return m_firstName; }
void Register::setFirstName(const QString& newFirstName)
{
if (m_firstName == newFirstName)
return;
m_firstName = newFirstName;
emit firstNameChanged();
}
const QString& Register::getLastName() const { return m_lastName; }
void Register::setLastName(const QString& newLastName)
{
if (m_lastName == newLastName)
return;
m_lastName = newLastName;
emit lastNameChanged();
}
const QString& Register::getNickname() const { return m_nickname; }
void Register::setNickname(const QString& newNickname)
{
if (m_nickname == newNickname)
return;
m_nickname = newNickname;
emit nicknameChanged();
}
To register the class as a component for QML
File: userregister_plugin.cpp
#include "userregister_plugin.h"
#include "register.h"
#include <QtQml>
void UserRegisterPlugin::registerTypes(const char* uri)
{
qmlRegisterType<Register>(uri, 1, 0, "Register");
}
In Projects
in the kit you are using -> build
-> Build Steps
, set the target install
. Build the project.
To test it, create a qml file with the content below and let’s run it with qmlscene
File: /tmp/UserRegisterApp.qml
import QtQuick
import QtQuick.Controls
import User.Register
ApplicationWindow {
id: window
height: 640
width: 480
visible: true
title: qsTr("Test User Register")
Register {
id: register
onFirstNameChanged: console.log("First name:", firstName)
onLastNameChanged: console.log("Last name:", lastName)
onNicknameChanged: console.log("Nickname:", nickname)
}
Column {
anchors.centerIn: parent
spacing: 10
TextField {
id: fieldFirstName
placeholderText: qsTr("First Name")
}
TextField {
id: fieldLastName
placeholderText: qsTr("Last Name")
}
TextField {
id: fieldNickname
placeholderText: qsTr("Nickname")
}
Button {
id: buttonRegister
text: qsTr("Register")
onClicked: {
register.firstName = fieldFirstName.text
register.lastName = fieldLastName.text
register.nickname = fieldNickname.text
fieldFirstName.text = ""
fieldLastName.text = ""
fieldNickname.text = ""
}
}
}
}
Running
/path/to/Qt/bin/qmlscene /tmp/UserRegisterApp.qml
Ready! Now you can migrate your QML plugins to CMake!
边栏推荐
- 【服务器数据恢复】某品牌ProLiant服务器raid瘫痪数据库文件损坏的数据恢复
- Unity shader implements the image with rounded corners and edge borders
- C语言实现并查集
- Difference between filter and interceptor
- 开发者分享|『啃书吧:深度学习与MindSpore实践』第二期 回归分析
- 数据工程系列精讲(第五讲): Data-centric AI之数据集质量
- DOM系列之节点操作
- [LeetCode]剑指 Offer 57. 和为s的两个数字
- Matlab summary of differential equation solving methods
- clion创建第一个C项目
猜你喜欢
NetFlow and SNMP are two different network monitoring methods
【5GC】5G PDU会话以及会话类型
JASMINER X4在海外爆红,获众多知名博主点赞认可
Unity shader implements the image with rounded corners and edge borders
MySQL 索引
乐扣乐扣澄清欠税事件:不存在欠税,将一如既往合规经营,植根中国
【AD学习记录】为什么原理图和PCB都在同一个文件夹下面了却,无法生成PCB?
华为员工爆料,这个岗位要开始大量招人了!!!
编译+链接和预处理
Harbor 高可用集群设计及部署(离线安装方式、含视频)
随机推荐
Fragment 这些 API 已废弃,你还在使用吗?
Mail push platform - Foreign Trade Promotion
美国议员倡导打击加密挖矿 敲响加密警钟?减少碳足迹才能发挥真正价值
The common loss function in the field of hyper Division
"Weilai Cup" 2022 Niuke summer multi school training camp 1 I chiitoitsu (probability DP)
开发者分享|『啃书吧:深度学习与MindSpore实践』第二期 回归分析
通过例子学C标准库<assert.h>
[R language text mining]: emotion analysis and word cloud mapping
LeetCode. 302 weekly games___ 01_ 6120. How many pairs can an array form__ Simple hash
【upload靶场12-16】截断、图片马
Top priority of dry goods: common indicators and terms in data analysis!
Go daily Gore
【AD学习记录】为什么原理图和PCB都在同一个文件夹下面了却,无法生成PCB?
乐扣乐扣澄清欠税事件:不存在欠税,将一如既往合规经营,植根中国
[LeetCode]剑指 Offer 53 - II. 0~n-1中缺失的数字
华为员工爆料,这个岗位要开始大量招人了!!!
MindSpore开源周年狂欢,量子机器学习与深度分子模拟等巨量新特性来袭!
.Net Core快速开发平台,强大工作流引擎,多系统快速配置
单体 or 微服务?你以为是架构权衡?其实是认知负载!
【upload靶场1-11】基础关卡:特点、分析、利用