본문 바로가기
Electron

[기초-1] 일렉트론 메뉴 추가하기 / 다루기

by 으노으뇨 2023. 2. 24.
728x90
반응형
SMALL

안녕하세요 일렉트론 상단의 메뉴를 다루거나 추가하거나 없애는 방법에 대해 포스팅하겠습니다.

https://www.electronjs.org/docs/latest/api/menu

 

Menu | Electron

Create native application menus and context menus.

www.electronjs.org

일렉트론 공식사이트를 통해서 메뉴를 다루는 것을 참고하실 수 있습니다. 

기능들은 참 많은데 이번 포스팅에서는 간단하고 주로 쓸수 있을 것 같은 것들을 한번 실습해보려고합니다. 


기존 메뉴는 아무것도 설정하지 않았다면

 

처럼 일반적인 모습만 나옵니다.

메뉴를 사용하기 위해서는 메뉴라는 api를 사용해야합니다.

main.js에 메뉴를 추가합니다.

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

추가한 모습

이러면 이제 메뉴를 사용할 준비가 되어있습니다.

그리고 우리는 템플릿을 이용할 것이기에 템플릿을 선언하고 메뉴를 사용할 수있게합니다.

main.js에 아래 내용을 추가해줍니다.

/**
 * @values 메뉴선언부
*/
/*start*/
const template = []; 
const menu = Menu.buildFromTemplate(template); 
/*end*/
Menu.setApplicationMenu(menu);

이걸 저장하고 시작을 해본다면

깔끔하게 메뉴가 다 사라진것을 볼 수 있습니다.

디폴트 메뉴를 사용하지 않겠다는 것이고 , 결론적으로는 메뉴를 설정했는데 빈 배열을 템플릿으로 선언해서 없습니다.

이제 템플릿 배열에 하나 추가해보겠습니다.

const template = 
[
  { 
    label: "File"
  }
];

추가한 뒤 재시작을 한다면

메뉴가 생겼음을 확인하실수 있습니다.

만약 파일이라는 대 메뉴에서 서브메뉴를 만들고싶다면

  { 
    label: "File"
    /*아래는 새로 추가한 내용*/
    ,submenu: 
    [ 
      { 
        label: "Open" 
      }
    ] 
    /*서브메뉴 끝*/
  }

이렇게 추가하시면됩니다.

배열형식을 맞추어서 추가해줍니다.

이렇게 2개를 추가해보았습니다.

2개가 모두 나왔군요

룰 메뉴(Rule Menu)

일렉트론에는 기본적인 기능들을 api로 제공하고있습니다. 기본적인 기능들입니다. 그것을 룰이라고 합니다.

https://www.electronjs.org/docs/latest/api/menu-item#roles

 

Class: MenuItem | Electron

Add items to native application menus and context menus.

www.electronjs.org

사이트에 간다면 아래처럼 룰들이 쭉있습니다. 기본적으로 메뉴들에서 사용하는 것들이 정의 되어있습니다.

이중 개발자툴(웹 dev) 과 같은 기능을 한번 추가해 보겠습니다.

  ,  { 
    label: "Dev"
    ,submenu: 
    [ 
      { 
        role   : "toggleDevTools" 
      }
    ] 
  }

이렇게 대메뉴를 따로 만들고 서브메뉴로 만들었습니다. 한번 확인해보겠습니다.

새로 생긴 메뉴입니다.

실제로 개발자도구 화면을 볼 수 있습니다.

메뉴 클릭시 이벤트 처리

이제 우리가 메뉴를 만들었는데 그 메뉴가 동작하도록 하는 간단한 이벤트를 적용해 보겠습니다.

우선 적용대상은 파일 > Open 이라는 메뉴에 적용해 보겠습니다.

  { 
    label: "File"
    ,submenu: 
    [ 
      { 
        label   : "Open"
        , click : (ev)=>{ 
          console.log('Clicked Menu Open!!!');
        }
      }
      ,{ 
        label   : "New" 
      }
    ] 
  }

클릭시 이벤트를 적용한 모습
엥 왜 여기서 로그가 안나오지..?
형이 왜 여기서나와...

그래도 오픈 메뉴를 눌렀을때 클릭 이벤트 주는 것은 성공했습니다 

타입 메뉴(Type menu)

메뉴기능간 구분을 준다거나 서브메뉴라고 선언해준다거나 (separator, submenu) 등의 기능입니다.

또 다른 기능으로는 노말, 구분자, 라디오, 체크박스 등이 있습니다.

,{type : "separator"}

이렇게 쏙! 넣어주시면됩니다.

잘~~보면 줄이 그어져있습니다.

그리고 체크박스도 한번 사용해보겠습니다.

      ,{ 
        label: 'Dark Mode'
        , type: 'checkbox'
        , checked: true 
      }

추가해준다음 실행하면

아직은 아무 이벤트는 없지만 그래도 체크박스메뉴형태가 나타났습니다.

외부사이트 열기

메뉴를 눌렀을때 외부 사이트를 호출하는 것입니다. 주로 도움말이나 자세히. 뭐 라이센스 보기 등에 활용할 수 있습니다.

우선 electron에 shell 을 추가해줍니다.

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

추가한 모습

이제 새로운 메뉴를 만들어서 도움말 기능처럼 만들어보겠습니다.

,  { 
    label: "Help"
    ,submenu: 
    [ 
      { 
        label   : "Api" 
        , click : (ev)=>{ 
          shell.openExternal("https://www.electronjs.org/docs/latest/api/app");
        }
      }
    ] 
  }

메뉴추가하는 소스

Dev 라는 메뉴 옆에 Help라는 대메뉴를 하나더 생성하고 하위메뉴로 Api를 추가했습니다.

해당 메뉴는 외부사이트를 열어줍니다.

추가로 아래는 공식 사이트에서 예제 소스입니다.

이렇게 쓸수 있구나 하고 적용해보셔도 됩니다. 이상입니다.

const template = [
  // { role: 'appMenu' }
  ...(isMac ? [{
    label: app.name,
    submenu: [
      { role: 'about' },
      { type: 'separator' },
      { role: 'services' },
      { type: 'separator' },
      { role: 'hide' },
      { role: 'hideOthers' },
      { role: 'unhide' },
      { type: 'separator' },
      { role: 'quit' }
    ]
  }] : []),
  // { role: 'fileMenu' }
  {
    label: 'File',
    submenu: [
      isMac ? { role: 'close' } : { role: 'quit' }
    ]
  },
  // { role: 'editMenu' }
  {
    label: 'Edit',
    submenu: [
      { role: 'undo' },
      { role: 'redo' },
      { type: 'separator' },
      { role: 'cut' },
      { role: 'copy' },
      { role: 'paste' },
      ...(isMac ? [
        { role: 'pasteAndMatchStyle' },
        { role: 'delete' },
        { role: 'selectAll' },
        { type: 'separator' },
        {
          label: 'Speech',
          submenu: [
            { role: 'startSpeaking' },
            { role: 'stopSpeaking' }
          ]
        }
      ] : [
        { role: 'delete' },
        { type: 'separator' },
        { role: 'selectAll' }
      ])
    ]
  },
  // { role: 'viewMenu' }
  {
    label: 'View',
    submenu: [
      { role: 'reload' },
      { role: 'forceReload' },
      { role: 'toggleDevTools' },
      { type: 'separator' },
      { role: 'resetZoom' },
      { role: 'zoomIn' },
      { role: 'zoomOut' },
      { type: 'separator' },
      { role: 'togglefullscreen' }
    ]
  },
  // { role: 'windowMenu' }
  {
    label: 'Window',
    submenu: [
      { role: 'minimize' },
      { role: 'zoom' },
      ...(isMac ? [
        { type: 'separator' },
        { role: 'front' },
        { type: 'separator' },
        { role: 'window' }
      ] : [
        { role: 'close' }
      ])
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click: async () => {
          const { shell } = require('electron')
          await shell.openExternal('https://electronjs.org')
        }
      }
    ]
  }
]
728x90
반응형
LIST

댓글