Electron qt开发教程
模块安装打包
npm install -g electron-forge
electron-forge init my-project --template=vue
npm start //进入目录启动
//打包成一个目录到out目录下,注意这种打包一般用于调试,并不是用于分发
npm run package
//打出真正的分发包,放在out\make目录下
npm run makenpx @electron-forge/cli@latest import
npx create-electron-app my-appnpm install mousetrap //快捷键绑定库
npm install worker_threads //工作线程模块
npm install worker-loader //
npm init //C++项目目录下初始化项目
npm install --global --production windows-build-tools
快速体验
npm install -g electron-prebuilt
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install && npm startcnpm install electron-packager -g
"scripts": {"package":"electron-packager . HelloWorld --platform=win32 --arch=x64 --icon=computer.ico --out=./out --asar --app-version=0.0.1 --overwrite --ignore=node_modules"
}
npm run package
@python "%~dp0gyp_main.py" %*
JS调用C++
#include <node.h>
#include <v8.h>using namespace v8;// 传入了两个参数,args[0] 字符串,args[1] 回调函数
void hello(const FunctionCallbackInfo<Value>& args) {// 使用 HandleScope 来管理生命周期Isolate* isolate = Isolate::GetCurrent();HandleScope scope(isolate);// 判断参数格式和格式if (args.Length() < 2 || !args[0]->IsString()) {isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments")));return;}// callback, 使用Cast方法来转换Local<Function> callback = Local<Function>::Cast(args[1]);Local<Value> argv[1] = {// 拼接StringString::Concat(Local<String>::Cast(args[0]), String::NewFromUtf8(isolate, " world"))};// 调用回调, 参数: 当前上下文,参数个数,参数列表callback->Call(isolate->GetCurrentContext()->Global(), 1, argv);
}// 相当于在 exports 对象中添加 { hello: hello }
void init(Local<Object> exports) {NODE_SET_METHOD(exports, "hello", hello);
}// 将 export 对象暴露出去
// 原型 `NODE_MODULE(module_name, Initialize)`
NODE_MODULE(test, init);//方法暴露
void Method(const FunctionCallbackInfo<Value>& args) {Isolate* isolate = args.GetIsolate();args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world").ToLocalChecked());
}void Initialize(Local<Object> exports) {NODE_SET_METHOD(exports, "hello", Method);
}NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
extern "C" NODE_MODULE_EXPORT void
NODE_MODULE_INITIALIZER(Local<Object> exports,Local<Value> module,Local<Context> context) {/* Perform addon initialization steps here. */
}int main(int argc, char* argv[]) {// Create a stack-allocated handle scope. HandleScope handle_scope;// Create a new context. Handle<Context> context = Context::New();// Enter the created context for compiling and // running the hello world script.Context::Scope context_scope(context);// Create a string containing the JavaScript source code. Handle<String> source = String::New("'Hello' + ', World!'");// Compile the source code. Handle<Script> script = Script::Compile(source);// Run the script to get the result. Handle<Value> result = script->Run();// Convert the result to an ASCII string and print it. String::AsciiValue ascii(result);printf("%s\n", *ascii);return 0;
}//create accessor for string username
global->SetAccessor(v8::String::New("user"),userGetter,userSetter);
//associates print on script to the Print function
global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); //注册类对象
Handle<FunctionTemplate> point_templ = FunctionTemplate::New();
point_templ->SetClassName(String::New("Point"));
Handle<ObjectTemplate> point_proto = point_templ->PrototypeTemplate();
point_proto->Set("method_a", FunctionTemplate::New(PointMethod_A));
point_proto->Set("method_b", FunctionTemplate::New(PointMethod_B));
//设置指针个数
Handle<ObjectTemplate> point_inst = point_templ->InstanceTemplate();
point_inst->SetInternalFieldCount(1);
//创建实例
Handle<Function> point_ctor = point_templ->GetFunction();
Local<Object> obj = point_ctor->NewInstance();
obj->SetInternalField(0, External::New(p));
//获取类指针处理Handle<Value> PointMethod_A(const Arguments& args)2. {3. Local<Object> self = args.Holder();4. Local<External> wrap = Local<External>::Cast(self->GetInternalField(0));5. void* ptr = wrap->Value();6. static_cast<Point*>(ptr)->Function_A();7. return Integer::New(static_cast<Point*>(ptr)->x_);8. }//向MakeWeak注册的callback.
void CloudAppWeakReferenceCallback(Persistent<Value> object , void * param) { if (CloudApp* cloudapp = static_cast<CloudApp*>(param)) { delete cloudapp; }
} //将C++指针通过External保存为Persistent对象,避免的指针被析构
Handle<External> MakeWeakCloudApp(void* parameter) { Persistent<External> persistentCloudApp = Persistent<External>::New(External::New(parameter)); //MakeWeak非常重要,当JS世界new一个CloudApp对象之后
//C++也必须new一个对应的指针。
//JS对象析构之后必须想办法去析构C++的指针,可以通过MakeWeak来实现,
//MakeWeak的主要目的是为了检测Persistent Handle除了当前Persistent
//的唯一引用外,没有其他的引用,就可以析构这个Persistent Handle了,
//同时调用MakeWeak的callback。这是我们可以再这个callback中delete
//C++指针 persistentCloudApp.MakeWeak(parameter, CloudAppWeakReferenceCallback); return persistentCloudApp;
} void Print(const v8::FunctionCallbackInfo<v8::Value>& args) { bool first = true; for (int i = 0; i < args.Length(); i++) { v8::HandleScope handle_scope(args.GetIsolate()); if (first) { first = false; } else { printf(" "); } v8::String::Utf8Value str(args[i]); const char* cstr = ToCString(str); printf("%s", cstr); const char* s_result = "print call succeed\n"; v8::Local<v8::String> v_result = v8::String::NewFromUtf8(args.GetIsolate(), s_result, v8::NewStringType::kNormal).ToLocalChecked(); args.GetReturnValue().Set(v_result); } printf("\n"); fflush(stdout);
}
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate); // Bind the global 'print' function to the C++ Print callback. global->Set( v8::String::NewFromUtf8(isolate, "print", v8::NewStringType::kNormal) .ToLocalChecked(), v8::FunctionTemplate::New(isolate, Print));
Local<Context> context = v8::Context::New(isolate, NULL, global);Isolate *isolate = args.GetIsolate();
Local<Object> opts = args[0]->ToObject();
Local<Number> mode = opts->Get(String::NewFromUtf8(isolate, "mode"))->ToNumber(isolate);
static void DeleteInstance(void* data) {// 将 `data` 转换为该类的实例并删除它。
}
node::AddEnvironmentCleanupHook(DeleteInstance) //在销毁环境之后被删除
JS调用C++函数,就是通过FunctionTemplate和ObjectTemplate进行扩展的。
V8的External就是专门用来封装(Wrap)和解封(UnWrap)C++指针的
V8_EXPORT
V8_INLINE
v8::Handle<
v8::Local<
const v8::Arguments
const v8::FunctionCallbackInfo<v8::Value>& 不定参数
Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate);
G
String::NewFromUtf8Literal(isolate, "isNull")
String::Cast
isolate->GetCurrentContext()
NODE_SET_PROTOTYPE_METHOD(tpl, "x", X);
https://github.com/alibaba/jsni.git
nodeqt
const qt = require("./lib/qt");
const app = new qt.QApplication();
const window = new qt.QMainWindow();
const box = new qt.QWidget();
box.setStyleSheet("background-color:red;");
box.resize(300, 300);
box.move(300, 300);
box.setParent(window);
window.resizeEvent((width, height) => {console.log("Resized1", width, height);console.log(width, height);
});
window.closeEvent(() => {console.log("Closing");
});
box.resizeEvent((width, height) => {console.log("Resized2", width, height);
});
box.mousePressEvent(() => console.log("CLICKED!"));
box.mouseReleaseEvent(() => console.log("UNCLICKED!"));
box.setMouseTracking(true);
box.mouseMoveEvent((x, y) => console.log(`MOUSE MOVED! x: ${x} y: ${y}`));
box.enterEvent(() => console.log("MOUSE ENTERED!"));
box.leaveEvent(() => console.log("MOUSE LEFT!"));
const label = new qt.QLabel(box);
console.log("Size hint", label.sizeHint());
console.log("Height", label.height());
label.setText('<span style="">dsawewwww<span style="">Hello2</span></span>');
label.adjustSize();
const label2 = new qt.QLabel(window);
const pix = new qt.QPixmap();
pix.load("/home/kusti8/Pictures/test_small.jpg");
pix.scaled(300, 300, qt.AspectRatioMode.IgnoreAspectRatio);
label2.setPixmap(pix);
label2.adjustSize();
label2.setStyleSheet("background-color: red;");
label2.move(300, 600);
label2.setScaledContents(false);
label2.setAlignment(qt.Alignment.AlignCenter);
label2.show();
const lineedit = new qt.QLineEdit(window);
lineedit.move(100, 100);
lineedit.textChangedEvent(text => console.log("text changed", text));
lineedit.show();
const combobox = new qt.QComboBox(window);
combobox.currentTextChangedEvent(text => console.log("New combo", text));
combobox.setEditable(true);
combobox.addItem("Test1");
combobox.addItem("Test2");
combobox.addItem("Test3");
box.show();
box.clear();
console.log("set parent");
window.show();
console.log("set parent");
app.aboutToQuitEvent(() => console.log("Quitting"));
console.log("Height", label.height());
console.log(qt.desktopSize());
app.exec();
GitHub - arturadib/node-qt: C++ Qt bindings for Node.js
mirrors_CoderPuppy/node-qt
GitHub - anak10thn/node-qt5
GitHub - NickCis/nodeQt: Qt binding for Node
GitHub - a7ul/mdview-nodegui: A Markdown editor in NodeGui
GitHub - kusti8/node-qt-napi: Node.js bindinds for Qt5, using NAPI
GitHub - nodegui/qode: DEPRECATED: Please see https://github.com/nodegui/qodejs instead
GitHub - svalaskevicius/qtjs-generator: Qt API bindings generator for Node.js
C++ 插件 | Node.js v22 文档
GitHub - nodegui/nodegui-starter: A starter repo for NodeGui projects
GitHub - anak10thn/qhttpserver: HTTP server implementation for Qt based on node.js' http parser
GitHub - anak10thn/chrome-app-samples: Chrome Apps
GitHub - magne4000/node-qtdatastream: Nodejs lib which can read/write Qt formatted Datastreams
GitHub - fwestrom/qtort-microservices: A simple micro-services framework for Node.js.
GitHub - ivan770/PiQture: Screenshot tool based on Electron
GitHub - miskun/qtc-sdk-node: Qt Cloud Services SDK for Node.js
v8: include/v8.h File Reference
nodegyp
node-gyp -j 8 configure
node-gyp -j 8 build
"install": "node-gyp -j 8 rebuild --arch=ia32"
"install": "node-gyp -j 8 rebuild --arch=x86"
https://github.com/kusti8/node-qt-napi/releases/download/0.0.4/qt-v0.0.4-4-win32-x64.tar.gz
工程搭建方式
gyp文件样例
TortoiseGit bash使用
set PRJ_PATH=E:\workspace\test\Web-Dev-For-Beginners\nodeqt
TortoiseGitProc.exe /command:commit /path:"%PRJ_PATH%\nodegyp" /logmsgfile:"%PRJ_PATH%\refModify.txt" /bugid:1 /closeonend:2%
TortoiseGitProc.exe /command:pull /path:"%PRJ_PATH%\nodegyp" /closeonend:2
TortoiseGitProc.exe /command:push /path:"%PRJ_PATH%\nodegyp" /closeonend:2
pause
GitHub - electron/electron-api-demos: Explore the Electron APIsExplore the Electron APIs. Contribute to electron/electron-api-demos development by creating an account on GitHub.
https://github.com/electron/electron-api-demosQuick Start | ElectronThis guide will step you through the process of creating a barebones Hello World app in Electron, similar to electron/electron-quick-start.
https://electronjs.org/docs/tutorial/quick-starthttps://github.com/electron/electron-quick-start
https://github.com/electron/electron-quick-start GitHub - qtoolkit/qtk: QTK 是一套基于HTML5 Canvas实现的, 专注于桌面/移动应用程序开发的框架。
https://github.com/sindresorhus/awesome-electron
Introduction | Electron
Electron
创作不易,小小的支持一下吧!


相关文章:
Electron qt开发教程
模块安装打包 npm install -g electron-forge electron-forge init my-project --templatevue npm start //进入目录启动 //打包成一个目录到out目录下,注意这种打包一般用于调试,并不是用于分发 npm run package //打出真正的分发包,放在o…...
尝试用 GPT-4o 写 2024高考语文作文
文章目录 新课标I卷科技进步与问题的演变 新课标II卷抵达未知之境:探索与成长的旅程 全国甲卷坦诚交流:构建真正相遇的桥梁 北京卷历久弥新 天津卷定义与自定义:在世界的缤纷中前行 上海卷认可度的思考与反思 新课标I卷 阅读下面的材料&#…...
自动化Reddit图片收集:Python爬虫技巧
引言 Reddit,作为一个全球性的社交平台,拥有海量的用户生成内容,其中包括大量的图片资源。对于数据科学家、市场研究人员或任何需要大量图片资源的人来说,自动化地从Reddit收集图片是一个极具价值的技能。本文将详细介绍如何使用…...
自动驾驶人工智能
自动驾驶技术中使用的算法和滤波器 如何部署软件中的算法和滤波器,以增强传感器数据的可用性和应用性 自动驾驶人工智能 文章目录 一、介绍二、自动驾驶的算法2.1 感知算法2.2 本地化算法2.3 映射算法2.4 规划算法2.5 控制算法2.6 过滤 器2.7 卡尔曼滤波器2.8 颗粒过…...
基础乐理入门
基础概念 乐音:音高(频率)固定,振动规则的音。钢琴等乐器发出的是乐音,听起来悦耳、柔和。噪音:振动不规则,音高也不明显的音。风声、雨声、机器轰鸣声是噪音,大多数打击乐器&#…...
mysql 8 linux7,8安装教程
选择自己对应的linux版本 cat /etc/os-release //查看自己linux系统版本 1.mysql下载地址 MySQL :: Download MySQL Community Server (Archived Versions) 拉到下面找到 选择自己linux指定的版本,否则会很麻烦 cat /etc/os-release //查看系统版本 2.查…...
『矩阵论笔记』特征分解(eigendecomposition)通俗解释!
特征分解(eigendecomposition)通俗解释! 文章目录 一. 特征分解(eigendecomposition)通俗解释!1. 它是如何工作的2. 试图达到什么目的3. 为什么它有用(将一个方阵分解成这三个组成矩阵有什么好处呢?)二. 参考文献一. 特征分解(eigendecomposition)通俗解释! 大家好,欢迎回…...
顶级域名和二级域名的区别
互联网是一个由无数个网络节点组成的复杂系统,而域名则是这个系统中用于识别和定位这些节点的重要工具。在域名体系中,顶级域名(Top-Level Domain,TLD)和二级域名(Second-Level Domain,SLD)是两个基本的层级概念。本文将探讨这两者…...
深入解析Kafka消息丢失的原因与解决方案
深入解析Kafka消息丢失的原因与解决方案 Apache Kafka是一种高吞吐量、分布式的消息系统,广泛应用于实时数据流处理。然而,在某些情况下,Kafka可能会出现消息丢失的情况,这对于数据敏感的应用来说是不可接受的。本文将深入解析Ka…...
【Python列表解锁】:掌握序列精髓,驾驭动态数据集合
文章目录 🚀一、列表🌈二、常规操作💥增💥删💥改💥查 ⭐三、补充操作 🚀一、列表 列表是一个能够存储多个同一或不同元素的序列 列表:list ---- [] 列表属于序列类型(容器…...
安卓打造安装包(应用打包、规范处理安装包、安全加固)
本章介绍应用安装包的基本制作规范,主要包括:如何导出既美观又精简的APK文件、如何按照上线规范调整App的相关设置、如何对APK文件进行安全加固以防止安装包被破解。 应用打包 本节介绍APK安装包的打包过程,包括:如何利用Androi…...
ElasticSearch教程(详解版)
本篇博客将向各位详细介绍elasticsearch,也算是对我最近学完elasticsearch的一个总结,对于如何在Kibana中使用DSL指令,本篇文章不会进行介绍,这里只会介绍在java中如何进行使用,保证你看完之后就会在项目中进行上手&am…...
[office] excel做曲线图的方法步骤详解 #经验分享#知识分享#其他
excel做曲线图的方法步骤详解 Excel是当今社会最流行用的办公软件之一,Excel可以用于数据的整理、分析、对比。可以更直观的看到数据的变化情况,而有很多时候需要制作曲线图表进行数据比较,因此,下面是小编整理的如何用excel做曲线…...
Git+Gitlab 远程库测试学习
Git远程仓库 1、Git远程仓库 何搭建Git远程仓库呢?我们可以借助互联网上提供的一些代码托管服务来实现 Gitee 码云是国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快 码云 Gitee - 基于 Git 的代码托…...
Python可视化 | 使用matplotlib绘制面积图示例
面积图是数据可视化中的一个有效工具,用于说明时间上的关系和趋势。它们提供了一种全面的、视觉上迷人的方法,通过熟练地将折线图的可读性与填充区域的吸引力相结合来呈现数值数据。 在本文中,我们将学习更多关于在Python中创建面积折线图的…...
【环境搭建】2.阿里云ECS服务器 安装MySQL
在阿里云的 Alibaba Cloud Linux 3.2104 LTS 64位系统上安装 MySQL 8,可以按照以下步骤进行: 1.更新系统软件包: 首先,更新系统软件包以确保所有软件包都是最新的: sudo yum update -y2.下载 MySQL 8 官方 Yum 仓库…...
Python Flask 入门开发
Python基础学习: Pyhton 语法基础Python 变量Python控制流Python 函数与类Python Exception处理Python 文件操作Python 日期与时间Python Socket的使用Python 模块Python 魔法方法与属性 Flask基础学习: Python中如何选择Web开发框架?Pyth…...
PostgreSQL查看当前锁信息
PostgreSQL查看当前锁信息 基础信息 OS版本:Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本:16.2 pg软件目录:/home/pg16/soft pg数据目录:/home/pg16/data 端口:5777查看当前锁信息的sql SELECT pg_s…...
毫米波雷达深度学习技术-1.6目标识别2
1.6.4 自动编码器和变体自动编码器 自编码器包括一个编码器神经网络,随后是一个解码器神经网络,其目的是在输出处重建输入数据。自动编码器的设计在网络中施加了一个瓶颈,它鼓励原始输入的压缩表示。通常,自编码器旨在利用数据中的…...
MineAdmin 前端打包后,访问速度慢原因及优化
前言:打包mineadmin-vue前端后,访问速度很慢,打开控制台,发现有一个index-xxx.js文件达7M,加载时间太长; 优化: 一:使用文件压缩(gzip压缩) 1、安装compre…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!
目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
