千锋教育-做有情怀、有良心、有品质的IT职业教育机构

400-811-9990
当前位置:首页  >  技术文章  >  正文

千锋web前端培训分享Electron之Main Process API

时间:2020-07-07 16:22     来源:千锋教育 作者:刘老师

本节由千锋web前端培训机构讲师给大家分享Electron使用指南之Main Process API,Electron API (Electron API 有三种) Main Process (主进进程) Renderer Process(渲染进程) Share Modules(共享模块)

App

事件

ready:

当 Electron 完成初始化时被触发。

两种使用方法 

app.on('ready', createWindow)

app.on('ready', () => {

console.log('App is ready!')

createWindow()

})

检查应用是否登录:app.isReady()

如果应用没有Ready,app.isReady()的值为 false

console.log('应用是否登录:' + app.isReady())

此时应用应该已经Ready

setTimeout(() => {

console.log('应用是否登录:' + app.isReady())

}, 2000)

before-quit

在应用程序开始关闭窗口之前触发。

app.on('before-quit', (e) => {

console.log('App is quiting')

e.preventDefault()

})

browser-window-blur

在 browserWindow 失去焦点时发出

app.on('browser-window-blur', (e) => {

console.log('App unfocused')

})

browser-window-focus

在 browserWindow 获得焦点时发出

app.on('browser-window-focus', (e) => {

console.log('App focused')

})

方法

app.quit()

app.on('browser-window-blur', (e) => {

setTimeout(() => {

app.quit()

}, 3000)

})

app.on('browser-window-blur', (e) => {

setTimeout(app.quit, 3000)

})

app.getPath(name)

app.on('ready', () => {

console.log(app.getPath('desktop'))

console.log(app.getPath('music'))

console.log(app.getPath('temp'))

console.log(app.getPath('userData'))

createWindow()

})

BrowserWindow

electron.BrowserWindow: 创建和控制浏览器窗口

实例方法

win.loadURL(url[, options]): 和 loadFile 互斥

mainWindow.loadURL('https://www.baidu.com')

优雅的显示窗口

使用ready-to-show事件

let mainWindow = new BrowserWindow({ show: false })

mainWindow.once('ready-to-show', () => {

mainWindow.show()

})

设置 backgroundColor

let win = new BrowserWindow({ backgroundColor: '#2e2c29' })

父子窗口

窗口定义

secondaryWindow = new BrowserWindow({

width: 600,

height: 600,

webPreferences: { nodeIntegration: true }

})

secondaryWindow.loadFile('index.html')

secondaryWindow.on('closed',  () => {

mainWindow = null

})

窗口关系

secondaryWindow = new BrowserWindow({

parent: mainWindon, // 定义父窗口

modal: true // 锁定在主窗口

})

子窗口显示和隐藏

secondaryWindow = new BrowserWindow({

show: false

})

setTimeout(() => {

secondaryWindow.show()

setTimeout(() => {

secondaryWindow.hide()

}, 3000)

}, 2000)

无边框窗口

Frameless Window

mainWindow = new BrowserWindow({

frame: false

})

让页面可拖拽

<body style="user-select: none; -webkit-app-region:drag;">

no-drag 修复下面控件的bug

<input style="-webkit-app-region: no-drag;" type="range" name="range" min="0" max="10">

显示红绿灯

mainWindow = new BrowserWindow({

titleBarStyle: 'hidden' // or hiddenInset 距离红绿灯更近

})

属性与方法

minWidth && minHeight

mainWindow = new BrowserWindow({

minWidth: 300,

minHeight: 300

})

窗口焦点事件

secWindow = new BrowserWindow({

width: 400, height: 300,

webPreferences: { nodeIntegration: true },

})

mainWindow.on('focus', () => {

console.log('mainWindow focused')

})

secWindow.on('focus', () => {

console.log('secWindow focused')

})

app.on('browser-window-focus', () => {

console.log('App focused')

})

静态方法

getAllWindows()

let allWindows = BrowserWindow.getAllWindows()

console.log(allWindows)

实例属性

id

console.log(secWindow.id)

实例方法

maximize()secWindow.on('closed', () => { mainWindow.maximize() })

state

electron-window-state 保存窗口的状态 npm install electron-window-state 

webContents

webContents 是 EventEmitter 的实例, 负责渲染和控制网页, 是 BrowserWindow 对象的一个属性。 let wc = mainWindow.webContents console.log(wc)

方法 getAllWebContents()

返回 WebContents[] - 所有 WebContents 实例的数组。 包含所有Windows,webviews,opened devtools 和 devtools 扩展背景页的 web 内容const {app, BrowserWindow, webContents} = require('electron') console.log(webContents.getAllWebContents())

实例事件

did-finish-load

dom-ready

<div>

<img src="https://placekitten.com/500/500" alt="">

</div>

<script>

let wc = mainWindow.webContents

wc.on('did-finish-load', () => {

console.log('Conent fully loaded')

})

wc.on('dom-ready', () => {

console.log('DOM Ready')

})

</script>

new-window

<div>

<a target="_blank" href="https://placekitten.com/500/500"><h3>Kitten</h3></a>

</div>

<script>

wc.on('new-window', (e, url) => {

e.preventDefault()

console.log('DOM Ready')

})

</script>

before-input-event

wc.on('before-input-event', (e, input) => {

console.log(`${input.key} : ${input.type}`)

})

login

did-navigate

mainWindow.loadURL('https://httpbin.org/basic-auth/user/passwd')

wc.on('login', (e, request, authInfo, callback) => {

console.log('Logging in:')

callback('user', 'passwd')

})

wc.on('did-navigate', (e, url, statusCode, message) => {

console.log(`Navigated to: ${url}, with response code: ${statusCode}`)

console.log(message)

})

media-started-playing

media-paused

<div>

<video src="./mgm.mp4" controls width="400"></video>

</div>

<script>

wc.on('media-started-playing', () => {

console.log('Video Started')

})

wc.on('media-paused', () => {

console.log('Video Paused')

})

</script>

context-menu : 右键上下文信息

wc.on('context-menu', (e, params) => {

console.log(`Context menu opened on: ${params.mediaType} at x:${params.x}, y:${params.y}`)

})

wc.on('context-menu', (e, params) => {

console.log(`User seleted text: ${params.selectionText}`)

console.log(`Selection can be copied: ${params.editFlags.canCopy}`)

})

实例方法

executeJavaScript()

wc.on('context-menu', (e, params) => {

wc.executeJavaScript(`alert('${params.selectionText}')`)

})

Session

管理浏览器会话、cookie、缓存、代理设置等。

起步

创建session对象

let session = mainWindow.webContents.session

console.log(session) // {}

在chromium 创建localStorage,然后创建两个窗口,两个session共享

mainWindow = new BrowserWindow({

width: 1000, height: 800,

webPreferences: { nodeIntegration: true }

})

secWindow = new BrowserWindow({

width: 500, height: 400,

webPreferences: { nodeIntegration: true }

})

let session = mainWindow.webContents.session

let session2 = mainWindow.webContents.session

console.log(Object.is(session, session2)) // true

// Load index.html into the new BrowserWindow

mainWindow.loadFile('index.html')

secWindow.loadFile('index.html')

// Open DevTools - Remove for PRODUCTION!

mainWindow.webContents.openDevTools();

secWindow.webContents.openDevTools();

// Listen for window being closed

mainWindow.on('closed',  () => {

mainWindow = null

})

secWindow.on('closed',  () => {

secWindow = null

})

defaultSession

const {app, BrowserWindow, session} = require('electron')

let ses = mainWindow.webContents.session

console.log(Object.is(session.defaultSession, ses)) // true

自定义session

let customSes = session.fromPartition('part1')

console.log(Object.is(customSes, ses)) //false, 此时customSes 还是共享session

secWindow = new BrowserWindow({

width: 500, height: 400,

webPreferences: {

nodeIntegration: true,

session: customSes // 定义session, 此时子窗口有自己的session

}

})

// 在子窗口里创建localstorge: winName/secWindow

// 关闭所有窗口,发现创建的localstorage又消失了,因为此时的session存储在内存里,重新启动应用又消失了。可以加前缀persist,使其变为永久存储:

let customSes = session.fromPartition('persist:part1')

// 或者:

secWindow = new BrowserWindow({

width: 500, height: 400,

webPreferences: {

nodeIntegration: true,

- session: customSes

+ partition: 'persist:part1'

}

})

实例方法

ses.clearStorageData() // 删除主窗口的的storage

cookie

查询和修改一个会话的cookies

// 查询所有 cookies

session.defaultSession.cookies.get({})

.then((cookies) => {

console.log(cookies)

}).catch((error) => {

console.log(error)

})

// 查询所有与设置的 URL 相关的所有 cookies

session.defaultSession.cookies.get({ url: 'http://www.github.com' })

.then((cookies) => {

console.log(cookies)

}).catch((error) => {

console.log(error)

})

// 设置一个 cookie,使用设置的名称;

// 如果存在,则会覆盖原先 cookie.

const cookie = { url: 'http://www.github.com', name: 'dummy_name', value: 'dummy' }

session.defaultSession.cookies.set(cookie)

.then(() => {

// success

}, (error) => {

console.error(error)

})

downloadItem

控制来自于远程资源的文件下载。

<h2><a href="https://picsum.photos/5000/5000/" download>Download Image</a></h2>

<progress value="0" max="100" id="progress"></progress>

<script>

window.progress = document.getElementById('progress')

</script>

// main.js

let ses = session.defaultSession

ses.on('will-download', (e, downloadItem, webContents) => {

let fileName = downloadItem.getFilename()

let fileSize = downloadItem.getTotalBytes()

// Save to desktop

downloadItem.setSavePath(app.getPath('desktop') + `/${fileName}`)

downloadItem.on('updated', (e, state) => {

let received = downloadItem.getReceivedBytes()

if (state === 'progressing' && received) {

let progress = Math.round((received/fileSize)*100)

webContents.executeJavaScript(`window.progress.value = ${progress}`)

}

})

})

dialog - 对话框

显示用于打开和保存文件、警报等的本机系统对话框

const {app, BrowserWindow, dialog} = require('electron')

mainWindow.webContents.on('did-finish-load', () => {

dialog.showOpenDialog({

buttonLabel: '选择',

defaultPath: app.getPath('desktop'),

properties: ['multiSelections', 'createDirectory', 'openFile', 'openDirectory']

}, filepaths => {

console.log(filepaths)

})

})

dialog.showSaveDialog({}, filename => {

console.log(filename)

})

const answers = ['Yes', 'No', 'Maybe']

dialog.showMessageBox({

title: 'Message Box',

message: 'Please select an option',

detail: 'Message details.',

buttons: answers

}, response => {

console.log(`User selected: ${answers[response]}`)

})

快捷键+系统快捷键

快捷键:定义键盘快捷键。 系统快捷键:在应用程序没有键盘焦点时,监听键盘事件。

快捷键可以包含多个功能键和一个键码的字符串,由符号+结合,用来定义你应用中的键盘快捷键

示例: 

CommandOrControl+A

CommandOrControl+Shift+Z

快捷方式使用 register 方法在 globalShortcut 模块中注册。

globalShortcut 模块可以在操作系统中注册/注销全局快捷键, 以便可以为操作定制各种快捷键。

注意: 快捷方式是全局的; 即使应用程序没有键盘焦点, 它也仍然在持续监听键盘事件。 在应用程序模块发出 ready 事件之前, 不应使用此模块。

const {app, BrowserWindow, globalShortcut} = require('electron')

globalShortcut.register('G', () => {

console.log('User pressed G')

})

globalShortcut.register('CommandOrControl+Y', () => {

console.log('User pressed G with a combination key')

globalShortcut.unregister('CommandOrControl+G')

})

Menu

1、index.html

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">

<title>Hello World!</title>

</head>

<body>

<h1>Hello World!</h1>

<textarea name="name" rows="8" cols="80"></textarea>

<!-- All of the Node.js APIs are available in this renderer process. -->

We are using Node.js <strong><script>document.write( process.versions.node)</script></strong>,

and Electron <strong><script>document.write( process.versions.electron )</script></strong>.

<script>

// You can also require other files to run in this process

require('./renderer.js')

</script>

</body>

</html>

2、main.js

// Modules

const {app, BrowserWindow, Menu, MenuItem} = require('electron')

// Keep a global reference of the window object, if you don't, the window will

// be closed automatically when the JavaScript object is garbage collected.

let mainWindow

let mainMenu = Menu.buildFromTemplate( require('./mainMenu') )

// Create a new BrowserWindow when `app` is ready

function createWindow () {

mainWindow = new BrowserWindow({

width: 1000, height: 800,

webPreferences: { nodeIntegration: true }

})

// Load index.html into the new BrowserWindow

mainWindow.loadFile('index.html')

// Open DevTools - Remove for PRODUCTION!

mainWindow.webContents.openDevTools();

Menu.setApplicationMenu(mainMenu)

// Listen for window being closed

mainWindow.on('closed',  () => {

mainWindow = null

})

}

// Electron `app` is ready

app.on('ready', createWindow)

// Quit when all windows are closed - (Not macOS - Darwin)

app.on('window-all-closed', () => {

if (process.platform !== 'darwin') app.quit()

})

// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow

app.on('activate', () => {

if (mainWindow === null) createWindow()

})

3、mainMenu.js

module.exports = [

{

label: 'Electron',

submenu: [

{ label: 'Item 1'},

{ label: 'Item 2', submenu: [ { label: 'Sub Item 1'} ]},

{ label: 'Item 3'},

]

},

{

label: 'Edit',

submenu: [

{ role: 'undo'},

{ role: 'redo'},

{ role: 'copy'},

{ role: 'paste'},

]

},

{

label: 'Actions',

submenu: [

{

label: 'DevTools',

role: 'toggleDevTools'

},

{

role: 'toggleFullScreen'

},

{

label: 'Greet',

click: () => { console.log('Hello from Main Menu') },

accelerator: 'Shift+Alt+G'

}

]

}

]

Context Menus

1、index.html

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">

<title>Hello World!</title>

</head>

<body>

<h1>Hello World!</h1>

<textarea name="name" rows="8" cols="80"></textarea>

<!-- All of the Node.js APIs are available in this renderer process. -->

We are using Node.js <strong><script>document.write( process.versions.node)</script></strong>,

and Electron <strong><script>document.write( process.versions.electron )</script></strong>.

<script>

// You can also require other files to run in this process

require('./renderer.js')

</script>

</body>

</html>

2、main.js

// Modules

const {app, BrowserWindow, Menu} = require('electron')

// Keep a global reference of the window object, if you don't, the window will

// be closed automatically when the JavaScript object is garbage collected.

let mainWindow

let contextMenu = Menu.buildFromTemplate([

{ label: 'Item 1' },

{ role: 'editMenu' }

])

// Create a new BrowserWindow when `app` is ready

function createWindow () {

mainWindow = new BrowserWindow({

width: 1000, height: 800,

webPreferences: { nodeIntegration: true }

})

// Load index.html into the new BrowserWindow

mainWindow.loadFile('index.html')

// Open DevTools - Remove for PRODUCTION!

mainWindow.webContents.openDevTools();

mainWindow.webContents.on('context-menu', e => {

contextMenu.popup()

})

// Listen for window being closed

mainWindow.on('closed',  () => {

mainWindow = null

})

}

// Electron `app` is ready

app.on('ready', createWindow)

// Quit when all windows are closed - (Not macOS - Darwin)

app.on('window-all-closed', () => {

if (process.platform !== 'darwin') app.quit()

})

// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow

app.on('activate', () => {

if (mainWindow === null) createWindow()

})

Tray (托盘)

1、main.js

// Modules

const {app, BrowserWindow, Tray, Menu} = require('electron')

// Keep a global reference of the window object, if you don't, the window will

// be closed automatically when the JavaScript object is garbage collected.

let mainWindow, tray

let trayMenu = Menu.buildFromTemplate([

{ label: 'Item 1' },

{ role: 'quit' }

])

function createTray() {

tray = new Tray('trayTemplate@2x.png')

tray.setToolTip('Tray details')

tray.on('click', e => {

if (e.shiftKey) {

app.quit()

} else {

mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()

}

})

tray.setContextMenu(trayMenu)

}

// Create a new BrowserWindow when `app` is ready

function createWindow () {

createTray()

mainWindow = new BrowserWindow({

width: 1000, height: 800,

webPreferences: { nodeIntegration: true }

})

// Load index.html into the new BrowserWindow

mainWindow.loadFile('index.html')

// Open DevTools - Remove for PRODUCTION!

mainWindow.webContents.openDevTools();

// Listen for window being closed

mainWindow.on('closed',  () => {

mainWindow = null

})

}

// Electron `app` is ready

app.on('ready', createWindow)

// Quit when all windows are closed - (Not macOS - Darwin)

app.on('window-all-closed', () => {

if (process.platform !== 'darwin') app.quit()

})

// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow

app.on('activate', () => {

if (mainWindow === null) createWindow()

})

powerMonitor (电源指示器)

// Modules

const electron = require('electron')

const {app, BrowserWindow} = electron

// Keep a global reference of the window object, if you don't, the window will

// be closed automatically when the JavaScript object is garbage collected.

let mainWindow

// Create a new BrowserWindow when `app` is ready

function createWindow () {

mainWindow = new BrowserWindow({

width: 1000, height: 800,

webPreferences: { nodeIntegration: true }

})

// Load index.html into the new BrowserWindow

mainWindow.loadFile('index.html')

// Open DevTools - Remove for PRODUCTION!

mainWindow.webContents.openDevTools();

// Listen for window being closed

mainWindow.on('closed',  () => {

mainWindow = null

})

electron.powerMonitor.on('resume', e => {

if(!mainWindow) createWindow()

})

electron.powerMonitor.on('suspend', e => {

console.log('Saving some data')

})

}

// Electron `app` is ready

app.on('ready', createWindow)

// Quit when all windows are closed - (Not macOS - Darwin)

app.on('window-all-closed', () => {

if (process.platform !== 'darwin') app.quit()

})

// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow

app.on('activate', () => {

if (mainWindow === null) createWindow()

})

相关文章

上一篇:千锋web前端培训分享Electron
下一篇:
  • 北京总部地址:北京市海淀区宝盛北里西区28号中关村智诚科创大厦4层
    北京沙河校区:北京市昌平区沙阳路18号北京科技职业技术学院广场服务楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 深圳校区地址:深圳市宝安区宝安大道5010号西部硅谷B座A区6层A605/B座C区1层108
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 上海校区地址:上海市宝山区同济支路199号智慧七立方3号楼2-4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 广州校区地址:广州市天河区元岗路200号慧通产业园B9三层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 郑州二七区校区地址:郑州市二七区航海中路60号海为科技园C区10层
    郑州高新区校区地址:郑州市高新区金梭路与银杏路交叉口教育科技产业园南门D座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 大连校区地址:辽宁省大连市高新园区爱贤街10号大连设计城A座901
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 武汉金融港校区地址:武汉市东湖高新技术开发区光谷大道77号金融港B18栋3楼
    武汉智慧园校区地址:武汉市东湖高新技术开发区光谷大道61号智慧园21栋2楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 成都校区地址:成都市高新区肖家河沿街138号肖家河大厦三楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 西安校区地址:西安市雁塔区高新六路52号立人科技C座西区4楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 杭州旺田校区:浙江省杭州市江干区九堡旺田书画城A座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 青岛校区地址:青岛市市北区龙城路31号卓越世纪中心4号楼5层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 重庆校区地址:重庆市高新区科园一路2号大西洋国际12-1
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 长沙校区地址:湖南省长沙市岳麓区麓谷企业广场A2栋三单元306号
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 哈尔滨校区地址:哈尔滨市松北区世泽路689号 科技创新城4号楼1101
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 南京校区地址:南京市建邺区应天大街780号弘辉产业园1栋2层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 太原校区地址:太原市小店区长治路230号能源互联网大厦6层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 沈阳校区地址:辽宁省沈阳市浑南区世纪路16号东大软件园B园B1座A201
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 合肥校区地址:合肥市包河区徽州大道396号东方广场B座12A
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、Adobe认证、PMP认证、红帽RHCE认证
  • 千锋教育服务号

    了解千锋动态
    关注千锋教育服务号

  • 千锋教育移动站

    扫一扫快速进入
    千锋移动端页面

  • 千锋互联服务号

    扫码匿名提建议
    直达CEO信箱

[an error occurred while processing the directive]