본문 바로가기

프로그램/앱인벤터

[문제풀이]앱인벤터2 - "10. 퀴즈만들기와 퀴즈풀기" 확장하기 P206

앱인벤터2 문제풀이 -  P200 페이지 "퀴즈만들기와 퀴즈풀기" 확장하기



1. 퀴즈를 만들 때 문제와 함께 그림도 지정할 수 있게 확장하자. TinyWebDB는 영상을 저장해 주지 않기 때문에 조금 복잡하다. 영상 파일 대신에 영상이 있는 곳의 URL을 지정해야 한다. <퀴즈 만들기> 앱의 사용자 인터페이스에 URL을 입력하는 텍스트 박스를 추가한다. 다행히 Image 컴포넌트의 Picture 속성에 URL을 설정 할 수 있다. 

(영상 = 사진처럼 정지된 그림 동영상 = 연속적으로 움직이는 영상)



 퀴즈 만들기 앱과 퀴즈풀기앱 모두 수정을 해야한다. 

아래는 결과화면이다. 먼저 퀴즈만들기앱에서 문제, 정답, 이미지의URL주소를 입력한뒤 "제출"을 누르면 아래 추가된 리스트 목록에 방금 입력한 내용이 나온다. 그리고, 퀴즈풀기 앱로 가서 문제를 하나씩 넘겨보면, 만들어진 문제에 따라 URL을 입력했던 이미지도 나타난다. 




  퀴즈만들기의 디자이너탭에서 TableArrangement1에서 Rows를 3으로 바꾸고, Label4와 TextBox1을 추가하여 TextBox1의 Rename을 UrlText로 바꾼다.



  퀴즈만들기의  블록탭에서 먼저 url리스트를 만들어주어야 하므로 리스트변수를 선언해야 하는데, initialize global UrlsList3 to create empty list로 선언해 준다. 그리고 when Screen1.Initialize docall TinyWebDB1.GetValue tag "gaurls"를 추가하고, when SubmitButton.Click doadd items to list list item의 list에 get global UrlsList3, item에 UrlText.Text를 추가하고, 밑에 set UrlText.Text to " "을 추가하고, call TinyWebDB1.StoreValue tag valueToStore의  tag에 "gaurls" valueToStore에 get global UrlList3 을 추가해 준다. 



  그리고, 데이터리스트가 총 3개(문제, 정답, 이미지url)이므로, 한번의 비교문을 더 넣어야 하는데, 이를 위해 when TinyWebDB1.GotValueif then의 if then else에 톱니바퀴를 눌러 else if를 추가하고 그 else if에 get tagFromWebDB = "gaanswers" (답변태그면) , then set global AnswerList3 to get valueFromWebDB(답변리스트에), else에 set global UrlsList3 to get valueFromWebDB(문제도, 정답도 아니면 UrlsList3에를 추가한다. 


  마지막으로 to displayQAs에 화면에서 내가 입력한 문제와 이미지가 제대로 들어갔는지 확인하기 위해 url리스트 목록을 보여주는데, 이는 to displayQAs에 for each index from to by do에서 set QuestionsAnswersLabel.Text to join에 톱니바퀴를 눌러서 spring을 2개 추가하여 ":"select list item list index의 list에 get global UrlsList3를, index에 get Index를 넣고 마무리 한다. 


  여기까지 했으면, 이번엔 퀴즈풀기의 디자이너탭에서 image를 추가하고 Height를 220pixels로, Width를 Fill parent로 설정한다. 



  퀴즈풀기의 블록탭에서,  initialize global UrlsList1 to create empty list로 선언해 준다. 그리고,  when Screen1.Initialize docall TinyWebDB1.GetValue tag "gaurls"를 추가하고, when TinyWebDB1.GotValue doif then의 if then else에 톱니바퀴를 눌러 else if를 추가하고 else if에 get tagfromWebDB = "gaanswers"then에 set global Answer1 to get valueFromWebDBelse에 set global UrlList1 to get valueFromWebDB, set image1.Picture to select list item list index의 list에 get global UrlList1, index에 "1"을 넣는다. 


  이어서  when NextButton1.Click do(다음버튼)의 맨 밑에단락에 set Image1.Picture to select list item list index의 list에 get global UrlsList1을, index에 get currentQuestionIndex1을 추가하여 마무리 한다.





2. 퀴즈 제작자가 문제를 삭제할 수 있게 만들자. 이는 ListPicker를 사용하여 편하게 프로그래밍 할 수 있다. 항목은 remove list item 블록을 사용하여 삭제한다. 해당 항목은 문제와 정답 리스트 모두에서 제거해야 하며, 웹데이터베이스도 갱신해 주어야 한다. ListPicker와 항목 삭제에 대해서는 19장을 참조한다. 


   아래 그림처럼 퀴즈만들기 앱에서 문제와 답을 몇개 입력해 놓고, "문제보기"버튼클릭하면, 리스트 형태로 두번째 그림과 같이 나오고, 목록에서 삭제하고자 하는 문제를 클릭을 하면, 세번째 그림처럼 목록에서 삭제가 되는 형태로 작업해 보았다.


   예시 그림은 "문제원"을 삭제하는 것을 캡처한 것이다. 



  디자이너탭에서 ListPicker를 추가하고, 오른쪽 설정에서 Text속성을 "문제보기"로 바꾼다.




  블록탭에서 기존에 있던, 웹DB의 가져오기를 처리하는 when TinyWebDB1.GotValue do에서 if then 안의 두번째 if then에서 - then부분에 set ListPicker1.Elements to get global QuestionList3를 추가해준다. (문제와 답변리스트중 눈에 보이는 부분)


  그리고, 아래 그림처럼 when ListPicker1.AfterPinking doremove list item list index를 넣고, list에 get global QuestionList3를, Index에 ListPicker1.SelectionIndex를 삽입하고, 마찬가지로 같은 삭제하는 작업을 get global AnswerList3 역시 적용하여 끼운다. 그리고, call TinyWebDB1.StoreValue tag valueToStore에서 순서대로 "gaquestions"get global QuestionList3를 넣고, 마찬가지로 get global AnswerList3 역시 같은 방법으로 call TinyWebDB1 처리해 주는데, tag와 valueToStore는 "gaanswers" get global AnswerList3 이다. (폴더에 데이터리스트 저장하는 작업)

  마지막으로 화면에 저장된 리스트데이터를 보여주는 call displayQAs로 마무리 한다. 

  (삭제한 데이터가 제대로 삭제 됐는지 확인할 수 있게 삭제한 데이터를 뺀 나머지 저장된 데이터를 보여주는 작업)






3. 퀴즈 제작자가 퀴즈에 이름을 붙일 수 있게 해보자. 퀴즈 이름도 별도의 태그를 사용하여 데이터베이스에 저장해야 하며, <퀴즈풀기> 앱에서는 퀴즈 이름도 추가로 검색해야 한다. 퀴즈 이름을 Screen.Title 속성에 설정하여 화면의 제일 위에 보이게 하자.  


   먼저 동작원리는 (ㄱ)퀴즈만들기에서 몇개의 문제를 입력하고, (ㄴ)퀴즈풀기 앱으로 이동하여 퀴즈이름을 검색하면 , 3번 ~ 4번 그림처럼 검색한 문제 이름의 문제지문이 표시창에 나타나 화면위에 퀴즈풀기 대신 문제이름이 나타나는 것( "퀴즈풀기 - 문제이름" 식으로 좀 다르게 표현하고 싶다면, 블록의 text박스와 join을 사용하면 될 것 같다. )을 확인 할 수 있다. 





  (ㄱ)퀴즈만들기앱 의 디자이너탭에서 TableArrangement1의 Rows 속성을 "3"으로 바꾸고 그 안에 Label를 추가하여,  Rename을 누르고 Label4로, Text속성"이름붙이기"로 하고, 다시 TextBox를 추가하여 Rename을 누르고 Name_1으로 바꾼 뒤 Hint속성을 "문제명" 이라고 한다. 


  (ㄱ)퀴즈만들기앱 의 블록탭에서 이름의 입력을 받을, Name리스트를 만들기 위해 리스트 전역변수 선언을 해주는데, initialize global NameList3 to create empty list로, 그리고, 퀴즈만들기 앱 실행시 기존에 웹DB에 저장된 데이터를 모두 가져오도록 하는 블록을 프로그램시작과 동시에 실행시키는 블록인 when Screen1.Initialize do  call TinyWebDB1.GetValue tag "ganames"를 추가하고, 웹DB에 저장하는 기능을 수행하는 "제출" 버튼 처리기인, when SubjmitButton.Click doadd items to list list item에 get global NameList3  Name_1.Text를 추가하고, set Name_1.Text to " " 와 call TinyWebDB1.StoreValue tag valueToStore에서 순서대로 "ganames"와 get global NameList3를 추가한다.


그리고, when TinyWebDB1.GotValue do에 set global NameList3 to get valueFromWebDB를 추가한다. 


그런다음 입력한 문제명이 화면에서도 확인할 수 있도록 하는 프로시저인 to displayQAs do for each index from to by do의 set QuestionsAnswersLabel.Text to join에 톱니바퀴를 눌러서 spring을 2개 추가하여 ":"와 select list item list index의 list에 get global NameList3를, index에 get Index를 넣고 마무리 한다.






 위와 같이 퀴즈만들기 앱의 작업을 마쳤으면 이 번엔 (ㄴ)퀴즈풀기앱 의 디자이너 탭으로 가서 그 안에 TextBox를 추가하고, Rename을 눌러서 SearchTextBox1로, Button을 추가하여 Text속성을 "문제검색"으로하고, Rename을 눌러서 QSearchButton1으로 바꾼다. 



  (ㄴ)퀴즈풀기앱 의 블록탭으로 가서 검색할 문제이름을 입력을 받을, Name리스트를 만들기 위해 리스트 전역변수 선언을 해주는데, initialize global NameList3 to create empty list로, 그리고, 퀴즈만들기 앱 실행시 저장된 데이터를 가져오도록 하는, when Screen1.Initialize do에 call TinyWebDB1.GetValue tag 에 "ganames"를, when TinyWebDB1.GotValue do if then(1) 안의 if then else if then else(2) 부분에 set global NameList3 to get valueFromWebDB를 추가해 준다. 


그리고 가장중요한 문제의 이름을 검색해줄 텍스트박스 이벤트 처리기의 블록인 when QSearchButton1.Click do를 꺼내어, for each item in list do 의  list에 get global QuestionList3를 do에 set QuestionLabel1.Text toselect list item list index를 꺼내어 순서대로 list부분에 get global QuestionList3를, Index Index in list thing list를 삽입하고, thing 부분에 SearchTextBox1.Text를, list에 get global NameList3를 삽입하여 끼운다. 

그리고, 스크린 윗 부분에도 문제의 이름이 보여야 하므로 set Screen1.Title to SearchTextBox1.Text로 마무리한다. 


퀴즈풀기앱 전체보기 ----------------------------------------------



4. 여러 개의 퀴즈를 만들 수 있도록 확장해 보자. 퀴즈가 여러 개 이므로  퀴즈 자체를 항목으로 저장하는 리스트가 필요하다. 각각의 퀴즈에 고유한 이름을 붙여 주어야 하며, 퀴즈 이름을 태그로 사용한다. 


  블록탭












<출처 :  David Wolber, Hal Abelson, Ellen Spertus, Liz Looney(2015), 

앱인벤터2(초판)(오일석, 이진선 번역, 서울:한빛아카데미. (원서는 2014년에 출판)>