아티클

NVDA 추가 기능 개발 가이드라인 2부

2018-08-27 15:16:58

 

 

 

안녕하세요. 엔비전스입니다.

이번 글에서는 NVDA 추가 기능의 기본 구성 요소 및 글로벌 플러그인, 앱 모듈의 간단한 예제를 살펴보겠습니다.

들어가기 전에

  • 1부에서 언급한 바와 같이 아티클 전반에서는 NVDA의 추가 기능 패키지(*.nvda-addon)를 사용하지 않으며, NVDA 사용자 환경 폴더 내 appModule, globalPlugins 폴더에 작업물을 저장합니다. 추가 기능 패키지(*.nvda-addon)를 제작하는 방법은 추후 다룰 예정입니다. NVDA 사용자 환경 폴더를 여는 방법은 NVDA 추가 기능 개발 가이드라인 1부 <추가 기능이 저장된 폴더 열기> 섹션을 참고합니다.
  • NVDA는 Python 언어로 추가 기능을 제작할 수 있습니다. 2부에서 사용한 NVDA에 내장된 클래스, 메소드 왜 Python 언어의 문법, 튜토리얼 등의 자세한 내용은 Python 공식 문서 웹사이트 https://docs.python.org/ko/2.7/를 참고하세요.
  • NVDA는 Python 언어로 추가 기능을 제작할 수 있습니다. 2부에서 사용한 NVDA에 내장된 클래스, 메소드 왜 Python 언어의 문법, 튜토리얼 등의 자세한 내용은 Python 공식 문서 웹사이트 https://docs.python.org/ko/2.7/를 참고하세요.
  • NVDA에 기본으로 포함된 추가 기능을 위한 모듈에 대해서는 NVDA 추가 기능 모듈 문서를 통해 내장 모듈, 클래스 및 메소드에 대한 설명을 확인할 수 있습니다.

추가 기능 코드의 구성

추가 기능 코드는 하나 이상의 Python 파일 (.py 파일)에 저장됩니다. 이는, 앱 모듈, 글로벌 플러그인 등 NVDA의 모든 추가 기능에 공통으로 적용됩니다. 추가 기능 코드는 다음과 같이 구성됩니다:
  1. 추가 기능 작성 시 먼저 추가 기능에 대한 선택적인 머리글 (예 : 추가 기능의 이름 및 추가 기능의 간단한 설명 등)을 작성하는 것으로 시작합니다. 이 부분은 선택 사항이지만, 추가 기능의 역할, 용도를 아는 데 도움이 되므로 작성하는 것이 좋습니다.
  2. 다음으로, 추가 기능 파일에 필요한 모듈을 NVDA에 알려줍니다. 이 작업은 <import module>을 작성하여 수행됩니다. 여기서 module은 코드에서 사용할 모듈의 이름입니다. 예를 들어, 추가 기능을 사용하는 동안 비프음을 재생하기 위해서는 import tones 구문을 작성합니다. 일반적으로 특정 추가 기능에 대해 두 개 이상의 모듈을 사용해야 할 수도 있습니다. 추가 기능에서 사용할 수 있는 여러 모듈에 대해서는 다음 글에서 자세히 설명합니다.
  3. 필요한 모듈을 선언한 후, 추가 기능 코드 (클래스, 변수, 메소드) 등을 작성합니다. 가장 중요한 섹션은 코드를 할당할 추가 기능 모듈 유형을 결정하는 추가 기능 클래스 코드입니다. 세 예제를 통해 추가 기능 클래스에 대해 간단히 살펴보겠습니다.
  4. 클래스를 선언한 다음 추가 기능에 필요한 코드를 작성합니다. 추가 기능 작성 시 Python 공식 문서, 외부 모듈을 사용한다면 모듈 문서를 참고합니다.
  5. 추가 기능을 실행하려면, NVDA 추가 기능 개발 가이드라인 1부 내 <추가 기능 폴더 열기> 섹션을 참고하여 추가 기능 폴더를 연 다음 .py 파일을 appModules 또는 globalPlugins 폴더에 붙여 넣습니다.

추가 기능 첫 번째 예제: 단축키를 눌러 음성 메시지 출력하기

세 섹션에 걸쳐 NVDA 추가 기능의 간단한 예제를 살펴보겠습니다. 첫 번째 예제는 NVDA +Shift+A를 누르면 모든 프로그램에서 <안녕하세요. NVDA 추가 기능 개발 가이드라인의 첫 번째 예제입니다.>가 음성 출력되는 예제입니다. 프로그램과 관계없이 어디에서나 실행되어야 하므로, 글로벌 플러그인으로 작성해야 합니다.
아래 코드는 첫 번째 예제 코드입니다. 파일을 내려받아 테스트하거나, 아래 코드를 복사하여 붙여 넣은 후 <example1GlobalPlugin.py> 로 저장합니다. 추가 기능 파일 이름은 추가 기능의 역할을 유추할 수 있는 이름으로 지정하는 것이 좋습니다. 첫 번째 예제 다운로드
<code start>
# -*- coding: utf-8 -*-
# NVDA 추가 기능 개발: 첫 번째 예제
# 이 예제는 NVDA+a 키를 누를 때마다 1초 동안 비프음을 울립니다. 이 예제는 특정 프로그램에 국한되지 않고, NVDA가 실행된 상태에서 어디에서나 사용할 수 있습니다.
# 제작자: a11yTester(a11yTester@example.com)

import globalPluginHandler # 글로벌 플러그인을 제작하기 위한 필수 모듈
import ui # 음성 또는 점자로 메시지 출력을 위한 모듈

class GlobalPlugin(globalPluginHandler.GlobalPlugin): # 글로벌 플러그인 제작을 위해 GlobalPlugin class 정의

    def script_outputMessage(self, gesture): # NVDA+Shift+A 키를 누르면 음성 메시지가 출력되는 함수
        ui.message(u'안녕하세요. NVDA 추가 기능 개발 가이드라인의 첫 번째 예제입니다.') # ui.message 메소드로 음성 및 점자로 메시지 출력
    __gestures = { # 추가 기능에 대한 단축키를 할당하기 위해 Python의 사전형으로 정의
        "kb:NVDA+shift+A":"outputMessage" # NVDA+Shift+A 키에 기능을 할당합니다
        }

</code end>

첫 번째 예제에 대한 코드 설명

첫 번째 예제를 자세히 살펴보겠습니다.
  1. 파일의 첫 번째, 두 번째 줄에는 추가 기능의 명칭 및 제작자 정보로 추가 기능 예제임을 명확히 알려 NVDA 추가 기능 관련 파일임을 명시했습니다. 추가 기능의 라이선스 등과 같은 중요 정보를 추가할 수도 있습니다.
  2. 이 예제는 글로벌 플러그인이므로 import globalPluginHandler 구문을 통해 글로벌 플러그인 작성을 위한 모듈을 불러왔습니다.
  3. import ui 구문을 작성하여 NVDA의 내장된 음성이나 점자로 메시지를 출력하기 위한 모듈을 불러왔습니다. 주어진 모듈의 메소드를 사용하고자 할 때 필요한 모듈을 import 구문을 통해 불러올 수 있습니다.
  4. 글로벌 플러그인을 작성하기 위한 <GlobalPlugin이>라는 클래스를 정의했습니다. 괄호 안의 텍스트는 이 클래스가 어디에서 왔는지 알려줍니다.
  5. 클래스 내 script_outputMessage 메소드는 단축키를 누를 때 실행되는 메소드입니다. 이 스크립트에서 메시지가 음성으로 출력되도록 NVDA에 알리기 위해 ui.message(u'안녕하세요. NVDA 추가 기능 개발 가이드라인의 첫 번째 예제입니다.')를 작성했습니다.
  6. 마지막으로 outputMessage 스크립트에 단축키를 NVDA+Shift+A에 할당하기 위해 __gestures 블록에 "kb:NVDA+A":"outputMessage"를 작성했습니다. __gestures 블록에는 스크립트에 대한 단축키 또는 터치 명령을 할당하며, Python의 사전형으로 정의합니다.

파일을 저장하고 NVDA를 다시 시작하거나, NVDA+Control+F3 키를 눌러 플러그인을 새로 고칩니다. 이제 NVDA +Shift+A를 누를 때마다 <안녕하세요. NVDA 추가 기능 개발 가이드라인의 첫 번째 예제입니다.>가 음성으로 출력됩니다.

참고

Python에서는 해시 기호(#)를 라인의 첫 번째 칸에 삽입하여 해당 라인을 주석으로 처리되도록 할 수 있습니다. 주석은 코드에 대한 부가적인 설명 등에 사용되어 코드를 작성하지 않은 제3자가 코드를 이해할 수 있도록 하는 등 여러 면에서 유용합니다.

추가 기능을 처음 작성하는 사용자를 위한 팁

처음 NVDA 추가 기능을 개발하거나 추가 기능 개발이 익숙하지 않다면, 다음의 추가 기능 작성을 위한 일반적인 팁을 참고합니다:
  1. 추가 기능을 개발할 때, 한 번에 한 가지 기능을 작성하고 테스트합니다. 예를 들어, 특정 단축키를 누를 때마다 각기 다른 기능(음성 메시지 출력 또는 브라우저 주소 열기 등)과 같이 여러 기능을 개발하려 한다면, 한 가지 기능을 먼저 개발한 후 테스트하는 것이 좋습니다.
  2. 응용 프로그램을 위한 앱 모듈을 작성하려면, 응용 프로그램의 설명서 및 사용법을 충분히 익혀야 합니다.
  3. 추가 기능에서 사용될 단축키를 정의할 때 NVDA의 기본 단축키와 충돌하지 않도록 NVDA의 설명서를 참조하여 확인합니다.

두 번째 예제: 이벤트가 발생할 때 비프음 재생하기

두 번째 예제는 특정 컨트롤에 초점을 이동하거나, 체크 상자를 선택 또는 해제하는 것과 같은 상황에서 이벤트가 발생할 때 비프음이 재생되는 예제입니다. 이벤트와 같은 중요 개념에 대해서는 3부에서 자세히 다룹니다. 다음 예제를 복사하여 <exampleGlobalPlugin.py> 과 같은 파일 이름으로 저장하거나, 파일을 내려받아 테스트합니다. 두 번째 예제 다운로드
<code start>
# -*- coding: utf-8 -*-
# NVDA 추가 기능 개발: 두 번째 예제
# 이 예제는 <네이버> 링크에 초점이 위치하거나 벗어날 때 다른 비프음을 출력합니다. 이 예제는 응용 프로그램에 관계없이 어디에서나 실행할 수 있습니다

import api # 플러그인 작성에 필요한 기본 API 모듈

 

import controlTypes # 체크 상자, 링크와 같은 컨트롤을 처리하기 위한 모듈
import globalPluginHandler # 글로벌 플러그인을 제작하기 위한 필수 모듈
import tones # 비프음을 재생하기 위한 모듈

class GlobalPlugin(globalPluginHandler.GlobalPlugin): # 글로벌 플러그인 제작을 위해 GlobalPlugin class 정의

    def event_gainFocus (self, obj, nextHandler): # 특정 컨트롤에 초점을 이동하면 발생하는 gainFocus 이벤트를 처리하기 위한 함수
        obj = api.getFocusObject() # api 모듈의 초점을 받은 객체를 얻기 위한 함수
        if (obj.name == u'네이버' and obj.role == controlTypes.ROLE_LINK): # 콘트롤의 이름이 네이버이고, 역할이 링크인 요소일 때 기능 실행
            tones.beep(440,100) # 440Hz의 비프음 재생
        nextHandler() # 비프음 재생 후 NVDA가 음성 출력 등과 같은 다음 기능이 처리될 수 있도록 함

    def event_loseFocus(self, obj, nextHandler): # 특정 컨트롤에서 초점을 잃었을 때 발생하는 loseFocus 이벤트를 처리하기 위한 함수
        obj = api.getFocusObject() # API 모듈에서 현재 초점을 받은 객체를 얻기 위한 함수
        if (obj.name == u'네이버' and obj.role == controlTypes.ROLE_LINK): # 컨트롤의 이름이 네이버이고, 역할이 링크인 요소일 때 기능 실행
            tones.beep(880, 100) # 880Hz의 비프음 재생 
        nextHandler() # 비프음 재생 후 NVDA가 음성 출력 등과 같은 다음 기능이 처리될 수 있도록 함

</code end>

두 번째 예제에 대한 코드 설명

  1. 파일의 첫 번째, 두 번째 줄에는 추가 기능에 대한 헤더를 작성하여 추가 기능이 어떤 역할 및 기능을 하는지 작성했습니다.
  2. 두 번째 예제도 글로벌 플러그인이므로 import globalPluginHandler 구문을 통해 글로벌 플러그인 작성을 위한 모듈을 불러왔습니다.
  3. import 구문을 통해 현재 초점이 있는 객체, 클립보드 복사와 같은 일반적인 함수가 정의된 api, 체크 상자, 라디오 버튼과 같은 컨트롤과 상호 작용을 위한 controlTypes, 비프음을 재생하기 위한 tones 모듈을 불러왔습니다.
  4. 글로벌 플러그인을 작성하기 위해 GlobalPlugin 클래스를 정의했습니다.
  5. 클래스 내 event_gainFocus, event_loseFocus 메소드를 통해 <네이버> 링크에 초점을 이동하거나 초점을 벗어났을 때 비프음이 재생되도록 처리합니다.

세 번째 예제: 특정 응용 프로그램에서 NVDA를 일시 중지하기

마지막으로 살펴볼 예제는, Firefox 웹 브라우저에서 NVDA가 일시 중지되도록 하는 예제입니다. Firefox 웹 브라우저에 초점을 위치하면, NVDA가 일시 중지되며, Firefox 웹 브라우저에서 초점을 벗어나기 전까지 NVDA는 음성 또는 점자 지원을 처리하지 않습니다. 키보드 명령 또한 NVDA에서 처리하지 않으며 응용 프로그램에 직접 전달됩니다. 다음 코드를 <firefox.py> 로 저장하여 NVDA 사용자 환경 폴더 내appModules 폴더에 저장합니다. 세 번째 예제 다운로드
<code start>
# NVDA 추가 기능 개발: 세 번째 예제
# 이 예제는 Firefox 웹 브라우저에서 NVDA가 일시 중지되도록 합니다. 이 예제는 Firefox 웹 브라우저에서만 작동합니다
# 제작자: a11yTester(a11yTester@example.com)

import appModuleHandler # APPModule을 작성하기 위한 필수 모듈

class AppModule(appModuleHandler.AppModule): # APPModule을 작성하기 위한 class 정의
    sleepMode = True # sleepMode 변수를 true로 설정하여 NVDA가 일시 중지되도록 처리
</code end>

세 번째 예제에 대한 코드 설명

세 번째 예제는 두 예제와 달리 Firefox 웹 브라우저만을 대상으로 작동하는 앱 모듈입니다. Firefox 웹 브라우저로 초점을 이동하면 NVDA가 일시 중지됩니다. 세 번째 예제의 자세한 코드 설명은 다음과 같습니다:
  1. 파일의 첫 번째, 두 번째 줄은 두 예제와 같이 추가 기능의 기본적인 정보 및 제작자 정보를 명시하였습니다.
  2. 세 번째 예제는 Firefox 웹 브라우저 응용 프로그램만을 대상으로 하여 작동하므로, 앱 모듈 제작 시 필수적으로 요구되는 appModuleHandler 모듈을 불러왔습니다.
  3. 앱 모듈 작성을 위해 AppModule class를 정의했습니다.
  4. appModuleHandler.AppModule에 정의된 sleepMode 변수를 true로 설정하여 Firefox 웹 브라우저에서 NVDA가 작동하지 않도록 처리했습니다.

참고

앱 모듈은 해당 응용 프로그램의 이름과 정확히 일치하는 파일 이름으로 저장해야 합니다. 예를 들어, Chrome 웹 브라우저를 위한 추가 기능을 작성했다면 <chrome.py> 과 같이 저장해야 해당 프로그램에서 앱 모듈이 작동합니다.

2부에서 사용된 NVDA 내장 모듈 목록

다음은 이번 글에서 사용된 NVDA 내장 모듈 목록입니다. 해당 모듈에 대한 자세한 클래스 및 메소드 사용법에 대해서는 모듈별로 제공된 링크를 통해 확인할 수 있습니다.
  • api: 현재 초점을 받은 객체 및 클립보드 복사 기능과 같은 일반적인 함수가 정의된 모듈
  • appModuleHandler: 앱 모듈 제작 시 필수적으로 필요한 모듈
  • controlTypes: 체크 상자, 라디오 버튼과 같은 컨트롤과의 상호 작용을 처리하기 위한 모듈
  • globalPluginHandler: 글로벌 플러그인을 제작하기 위한 필수 모듈
  • tones: 비프음 재생을 위한 모듈
  • ui: 음성 및 점자로 사용자에게 메시지를 출력하기 위한 용도로 사용되며, 예제 1에서 음성 출력을 위해 사용

3부에서는 NVDA에 기본으로 내장된 유용한 모듈 및 메소드를 살펴보고, 추가 기능 제작 시 알아야 할 이벤트, 스크립트와 같은 주요 개념에 대해 살펴보겠습니다.

 


 

 

 

댓글 0
댓글을 작성하려면 해주세요.