Electron qt开发教程

模块安装打包 

npm install -g electron-forge
electron-forge init my-project --template=vue
npm start  //进入目录启动
//打包成一个目录到out目录下,注意这种打包一般用于调试,并不是用于分发
npm run package
//打出真正的分发包,放在out\make目录下
npm run make

npx @electron-forge/cli@latest import
npx create-electron-app my-app

npm 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 start

cnpm 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] = {
    // 拼接String
    String::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.icon-default.png?t=N7T8https://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.icon-default.png?t=N7T8https://electronjs.org/docs/tutorial/quick-starthttps://github.com/electron/electron-quick-starticon-default.png?t=N7T8https://github.com/electron/electron-quick-start GitHub - qtoolkit/qtk: QTK 是一套基于HTML5 Canvas实现的, 专注于桌面/移动应用程序开发的框架。

https://github.com/sindresorhus/awesome-electron

Introduction | Electron

Electron


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/690964.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java的基础知识包括哪些?

java入门基础知识点需要学什么&#xff1f;入门学习一定要找到适合自己的方法才能事半功倍&#xff0c;对需要掌握的知识点有一个大概的了解&#xff0c;Java入门基础知识包含&#xff1a;标识符、变量、AScii码和Unicod码、基本数据类型转化String类、进制、运算符、程序流程控…

【AIGC】基于大模型+知识库的Code Review实践

一、背景描述 一句话介绍就是&#xff1a;基于开源大模型 知识库的 Code Review 实践&#xff0c;类似一个代码评审助手&#xff08;CR Copilot&#xff09;。信息安全合规问题&#xff1a;公司内代码直接调 ChatGPT / Claude 会有安全/合规问题&#xff0c;为了使用 ChatGPT…

【数据结构】初识数据结构之复杂度与链表

【数据结构】初识数据结构之复杂度与链表 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C语言学习之路 文章目录 【数据结构】初识数据结构之复杂度与链表前言一.数据结构和算法1.1数据结构1.2算法1.3数据结构和算法的重要性 二.时间与空间…

[AIGC] Springboot 自动配置的作用及理由

在详细解释SpringBoot的自动配置之前&#xff0c;先介绍以下背景知识。在创建现代复杂的应用程序时&#xff0c;一个困难的部分是正确地设置您的开发环境。这个问题尤其在Java世界中尤为突出&#xff0c;因为您必须管理和配置许多独立的标准和技术。 当我们谈论Spring Boot的自…

[NOVATEK] NT96580行车记录仪功能学习笔记(持续更新~

一、u-Boot升级灯 运行u-Boot程序时LED灯闪烁,找到运行过程中一直在运行的函数在里面进行LED引脚电平的翻转 宏定义 Z:\SunFan\AHD580\pip\na51055_PIP\BSP\u-boot\include\configs\nvt-na51055-evb.h Z:\SunFan\AHD580\pip\na51055_PIP\BSP\u-boot\drivers\mtd\nvt_flash_…

HTTP协议分析实验:通过一次下载任务抓包分析

HTTP协议分析 问&#xff1a;HTTP是干啥用的&#xff1f; 最简单通俗的解释&#xff1a;HTTP 是客户端浏览器或其他程序与Web服务器之间的应用层通信协议。 在Internet上的Web服务器上存放的都是超文本信息&#xff0c;客户机需要通过HTTP协议传输所要访问的超文本信息。 一、…

btstack协议栈实战篇--GAP Link Key Management

btstack协议栈---总目录-CSDN博客 目录 1.GAP 链接密钥逻辑 2.蓝牙逻辑 3.主应用程序设置 4.log信息 展示了如何遍历存储在 NVS 中的经典链接密钥&#xff0c;链接密钥是每个设备-设备绑定的。如果蓝牙控制器可以交换&#xff0c;例如在桌面系统上&#xff0c;则每个控制器都需…

Shell脚本学习_环境变量深入

目录 1.Shell环境变量深入&#xff1a;自定义系统环境变量 2.Shell环境变量深入&#xff1a;加载流程原理介绍 3.Shell环境变量深入&#xff1a;加载流程测试 4.Shell环境变量深入&#xff1a;识别与切换Shell环境类型 1.Shell环境变量深入&#xff1a;自定义系统环境变量 …

8.3 Go 包的组织结构

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

WPS JS宏获取自动筛选后的行数

//WPS JS宏获取自动筛选后的行数 function getFilterRowCnt(shtRng)//shtRng表示筛选目标工作表范围 {let lngRowCnt 0;for(let rngCell of shtRng.SpecialCells(xlCellTypeVisible).Areas)//获取自动筛选后的单元格行数{lngRowCnt lngRowCnt rngCell.Rows.Count;}return ln…

从0到1:企业办公审批小程序开发笔记

可行性分析 企业办公审批小程序&#xff0c;适合各大公司&#xff0c;企业&#xff0c;机关部门办公审批流程&#xff0c;适用于请假审批&#xff0c;报销审批&#xff0c;外出审批&#xff0c;合同审批&#xff0c;采购审批&#xff0c;入职审批&#xff0c;其他审批等规划化…

关于音乐播放器与系统功能联动功能梳理

主要实现功能&#xff1a; 一、通知栏播放显示和控制 二、系统下拉栏中播放模块显示同步 三、与其他播放器状态同步&#xff1a;本应用播放时暂停其他应用播放&#xff0c;进入其他应用播放时&#xff0c;暂停本应用的后台播放 通知栏播放的显示和控制&#xff1a; 通过Not…

RTKLIB之RTKPLOT画图工具

开源工具RTKLIB在业内如雷贯耳&#xff0c;其中的RTKPLOT最近正在学习&#xff0c;发现其功能之强大&#xff0c;前所未见&#xff0c;打开了新的思路。 使用思博伦GSS7000卫星导航模拟器,PosApp软件仿真一个载具位置 1&#xff0c;RTKPLOT支持DUT 串口直接输出的NMEA数据并…

基于深度学习的中文标点预测模型-中文标点重建(Transformer模型)【已开源】

基于深度学习的中文标点预测模型-中文标点重建&#xff08;Transformer模型&#xff09;提供模型代码和训练好的模型 前言 目前关于使用深度学习对文本自动添加标点符号的研究并不多见&#xff0c;已知的开源项目也较少&#xff0c;而对该领域的详细介绍更是稀缺。然而&#x…

苹果手机微信如何直接打印文件

在快节奏的工作和生活中&#xff0c;打印文件的需求无处不在。但你是否曾经遇到过这样的困扰&#xff1a;打印店价格高昂&#xff0c;让你望而却步&#xff1f;今天&#xff0c;我要给大家介绍一款神奇的微信小程序——琢贝云打印&#xff0c;让你的苹果手机微信直接变身移动打…

React Hooks路由传参

场景&#xff1a;如何把想要的参数带到跳转过去的页面里呢&#xff1f;很简单 上代码&#xff1a; 在你需要跳转的页面上 引入 Link用来跳转使用 Link跳转并携带参数 然后需要什么参数就带什么过去喽 这里record里面存的就是我的数据 我只需要id和state然后到你跳转过去的页面…

MySQL-备份(三)

备份作用&#xff1a;保证数据的安全和完整。 一 备份类别 类别物理备份 xtrabackup逻辑备份mysqldump对象数据库物理文件数据库对象&#xff08;如用户、表、存储过程等&#xff09;可移植性差&#xff0c;不能恢复到不同版本mysql对象级备份&#xff0c;可移植性强占用空间占…

【C语言】详解函数(上)(庖丁解牛版)

文章目录 1. 前言2. 函数的概念3.库函数3.1 标准库和头文件3.2 库函数的使用3.2.1 头文件的包含3.2.2 实践 4. 自定义函数4.1 自定义函数的语法形式4.2 函数的举例 5. 形参和实参5.1 实参5.2 形参5.3 实参和形参的关系 6. return 语句6. 总结 1. 前言 一讲到函数这块&#xff…

算法—字符串操作

394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:string longestCommonPrefix(vector<string>& strs) { string retstrs[0];//***1***记得先要初始化ret&#xff0c;作为第一个比较值for(int i0;i<strs.size();i){retfoundcom…

聪明人社交的基本顺序:千万别搞反了,越早明白越好

聪明人社交的基本顺序&#xff1a;千万别搞反了&#xff0c;越早明白越好 国学文化 德鲁克博雅管理 2024-03-27 17:00 作者&#xff1a;方小格 来源&#xff1a;国学文化&#xff08;gxwh001&#xff09; 导语 比一个好的圈子更重要的&#xff0c;是自己优质的能力。 唐诗宋…