模块安装打包npm install -g electron-forgeelectron-forge init my-project --templatevuenpm start //进入目录启动//打包成一个目录到out目录下注意这种打包一般用于调试并不是用于分发npm run package//打出真正的分发包放在out\make目录下npm run makenpx electron-forge/clilatest importnpx create-electron-app my-appnpm install mousetrap //快捷键绑定库npm install worker_threads //工作线程模块npm install worker-loader //npm init //C项目目录下初始化项目npm install --global --production windows-build-toolselectron 将pc端vue页面打包为桌面端应用-CSDN博客快速体验npm install -g electron-prebuiltgit clone https://github.com/electron/electron-quick-startcd electron-quick-startnpm install npm startcnpm install electron-packager -gscripts: {package:electron-packager . HelloWorld --platformwin32 --archx64 --iconcomputer.ico --out./out --asar --app-version0.0.1 --overwrite --ignorenode_modules}npm run packageGitHub - electron/electron-api-demos: Explore the Electron APIspython %~dp0gyp_main.py %*JS调用C#include node.h #include v8.h using namespace v8; // 传入了两个参数args[0] 字符串args[1] 回调函数 void hello(const FunctionCallbackInfoValue 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方法来转换 LocalFunction callback LocalFunction::Cast(args[1]); LocalValue argv[1] { // 拼接String String::Concat(LocalString::Cast(args[0]), String::NewFromUtf8(isolate, world)) }; // 调用回调, 参数: 当前上下文参数个数参数列表 callback-Call(isolate-GetCurrentContext()-Global(), 1, argv); } // 相当于在 exports 对象中添加 { hello: hello } void init(LocalObject exports) { NODE_SET_METHOD(exports, hello, hello); } // 将 export 对象暴露出去 // 原型 NODE_MODULE(module_name, Initialize) NODE_MODULE(test, init); //方法暴露 void Method(const FunctionCallbackInfoValue args) { Isolate* isolate args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8( isolate, world).ToLocalChecked()); } void Initialize(LocalObject exports) { NODE_SET_METHOD(exports, hello, Method); } NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize) extern C NODE_MODULE_EXPORT void NODE_MODULE_INITIALIZER(LocalObject exports, LocalValue module, LocalContext 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. HandleContext 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. HandleString source String::New(Hello , World!); // Compile the source code. HandleScript script Script::Compile(source); // Run the script to get the result. HandleValue 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)); //注册类对象 HandleFunctionTemplate point_templ FunctionTemplate::New(); point_templ-SetClassName(String::New(Point)); HandleObjectTemplate point_proto point_templ-PrototypeTemplate(); point_proto-Set(method_a, FunctionTemplate::New(PointMethod_A)); point_proto-Set(method_b, FunctionTemplate::New(PointMethod_B)); //设置指针个数 HandleObjectTemplate point_inst point_templ-InstanceTemplate(); point_inst-SetInternalFieldCount(1); //创建实例 HandleFunction point_ctor point_templ-GetFunction(); LocalObject obj point_ctor-NewInstance(); obj-SetInternalField(0, External::New(p)); //获取类指针处理 HandleValue PointMethod_A(const Arguments args) 2. { 3. LocalObject self args.Holder(); 4. LocalExternal wrap LocalExternal::Cast(self-GetInternalField(0)); 5. void* ptr wrap-Value(); 6. static_castPoint*(ptr)-Function_A(); 7. return Integer::New(static_castPoint*(ptr)-x_); 8. } //向MakeWeak注册的callback. void CloudAppWeakReferenceCallback(PersistentValue object , void * param) { if (CloudApp* cloudapp static_castCloudApp*(param)) { delete cloudapp; } } //将C指针通过External保存为Persistent对象避免的指针被析构 HandleExternal MakeWeakCloudApp(void* parameter) { PersistentExternal persistentCloudApp PersistentExternal::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::FunctionCallbackInfov8::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::Localv8::String v_result v8::String::NewFromUtf8(args.GetIsolate(), s_result, v8::NewStringType::kNormal).ToLocalChecked(); args.GetReturnValue().Set(v_result); } printf(\n); fflush(stdout); } v8::Localv8::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)); LocalContext context v8::Context::New(isolate, NULL, global); Isolate *isolate args.GetIsolate(); LocalObject opts args[0]-ToObject(); LocalNumber 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_EXPORTV8_INLINEv8::Handlev8::Localconst v8::Argumentsconst v8::FunctionCallbackInfov8::Value 不定参数LocalFunctionTemplate tpl FunctionTemplate::New(isolate);GString::NewFromUtf8Literal(isolate, isNull)String::Castisolate-GetCurrentContext()NODE_SET_PROTOTYPE_METHOD(tpl, x, X);https://github.com/alibaba/jsni.gitnodeqtconst 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 styledsawewwwwspan styleHello2/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.jsmirrors_CoderPuppy/node-qtGitHub - anak10thn/node-qt5GitHub - NickCis/nodeQt: Qt binding for NodeGitHub - a7ul/mdview-nodegui: A Markdown editor in NodeGuiGitHub - kusti8/node-qt-napi: Node.js bindinds for Qt5, using NAPIGitHub - nodegui/qode: DEPRECATED: Please see https://github.com/nodegui/qodejs insteadGitHub - svalaskevicius/qtjs-generator: Qt API bindings generator for Node.jsC 插件 | Node.js v22 文档GitHub - nodegui/nodegui-starter: A starter repo for NodeGui projectsGitHub - anak10thn/qhttpserver: HTTP server implementation for Qt based on node.js http parserGitHub - anak10thn/chrome-app-samples: Chrome AppsGitHub - magne4000/node-qtdatastream: Nodejs lib which can read/write Qt formatted DatastreamsGitHub - fwestrom/qtort-microservices: A simple micro-services framework for Node.js.GitHub - ivan770/PiQture: Screenshot tool based on ElectronGitHub - miskun/qtc-sdk-node: Qt Cloud Services SDK for Node.jsv8: include/v8.h File Referencenodegypnode-gyp -j 8 configurenode-gyp -j 8 buildinstall: node-gyp -j 8 rebuild --archia32install: node-gyp -j 8 rebuild --archx86https://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_PATHE:\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 pausegit bash使用git config --global user.name your-name git config --global user.email your-email git init Initialize a git repositor git status Check status git add . git add [file or folder name] git reset //将文件还原到上一个commit git reset [file or folder name] //特定文件还原到上一个commit git commit -m first commit git remote add origin https://github.com/username/repository_name.git //添加远程仓库地址 git push -u origin main //This sends your commits in your main branch to GitHub git branch [branch-name] //Create a branch git checkout [branch-name] //Switch to working branch git checkout main git pull //Combine your work with the main branch git checkout [branch_name] git merge main //conflicts combine the changes happens in your working branch. git push --set-upstream origin [branch-name] //Send your work to GitHub git branch -d [branch-name] //clean up both your local branch git pull参考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-starthttps://github.com/electron/electron-quick-startGitHub - qtoolkit/qtk: QTK 是一套基于HTML5 Canvas实现的, 专注于桌面/移动应用程序开发的框架。https://github.com/sindresorhus/awesome-electronIntroduction | ElectronElectronnode与Electron版本对应GitHub - atom/atom: :atom: The hackable text editorGitHub - nodejs/node-addon-api: Module for using Node-API from CGitHub - glencornell/TinyEventLib: A tiny clean room implementation of the event processing loop in Qt创作不易小小的支持一下吧
企业数字化 ERP 产品动态
相关推荐
gprof性能分析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/11 14:03:45
Google Chrome 设备工具栏原理 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/11 14:03:45
layout 自定义布局管理器 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 20:29:29
广东省特种工证件查询值不值得考?别怕考不过白交培训费 广东省特种工证件查询值不值得考?别怕考不过白交培训费 你是不是正在纠结要不要考广东省特种工证件?怕花了几千块培训费最后还是考不过?别急,今天我就从一个过来人的角度,给你讲讲这个证到底 值不值得考… · 2026/11/11 14:02:59
韩国电工证如何申请 上岗必备的求职敲门砖 韩国电工证如何申请 上岗必备的求职敲门砖 你是不是也在为找不到工作发愁?特种作业证就是你求职路上的“通行证”,尤其是韩国电工证, 上岗必备… · 2026/11/11 14:02:59
佛山南海电工证报考通过率揭秘:怎么避坑?怎么拿证?怎么挣钱? 佛山南海电工证报考通过率揭秘:怎么避坑?怎么拿证?怎么挣钱? 你是不是也担心在佛山南海电工证报考这事上被中介坑?是不是看网上一堆广告,又怕花冤枉钱还拿不到证?别急,今天咱们就从 佛山南海电工证报考 的全过程聊起, 通过率揭秘… · 2026/11/11 14:02:59
无电工证怎么找工作 别踩坑!郑州电工证办理全攻略 无电工证怎么找工作 别踩坑!郑州电工证办理全攻略 你还在为找不到电工相关工作发愁?无电工证怎么找工作?别踩坑!在郑州,很多建筑、电力、维修类岗位都明确要求持证上岗,没有特种作业操作证,别说进工地,连面试机会都没有。尤其现在工地项目多、用工紧… · 2026/11/11 14:02:59
桂阳哪里考电工证全流程办理指南 桂阳哪里考电工证全流程办理指南 工地太忙根本没时间复习考试,你是不是也经常这样想?电工证作为特种作业人员的“通行证”,在工地、工厂等高风险作业环境中是必备的资质,但很多人因为工作繁忙、信息不全,不知道 在哪考… · 2026/11/11 14:02:59
工地太忙根本没时间复习考试?巩义电工证河南的真实经历教你避坑 工地太忙根本没时间复习考试?巩义电工证河南的真实经历教你避坑 工地太忙根本没时间复习考试?我身边有位在信阳干了五年的电工老王,就因为没考下巩义电工证河南,差点丢了饭碗。那会儿他天天在工地上抢时间、抢进度,哪还有心思去复习考试?结果公司要求全… · 2026/11/11 14:01:59
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/11 12:18:07
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/10 17:46:39
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/10 17:11:43
_中职电工证最新政策解读 中职电工证在哪考?工地太忙根本没时间复习考试的救星来了 工地太忙根本没时间复习考试,这是很多正在备考 中职电工证 的建筑工友的真实写照。你不是不想考,而是真的没时间。但别担心,这期内容是 新乡初次报考人员… · 2026/11/11 0:00:52
昆明电工证培训价格值不值得考?老电工告诉你真相 昆明电工证培训价格值不值得考?老电工告诉你真相 之前考的证在外省能不能转过来?这个问题是很多在外地打工、换城市生活、或者是想在昆明发展的朋友最关心的。尤其是现在云南发展快,很多企业都在招持证上岗的电工,如果你手头有证但不在本地,那这个证是不… · 2026/11/11 0:00:52
特种电缆张工网上查询全攻略:外省证如何转过来 特种电缆张工网上查询全攻略:外省证如何转过来 之前考的证在外省能不能转过来?这是很多特种作业从业者最关心的问题,尤其是像特种电缆张工这类证书,直接关系到日常工作是否合规、能否顺利晋升。很多小伙伴因为证书归属地的问题,陷入职业发展的瓶颈,甚至… · 2026/11/11 0:00:52
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 20:19:29
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 19:22:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/10 17:00:47