Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Electronで任意のファイルを開く機能を実装する

More than 1 year has passed since last update.

ユーザーの視点からファイルを開く方法を考えると、3つの方法があると思います。

1.Menu,ショートカットキーでファイル選択ダイアログを開いてファイルを選択する
2.開きたいファイルをWindowにドラッグ&ドロップする
3.ファイルをダブルクリックしてElectronアプリで開く

この記事では1の"Menu,ショートカットキーでファイル選択ダイアログを開いてファイルを選択する"機能の実装方法について説明します。

自分の環境はこの記事を参照。UIの作成にReactを使っています。

情報が正しくなかったり、もっとスマートな実装方法があったりするかもしれませんがあしからず。

1.成果物

a.gif

2実装方法

Menudialogは基本的にメインプロセスでしか取扱えないらしいです。なのでメインプロセスでMenuの作成とdialogを表示する処理を行います。そしてdialogを表示したあとにレンダラープロセスにイベントを飛ばします。

メインプロセスとかレンダラープロセスとか何ぞ?という方はこちら

main.js
const { Menu, dialog } = require('electron')

// メニューの作成
function createMenu() {
  const template = [
    {
      label: 'Electron',
      submenu: [
        {
          label: 'about'
        }
      ]
    },
    {
      label: 'File',
      submenu: [
        {
          label: 'Open..',
          accelerator: 'CmdOrCtrl+O', // ショートカットキーを設定
          click: () => { openFile() } // 実行される関数
        }
      ]
    }
  ]
  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu);
}

// ファイル選択ダイアログを開く
function openFile() {
  dialog.showOpenDialog({ properties: ['openFile'] }, (filePath) => {

    // レンダラープロセスにイベントを飛ばす
    mainWindow.webContents.send('open_file', filePath);
  })
}

// 未検証だけどMenuを作成するタイミングは別にここじゃなくても良い気がする。
app.on('ready', createMenu)

そしてレンダラープロセス側でイベントを受け取る。

App.js
import '../assets/css/App.css'
import React, { Component } from 'react'

const { remote, ipcRenderer } = require('electron')
const { Menu, MenuItem } = remote

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = { path: '' }

    this.init();
  }

  init() {
    this.setup();
  }

  setup() {

    // イベントを受け取る
    ipcRenderer.on('open_file', (event, arg) => {

      // ファイルパスからファイル名を抜き取る
      let filePath = arg[0];
      filePath = filePath.split('\\'); 
      const fileName = filePath[filePath.length - 1];
      console.log(fileName);

      // Stateの更新
      this.setState({ path: fileName });
    })
  }

  render() {
    return (
      <div>
        <h1>Hello, Electron!</h1>
        <p>{this.state.path}</p>
      </div>
    )
  }
}

export default App


ファイルじゃなくてフォルダを選択させたい場合

  dialog.showOpenDialog({ properties: ['openDirectory'] }, (filePath) => {
       mainWindow.webContents.send('open_file', filePath);
  })

いろいろ設定できるみたいなので公式のドキュメントを参照してください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away