페이지

2016년 3월 18일 금요일

pvdevelop 프로젝트 -UI 편집 방법 - lineEdit 위젯 사용법

오늘은 라인에디트 위젯 사용법에 대해 알아 보죠.

GUI 화면의 자세한 노가다 방법은 빼고, 그림 1과 같은 GUI 화면을 만들어 주시기 바랍니다.

그림 1.Mask2 GUI 화면
그림 1은 4개의 라벨 위젯과 1개의 라인에디터 위젯, 2개의 푸쉬버튼 위젯을 이용하여 만들어진 GUI 화면이다. 아래와 같이 지정되어 있다. 외관 및 형태는 원하는 데로 지정하시기 바랍니다.

위젯위젯 이름텍스트
Labellb_01ITEM_TEXT
Labellb_02INPUT_TEXT
Labellb_03Real Time
Labellb_10-
LineEditle_textinput text
PushButtonpb_ChangeCHANGE
PushButtonpb_HomeHOME

라인에디트 위젯을 설명하기 위해 위젯을 7개나 동원하다니 좀 과한가?

라인에디트는 한 줄의 텍스트를 입력 받기 위해 사용되는 위젯입니다.

위젯을 다 편집하였다면 에디터 모드에서 Action->start server를 눌러 컴파일 후 서버를 실행시키자.
그림 2. 처음 실행화면


GUI 화면에 처음 접속하면 그림 2와 같은 화면이 나타날 것이다. 라인에디터에 입력된 내용을 지운 후 그림 3과 같이 숫자를 입력해보자.

그림 3. 라이에디터 숫자 입력

라인에디터에 문자를 입력하면... 원하는 문자가 입력된다. (한글도 입력된다...OTL...) 아직까지는 좋은 출발입니다.


그림 4.서버 도스창 출력 메시지.
이제 서버 출력 메시지를 확인해 보자 그림 4와 같은 메시지가 출력되어 있을 것이다.
키도드 입력과 관련하여 관심을 가져야 할 메시지는 뭘까? 간단히 말하면 다음의 두가지...
  • KEYBOARD_EVENT modifier=4 key=********
    backspace와 같은 키를 눌렀을 때 발생한다.
  • TEXT_EVENT id=3 1
    숫자나 문자를 입력하면 발생한다.
출력 메시지를 보면 숫자를 1 ~ 0까지 입력할 때, 1개의 문자가 들어갈 때 마다 TEXT_EVENT 가 발생하면서 이벤트가 발생한 위젯 번호와 라인에디터에 현재 입력된 내용을 보여주고 있는 것을 알 수 있다. 이 이벤트를 이용하면 입력된 내용을 실시간으로 반영할 수 있습니다.

자, 그럼 slots 에 있는 slotTextEvent를 살펴봅시다.



아주 간단합니다. 입력된 텍스트를 넘겨주기 위한 const char *text 인자가 있습니다. 이 것을 이용하면 아주 쉽게 실시간으로 입력되는 텍스트를 이용할 수 있습니다.
자. 그럼 입력되는 내용이 실시간으로 반영되도록 코드를 넣어봅시다.



If (id == le_text) pvSetText(p, lb_03, text);

단 한줄의 코드만 입력되었습니다. 에디터 모드에서 start_server후 pvbrowser에서 확인해 보았습니다. 라인에디터 내용이 lb_03 라벨 위젯에 바로 반영이 됩니다. 지금까지는 아주 아주 간단합니다.

그림 5. 실시간 반영 테스트 화면
실시간 입력값이 반영되는 것이 중요할 때도 있지만, 중요 설정값 같은 것을 받아 들일 때, 이값이 실시간으로 반영되면 문제가 발생할 수 도 있습니다.

한번 생각해 보죠.현재 설정값이 50입니다. 설정값을 100으로 고치기 위해 50앞에 1을 넣어주면 150이라는 값이 바로 반영됩니다. 반대로 5를 1로 고치면 실시간 입력값이 0 이 되었다가 10 이 됩니다. 실시간 설정갑을 바로 반영 시키면 설정값이 크게 변동할 우려가 있습니다.
이런 문제를 피하기 위해 본인이 사용하는 방법은 라인 에디터에서 값을 변동한 후 확인 버튼(여기서는 CHANGE 버튼)을 눌러야 값을 변경하는 방법을 주로 이용합니다.

그럼 푸쉬버튼을 이용하여 값을 받아들여 보겠습니다.


우선, 여담 한마디
본인도 아직 정확하게 이해하지 못한 내용이지만, 한번 읽어만 보시기 바랍니다.

TEXT_EVENT에서 넘겨주는 text값은 항상 변하는 값입니다.
 mask*.cpp의 show_mask2에 정의되어 있는 이 문자열 변수의 값은 항상 변한다고 생각하십시오. 문자열 포인터를 하나 만들어 이 문자열의 주소를 참조할 경우 거의 \NULL값이 나타납니다.

 char text[MAX_EVENT_LENGTH];

 char *textPointer;
 textPointer = text;

 text는 문자열 배열이기 때문에 위와 같이 새로운 textPointer 포인터 변수를 만든 후, text의 주소를 지정하면 쉽게 접근할 수 있을 것 같은 데, 이런 방식으로 접근해봐야 아무 소용 없습니다. 즉 text 변수에 원하는 값이 있을 확률이 거의 없습니다.

어떻게 접근하면 쉽게 할 수 있을까요?

방법은 간단합니다. strcpy 함수를 이용하여 라인 에디터 위젯의 TEXT_EVENT가 발생할 때 마다. 문자열을 복사한 후 사용하면 됩니다. 이렇게 하면 라인 에디터의 최종 입력 내용을 항상 사용할 수 있습니다.
그럼 또 하나의 의문 사항, 어디에 문자열 변수를 만들어야 할 까요?

mask?_slot.h 함수, 앞 부분 코드를 살펴보면 DATA struct 구문이 있습니다. 여기에 문자열 배열을 만들어 주면 mask 함수 전 영역에서 사용할 수 있습니다.


다음과 같이 문자열 배열을 한개 만들어 주십시오.



mask.cpp 함수 내부에 정의된 것과 똑같이 만들었습니다(그냥 카피했습니다.)
DATA 구조 내부에 정의된 것이기 때문에 형식, 변수명이 동일하여도 문제없습니다.

DATA 구조체를 사용하기 위해서는 구조체, 변수값을 초기화하여야 합니다.
초기화 함수는 DATA 구조체 정의 바로 밑에 있는 slotInit 함수에 정의되어 있지만 주석처리되어 있습니다. 주석을 제거하여 주시기 바랍니다.




GUI 화면이 초기화 될 때 마다, 구조체에 정의되어 있는 변수들은 초기화됩니다...

자, 8부 능선이상 올랐습니다.
복사할 문자열을 저장할 변수를 만들었으니까. strcpy 함수를 이용해 보겠습니다.
TextEvent가 발행할 때 마다 변수를 저장하여야 하니까. slotTextEvent 함수에 다음 내용을 삽입해 주십시오.

if (id == le_text) strcpy(d->text, text);

최종적으로 변경된 slotTextEvent 함수는 다음과 같습니다.




이제 le_text 위젯의 내용이 변경될 때마다 d->text에 변경된 최종 문자열이 저장됩니다.

마지막으로 CHANGE 푸쉬버튼을 눌렀을 때 d->text의 내용을 lb_10 라벨 위젯에 나타나게 해보죠.
푸쉬버튼 위젯을 설명할때 BUTTON_PRESSED_EVENT를 이용하였습니다. 동일합니다.




pb_change 푸쉬 버튼이 눌러졌을 때 pvSetText 함수를 이용하여 lb_10에 d->text 문자를 넣어주는 구문입니다.

그림 6. 최종 실행 화면
최종 실행화면입니다. CHANGE 버튼을 눌러 lb_10 라벨에 입력된 문자가 나타나는 것을 확인할 수 있습니다. 한글도 지원이 되는 것 같군요.

저장된 값은 문자열입니다. 숫자 형태로 받아 들이기 위해서는 적당한 이벤트에 문자열을 숫자로 변경하는 함수를 넣어주거나 입력되는 문자열을 감시하는 구문을 넣어주어야 합니다.
이것은 표준 C/C++ 함수를 이용하면 충분히 구현되는 내용이므로 더 이상 설명하지는 않겠습니다.

댓글 없음:

댓글 쓰기