初心者向き!electron で簡単なメモ帳をつくってみよう

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、前回と前々回ではこのブログでよく話題にするLaravelVueではなく、久しぶりにPythonを扱ってみました。

これは複数のプログラミング言語を触ったことがある人ならよく感じると思うのですが、やはり各プログラミング言語には特徴があって、その特徴の中には他のプログラミング言語でも有効に利用できる考え方だったり、実装方法があったりするものです。

そこで、今回はこちらも少しの間コーディングからは離れてしまっているelectron関連の話題をチョイスしてみました。(といっても、実際はJavaScript, CSS, HTMLなんですが ^^;)

ということで、今回はこのelectronを使って独自のメモ帳をつくってみます。

electronは基本的にはWindows, Mac OS, Linuxどの環境でも動く上に、ウェブの技術がそのまま使えるので、用途は多いんじゃないでしょうか。

ぜひ学習者さんは参考にしてみてくださいね。(最後に教材ソースコードをダウンロードできます。)

開発環境: Ubuntu 18.04、electron-v8.1.1(Windowsでもgitとnodeがあれば開発可能です)

【追記:2020.3.17】この記事は過去バージョンの内容に加筆修正したものです。

インストール

electronのインストール

electronでは初期状態で必要なファイルを全て自分で用意する必要はなく、electron-quick-startのコードをgitを使ってcloneするだけでOKです。

では、ソースコードを保存したいフォルダへ移動して以下のgitコマンドを実行しましょう。

git clone https://github.com/electron/electron-quick-start

すると、フォルダ内には「electron-quick-start」というフォルダが作成されます。

では、今回はメモ帳をつくるので、フォルダ名をmy-memoへ変更しましょう。

では次にmy-memoの中へ移動して次のnpmコマンドを実行します。

npm install

これでelectron開発必要なファイルは全て揃いました。

とりあえずこの状態で起動できるかどうかをテストしてみます。次のコマンドを実行してください。

npm start

次のようなウィンドウが表示されたら成功です。

electronの設定

では、実際に自分だけのメモ帳を開発する前に、electronアプリの主要な設定方法をまとめておきましたので、お好きなものを設定してみてください。(必要ない場合は次まで読み飛ばしてください)

変更するのはmain.jsにある、new BrowserWindow()のオプション値です。

ウィンドウの初期サイズ

main.js

mainWindow = new BrowserWindow({width: 800, height: 600})

ウィンドウ位置

起動した時にウィンドウが開く位置です。

main.js

mainWindow = new BrowserWindow({
  width: 800,
  height: 800,
  x: 100,
  y: 100
})

メニューバーを隠す

main.js

mainWindow = new BrowserWindow({
  width: 800,
  height: 800,
  autoHideMenuBar: true
})

アイコンを変更する

まず、assets/imagesなど適当なフォルダをつくり、アイコン画像を保存します。

そして、BrowserWindow内でアイコンへのパスを指定します。

main.js

mainWindow = new BrowserWindow({
  width: 800,
  height: 800,
  icon: __dirname +'/assets/images/icon_64x64.png'
})

タイトルバーの名前を変更する

これは各HTMLの<title>〜</title>を変更するだけでOKです。初期状態で呼び出されるのはindex.htmlなのでこのファイルを次のように変更しましょう。
index.html

<title>私のメモ帳(^^)</title>

ちなみに以下のようにデフォルトのタイトルを指定しておくと<title>タグが見つからない場合はそちらが表示されます。

main.js

mainWindow = new BrowserWindow({
  title: 'デフォルトのタイトル'
})

Uncaught ReferenceError: require is not definedとエラーが出る場合

【追記:2020.3.17】訪問ユーザー様からご質問をいただいて、追記しました。皆さん、いつもありがとうございます。😊✨

Electronは、v5以降では初期状態でrequire()が使えないようになっています。

そのため、もしrequie is not definedとエラーが出た場合は、次のように設定を変更してみてください。

main.js

const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
        nodeIntegration: true // 👈ここ
    }
})

【注意】
ただし!nodeIntegrationtrueにしたアプリ内でインターネット上のサイトを開く場合、注意が必要です。なぜなら、ブラウザがnode.jsの機能を使えるようになる(つまり、ファイルの操作などができるようになる)ため、危険です。

では、このクイックスタート・アプリを使って次の項目から実際に開発をしていきましょう!

メモ帳をつくる

JS、CSSフレームワークをインストール

いつものようにcdnでJSを読み込む方法でもいいのですが、デスクトップアプリなので今回はJS、CSSフレームワークはnpmでインストールして使うことにします。

ということで、次のコマンドでbootstrapvueをインストールしてください。

npm install bootstrap --save
npm install vue --save

そして、次のようにして読み込みます。

index.html

<html>
  <head>
    <!-- 省略 -->
    <link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
  </head>
  <body>

    <!-- 省略 -->

    <script src="node_modules/vue/dist/vue.min.js"></script>
  </body>
</html>

※ 今回bootstrapはCSSのみ使います。

レイアウトを作る

では続いて、メモ帳のレイアウトを決めましょう。

index.html

<textarea style="height:500px;width:100%;display:block;padding:10px;"></textarea>

<div style="position:fixed;bottom:0;width:100%;padding:10px;">
    <button class="btn btn-secondary float-right">保存する</button>
    <div style="opacity:0.7;"></div>
</div>

簡単にテキストエリアとボタンがあるだけです。
実行の画像です。

テキストファイルを保存する部分を作る

では、JavaScriptで入力された文章をファイルに保存するコードを見ていきましょう。

まずは、Vueが利用できるようにidをつけて<script>〜</script>内に基本コードを追加します。

<div id="app">

    <!-- 省略 -->

</div>
<script>
  new Vue({
    el: '#app'
  })
</script>

次に、入力した値にVueからアクセスできるよう、次のデータ変数をバインディングします。

  • inputText ・・・ 入力されたテキスト
  • resultMessage ・・・ 保存した時の結果メッセージ
<textarea v-model="inputText" style="height:500px;width:100%;display:block;padding:10px;"></textarea>

<!-- 省略 -->

<div v-text="resultMessage" style="opacity:0.7;"></div>
new Vue({
  el: '#app',
  data: {
    inputText: '',
    resultMessage: ''
  }
})

続いて、「保存する」ボタンをクリックした時のイベントを作っていきましょう。
まず、ボタンにイベントを追加してsaveText()を実行できるようにします。

<button class="btn btn-secondary" @click="saveText()">保存する</button>

続いてsaveText()本体ですが、この中でファイル操作とダイアログのモジュールを使うので、先に読み込んでおきます。

const fs = require('fs')
const dialog = require('electron').remote.dialog

そして、保存メソッドです。

methods: {
    saveText() {

        dialog.showSaveDialog(null, (path) => {

            if (path != undefined) {

                try {

                    fs.writeFileSync(path, this.inputText)
                    this.resultMessage = '保存が完了しました♪'

                } catch (e) {

                    this.resultMessage = '予期せぬエラーによりファイル保存に失敗しました・・・'

                }

            }

        })

    }

}

まず、showSaveDialog()で保存ダイアログを開きます。

そして、もしファイル名を入力して保存が実行されると、ファイルを保存する以下のコードが実行されます。

fs.writeFileSync(path, this.inputText)
this.resultMessage = '保存が完了しました♪'

なお、フォルダに書き込み権限がない等の場合はエラーになりますので、catchの中が実行されます。

catch(e) {

    this.resultMessage = '予期せぬエラーによりファイル保存に失敗しました・・・'

}

テストしてみる

では、実際にテキストを保存してみましょう。

まずは、メモ帳に何列か「テストの文章です。」と入力します。

保存ボタンをクリックすると、ダイアログが表示されます。

今回はtest.txtという名前で保存します。

完了メッセージが表示されました。

うまくファイルが保存できています。中身を別のテキストエディタで確認してみましょう。

中身もうまく保存することができています!

ファイルを読み込む機能をつくる

JavaScriptコードをつくる

ファイルを書き込む機能は完成しましたので、次はすでにあるテキストファイルを選んで内容を表示する機能をつくってみましょう。

では、保存ボタンの横に「開く」ボタンをつくってopenFile()が実行できるようにクリックイベントを設定します。

<button class="btn btn-secondary" @click="openFile()">開く</button>

openFile()メソッドの本体です。

methods: {

  // 省略

  openFile() {

    const options = {
        multiSelections: false
    };
    dialog.showOpenDialog(null, options, (paths) => {

        if(paths != undefined) {

            const path = paths[0]
            this.inputText = fs.readFileSync(path, {encoding: 'utf8'})

        }

    })

  }
}

先ほどのshowSaveDialog()と同じようにshowOpenDialog()でファイルを選択するダイアログを開きます。

※ 選択されるファイルが複数あっては困るので、オプションでmultiSelectionsfalseにしています。

そして、ファイルが選択されたらpaths(オプションで指定しても配列)に情報が入ってくるので、ファイルを読み込んで入力テキストの変数inputTextへ格納するようにしています。

なお、readFileSync()は初期状態では文字列ではなくbufferが返ってきます。そのため、encodingを指定しておく必要があります。

また、ファイルの選択がキャンセルされた場合はpathsundefinedになります。

テストしてみる

では、先ほど保存した「テスト文章です。」のファイルを読み込んでみましょう。

まずは、入力テキストは何も表示されていません。
開くボタンをクリックしてみましょう。

ファイルの一覧が表示されますので、「test.txt」を選択します。

すると先ほど保存した内容が表示されました。成功です!

配布できるようパッケージ化する

electronのソースコードをパッケージ化して配布できる形にするにはelectron-packagerというパッケージを使うと便利です。

まずはnpmのグローバル環境にインストールします。

npm install electron-packager -g

次にmy-memoのひとつ上の階層へ移動して以下のコマンドを実行します。

electron-packager ./my-memo my-memo --platform=all

パラメータの意味は、

  1. electronソースコードがあるフォルダ
  2. アプリケーション名
  3. 対応するプラットフォーム(OS)。allは全てに対応します。

実行が完了すると、次のようなフォルダが作られます。

左から、WindowsOS XMac App Store、そしてLinuxです。

では、私の開発環境はUbuntuなのでLinuxで実行してみます。my-memo-linux-x64へ移動して次のコマンドを実行します。

./my-memo

うまく表示できました!

ソースコードをダウンロードする

今回実際に開発した教材コードを以下からダウンロードすることができます。

※ ただし、アイコン、main.jsは自分で用意してください。

electron: 簡単なメモ帳をつくるソースコード

 

このエントリーをはてなブックマークに追加       follow us in feedly  
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ