<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
	<id>https://old.wiki.ubuntu-kr.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=122.36.132.209</id>
	<title>Ubuntu Korea Community Wiki - 사용자 기여 [ko]</title>
	<link rel="self" type="application/atom+xml" href="https://old.wiki.ubuntu-kr.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=122.36.132.209"/>
	<link rel="alternate" type="text/html" href="https://old.wiki.ubuntu-kr.org/index.php?title=%ED%8A%B9%EC%88%98:%EA%B8%B0%EC%97%AC/122.36.132.209"/>
	<updated>2026-10-17T00:59:39Z</updated>
	<subtitle>사용자 기여</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://old.wiki.ubuntu-kr.org/index.php?title=Library4developers&amp;diff=1315</id>
		<title>Library4developers</title>
		<link rel="alternate" type="text/html" href="https://old.wiki.ubuntu-kr.org/index.php?title=Library4developers&amp;diff=1315"/>
		<updated>2017-11-17T05:45:41Z</updated>

		<summary type="html">&lt;p&gt;122.36.132.209: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== 라이브러리란? ==&lt;br /&gt;
* 도서관이라는 뜻처럼, 헤더 파일과 실행 루틴이 모여 있는 것으로 프로그래밍 언어에서 입출력과 문자열 관리와 같은 일상적인 작업을 추가할 때 사용한다.&lt;br /&gt;
== 동적 라이브러리와 정적 라이브러리의 특징 ==&lt;br /&gt;
=== 동적 라이브러리 ===&lt;br /&gt;
* 일반적으로 .so 로 끝나는 이름을 하고 있다.&lt;br /&gt;
* 윈도우의 DLL 파일이라고 생각하면 된다.&lt;br /&gt;
* 실행할 때 시스템에 설치되어 있는 라이브러리를 가져다 사용하므로, 정적 라이브러리에 비해 상대적으로 느리다.&lt;br /&gt;
* 공유 라이브러리를 사용하면 실행파일에 라이브러리를 포함할 필요가 없으므로 스토리지가 절약된다.&lt;br /&gt;
* 컴파일러의 기본값이다.&lt;br /&gt;
* 사용법&lt;br /&gt;
&amp;lt;pre lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gcc --shared -o parse parse.c -lxml2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 정적 라이브러리 ===&lt;br /&gt;
* 일반적으로 .a 로 끝나는 이름을 하고 있다.&lt;br /&gt;
* 윈도우의 lib 파일이라고 생각하면 된다.&lt;br /&gt;
* 컴파일할 때 함수를 실행파일에 포함한다.&lt;br /&gt;
* 실행할 때 모든 함수가 실행파일 안에 있으므로, 동적 라이브러리에 비해 상대적으로 빠르다.&lt;br /&gt;
* 정적 라이브러리를 사용하면 의존성 등에서 조금 더 자유로울 수 있다.&lt;br /&gt;
* 사용법&lt;br /&gt;
&amp;lt;pre lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
gcc --static -o parse parse.c -lxml2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== 기본 정적 라이브러리 ===&lt;br /&gt;
* 두개의 함수가 포함되어 있는 작은 라이브러리를 만들어보자. 예제에서는 이들 중 하나를 사용할 것이다. 이 함수들은 fred와 bill이며, 간단한 인사말을 출력한다. 우리는 각자 따로 소스파일을 작성할 것이다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; title=&amp;quot;fred.c&amp;quot;&amp;gt;&lt;br /&gt;
/* fred.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void fred(int arg)&lt;br /&gt;
{&lt;br /&gt;
  printf(&amp;quot;fred: you passed %d\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; title=&amp;quot;bill.c&amp;quot;&amp;gt;&lt;br /&gt;
/* bill.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void bill(char *arg)&lt;br /&gt;
{&lt;br /&gt;
  printf(&amp;quot;bill: you passed %s\n&amp;quot;, arg);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이러한 함수들을 각자 컴파일한 후 오프젝트파일을 만듦으로서 라이브러리파일에 포함시킬 수 있다. 우리는 -c 옵션을 사용함으로서 gcc가 실행가능한 완벽한 프로그램을 만들지 못하도록 해야 한다(.o 파일을 뽑아야 한다). 만일 이 소스를 -c옵션을 사용하지 않고 컴파일하면 main이 정의되지 않았다고 실패할 것이다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc -c bill.c fred.c&lt;br /&gt;
$ ls *.o&lt;br /&gt;
bill.o    fred.o&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* bill 함수를 호출하는 프로그램을 작성해보자. 먼저, 라이브러리에 필요한 헤더파일을 만들자. 이 헤더파일은 라이브러리 내부에서 함수들을 선언하는 것이며, 본 라이브러리를 사용하는 프로그램은 모두 이 헤더파일을 포함해야 한다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; title=&amp;quot;lib.h&amp;quot;&amp;gt;&lt;br /&gt;
/* 이건 lib.h다. fred와 bill을 사용할 어플들은 모두 이걸 include하도록 */&lt;br /&gt;
void bill(char *);&lt;br /&gt;
void fred(int);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 본 라이브러리를 사용하는 프로그램(program.c)을 작성하는 일은 존나 쉽다. 필요한 라이브러리와 헤더파일을 포함하고, 라이브러리에 들어있는 함수만 호출하면 된다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot; title=&amp;quot;program.c&amp;quot;&amp;gt;&lt;br /&gt;
/* program.c */&lt;br /&gt;
#include &amp;quot;lib.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  bill(&amp;quot;헬로 월드&amp;quot;);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이제 프로그램을 컴파일하고 테스트해보자. gcc한테 소스코드를 모두 오브젝트 파일로 컴파일하고 실행파일로 링크하라고 하자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc -c program.c&lt;br /&gt;
$ cc -o program program.o bill.o&lt;br /&gt;
$ program&lt;br /&gt;
bill : you passed 헬로 월드&lt;br /&gt;
$&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 이제 라이브러리를 만들고 사용해보자. ar프로그램을 사용하여 archive을 만들고 여기에 오프젝트 파일을 추가한다. 이 프로그램이 ar이라 불리는 까닭은 archive를 만들거나 각각의 파일을 모아서 하나의 커다란 파일에다 모아주기 때문이다. ar은 텍스트 파일들의 archive를 만들때에도 사용할 수 있기 때문에 주목해야 한다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ar crv lib.a bill.o fred.o&lt;br /&gt;
c - bill.o&lt;br /&gt;
c - fred.o&lt;br /&gt;
$&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이제 라이브러리를 만들었고, 두개의 오브젝트파일을 추가했다. 버클리 유닉스에서 파생된 몇몇 시스템에서는 라이브러리를 성공적으로 사용하기 위해 라이브러리 목록이 필요하다. 이 일은 ranlib라는 명령으로 처리한다. 하지만 리눅스와 같은 시스템에서 GNU 개발툴(build-essential)을 사용하면 이 과정은 필요없다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ranlib lib.a&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이제 라이브러리를 사용할 준비는 끝났다. 보통 프로그램을 만들 때 이러한 라이브러리를 추가할 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc -o program program.o lib.a&lt;br /&gt;
$ ./program&lt;br /&gt;
bill : you passed 헬로 월드&lt;br /&gt;
$&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 오브젝트 파일이나, 라이브러리 또는 실행 가능한 프로그램에 어떤 함수가 포함돼있는지 알아보기 위해 nm이라는 명령어를 사용할 수 있다. program과 lib.a를 살펴보면, 라이브러리는 fred와 bill을 포함하고 있지만 program은 단지 bill만 포함하고 있다는걸 알 수 있다. 프로그램이 만들어질 때, 실제로 필요한 함수들만 라이브러리에 포함된다. 라이브러리의 모든 함수들이 선언된 헤더 파일을 포함한다고 해서 모든 라이브러리 함수들이 포함되는건 아니다.&lt;br /&gt;
* 만약에 여러분이 [[MSDOS]]나 [[윈도우]] 소프트웨어 개발에 대해 좀 알고 있다면 몇가지 유사한 점을 살펴볼 수 있다.&lt;br /&gt;
{| align=&amp;quot;center&amp;quot; cellpadding=&amp;quot;10&amp;quot; cellspacing=&amp;quot;0&amp;quot; border=&amp;quot;1&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| Item&lt;br /&gt;
| Unix&lt;br /&gt;
| DOS / Windows&lt;br /&gt;
|-&lt;br /&gt;
| 오브젝트 모듈&lt;br /&gt;
| lib.a&lt;br /&gt;
| lib.lib&lt;br /&gt;
|-&lt;br /&gt;
| 실행파일&lt;br /&gt;
| program&lt;br /&gt;
| program.exe&lt;br /&gt;
|}&lt;br /&gt;
* 정적라이브러리의 단점은 동시에 여러 프로그램을 띄웠을 경우 이들이 모두 같은 라이브러리의 함수들을 사용하니까 메모리에 같은 함수들을 여러번 복사하고, 프로그램 파일에도 같은 라이브러리를 여러번 복사한다는거다. 이는 메모리 용량과 디스크 용량을 많이 소모한다. 많은 유닉스 시스템에서는 이러한 불편함을 극복할 수 있게 공유라이브러리를 제공한다.&lt;br /&gt;
* 공유라이브러리랑 정적라이브러리는 같은데 저장돼있는데 확장자가 다르다. 전형적인 리눅스 시스템에서 표준 C 라이브러리의 공유 라이브러리 버전은 /lib/아키텍쳐/libc.so.N이다. 32비트의 경우 그냥 /lib/i386-linux-gnu/libc.so.6일 것이고, 64비트라면 /lib/amd64-linux-gnu/libc.so.6일 것이다. 여기서 N은 대부분 메이저 버전 숫자를 나타내며 현재는 6이다.&lt;br /&gt;
* 프로그램이 공유라이브러리를 사용할 때, /usr/lib/아키텍쳐/libc.so라는 라이브러리에 링크된다. 이 라이브러리는 그 자체로 함수코드를 포함하고 있지 않은 특별한 라이브러리다. 하지만 런타임에 포함할 공유라이브러리를 참조한다.&lt;br /&gt;
* 프로그램이 실행을 위해 메모리에 적재될 때 함수에 대한 참조 부분이 분석되어 공유라이브러리의 적재가 가능하게 되며, 필요한 경우에 공유라이브러리는 메모리상에 적재된다.&lt;br /&gt;
* 이경우 시스템은 많은 응용프로그램들이 하나의 라이브러리를 공유할 수 있게 해준다. 또, 프로그램마다 같은 라이브러리를 실행파일에 포함할 이유가 없으니 하드도 절약된다.&lt;br /&gt;
* 공유라이브러리는 이것에 의존하는 프로그램과 상관없이 지혼자 업그레이드할 수 있는 부가적인 이점도 있다.&lt;br /&gt;
* 리눅스 시스템에서 공유 라이브러리의 적재를 관리하며, 클라이언트 프로그램의 함수 참조를 분석하는 일은 ld.so 또는 ld-linux.so가 맡고 있다. 공유 라이브러리 검색 디렉토리는 /etc/ld.so.conf에 설정된다. /etc/ld.so.conf파일에 변경이 있었다면 ldconfig를 수행해야 한다. 하나의 예로, X11 공유 라이브러리 검색 디렉토리가 추가됐을 때를 들 수 있겠다.&lt;br /&gt;
* ldd를 사용하면 해당 프로그램에서 어떠한 공유 라이브러리를 요구하는지 알아볼 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ldd program&lt;br /&gt;
  linux-gate.so.1 =&amp;gt; (0xb7785000)&lt;br /&gt;
  libc.so.6 =&amp;gt; /lib/i386-linux/gnu/i686/cmov/libc.so.6 (0xb760e000)&lt;br /&gt;
  /lib/ld-linux.so.2 (0xb7786000)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 위의 경우 표준 C라이브러리(libc)가 공유되고 있음을 알 수 있다. 다른 유닉스 시스템에서도 공유라이브러리 접근 방법은 비슷비슷하다. 좀더 자세한 사항은 아는사람 있으면 추가바람&lt;br /&gt;
* 공유라이브러리는 [[Windows]]에서 사용되는 동적 링크 라이브러리와 많은 부분이 비슷하다. .so라이브러리는 .dll과 대응되며, .a라이브러리는 .lib와 비슷하다고 보면 된다.&lt;br /&gt;
&lt;br /&gt;
== 라이브러리의 설치 ==&lt;br /&gt;
* sudo apt-get install로 설치가 가능하다.&lt;br /&gt;
ex)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sudo apt-get install libxml2-dev&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 설치된 라이브러리는 일반적으로 /usr/include에 헤더파일이 들어가며, /usr/lib에 .so파일과 .a파일이 들어간다.&lt;br /&gt;
== 라이브러리 사용법 ==&lt;br /&gt;
=== getopt ===&lt;br /&gt;
* 일단 받은 인자를 출력하는 코드부터 보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* args.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
  int arg;&lt;br /&gt;
&lt;br /&gt;
  for(arg = 0; arg &amp;lt; argc; arg++) {&lt;br /&gt;
    if(argv[arg][0] == '-')&lt;br /&gt;
      printf(&amp;quot;Option: %s\n&amp;quot;, argv[arg] + 1);&lt;br /&gt;
    else&lt;br /&gt;
      printf(&amp;quot;argument %d: %s\n&amp;quot;, arg, argv[arg]);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 프로그램을 실행시키면 프로그램의 인자와 옵션을 출력한다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ ./args -i -lr 'hi there' -f fred.c&lt;br /&gt;
argument 0: args&lt;br /&gt;
option: i&lt;br /&gt;
option: lr&lt;br /&gt;
argument 3: hi there&lt;br /&gt;
option: f&lt;br /&gt;
argument 5: fred.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* ... 이걸 라이브러리 안 쓰고 파싱하려면 머리에 쥐난다.&lt;br /&gt;
* 그래서 getopt가 있는거다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int getopt(int argc, char *const argv[], const char *optstring);&lt;br /&gt;
extern char *optarg;&lt;br /&gt;
extern int optind, opterr, optopt;&lt;br /&gt;
* getopt는 main에서 전달된 argc, argv 인자를 가지고 옵션인지 아닌지 판단해주는 라이브러리다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
getopt(argc, argv, &amp;quot;if:lr&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* getopt의 동작 순서는 다음과 같다.&lt;br /&gt;
# 옵션이 값을 취한다면, 해당 값을 전역변수 optarg에 넣는다.&lt;br /&gt;
# 더이상 처리할 옵션이 없다면 getopt에 -1을 반환.&lt;br /&gt;
# 인식할 수 없는 옵션이 있으면 getopt는 ?를 반환. 해당 옵션은 전역변수 optopt에 저장.&lt;br /&gt;
# 옵션이 값을 취하고 해당 값이 없으면 getopt는 :를 반환&lt;br /&gt;
* 전역변수 optind는 처리할 다음 인자의 인덱스로 설정한다. 그래서 남은 인자가 argv 몇번째인지 알 수 있다.&lt;br /&gt;
* POSIX는 opterr 변수가 0이 아닐 경우 getopt가 stderr로 에러메세지를 출력해야 한다고 권고하고 있다.&lt;br /&gt;
* 아래는 getopt를 사용하는 예제다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
  int opt;&lt;br /&gt;
&lt;br /&gt;
  while((opt = getopt(argc, argv, &amp;quot;if:lr&amp;quot;)) != -1) {&lt;br /&gt;
    switch(opt) {&lt;br /&gt;
    case 'i':&lt;br /&gt;
    case 'l':&lt;br /&gt;
    case 'r':&lt;br /&gt;
      printf(&amp;quot;옵션: %c\n&amp;quot;, opt);&lt;br /&gt;
      break;&lt;br /&gt;
    case 'f':&lt;br /&gt;
      printf(&amp;quot;파일: %s\n&amp;quot;, optarg);&lt;br /&gt;
      break;&lt;br /&gt;
    case ':':&lt;br /&gt;
      printf(&amp;quot;옵션에 값을 넣어주세요\n&amp;quot;);&lt;br /&gt;
      break;&lt;br /&gt;
    case '?':&lt;br /&gt;
      printf(&amp;quot;모르는 옵션: %c\n&amp;quot;, optopt);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  for(; optind &amp;lt; argc; optind++)&lt;br /&gt;
    printf(&amp;quot;argument: %s\n&amp;quot;, argv[optind]));&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행해보면 다음과 같다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ argopt -i -lr 'hi there' -f fred.c -q&lt;br /&gt;
옵션: i&lt;br /&gt;
옵션: l&lt;br /&gt;
옵션: r&lt;br /&gt;
파일: fred.c&lt;br /&gt;
argopt: illegal option-q&lt;br /&gt;
모르는 옵션: q&lt;br /&gt;
argument: hi there&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 반복적으로 getopt를 호출하여 출력하는게 일반적이다.&lt;br /&gt;
=== getopt_long ===&lt;br /&gt;
* 추후 추가&lt;br /&gt;
=== getenv, putenv ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *getenv(const char *name);&lt;br /&gt;
int putenv(const char *string);&lt;br /&gt;
extern char **environ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 환경변수는 name=value 형식으로 구성되어 있다.&lt;br /&gt;
* getenv 함수는 주어진 name으로 사용된 환경변수를 찾아서 있으면 value값을 반환. 없으면 null 반환.&lt;br /&gt;
* putenv 함수는 &amp;quot;name=value&amp;quot; 형식의 문자열로 사용. 메모리가 부족하면 -1 반환, errno는 ENOMEM으로 세팅됨.&lt;br /&gt;
* 환경변수 출력 예제&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* environ.c */&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
  char *var, *value;&lt;br /&gt;
  if(argc == 1 || argc &amp;gt; 3) {&lt;br /&gt;
    fprintf(stderr, &amp;quot;Usage: ./environ var [value]\n&amp;quot;);&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
  /* getenv로 환경변수를 읽는다 */&lt;br /&gt;
  var = argv[1];&lt;br /&gt;
  value = getenv(var);&lt;br /&gt;
  if(value)&lt;br /&gt;
    printf(&amp;quot;환경변수 %s는 %s 값을 가지고 있음\n&amp;quot;, var, value);&lt;br /&gt;
  else&lt;br /&gt;
    printf(&amp;quot;환경변수 %s는 값이 없음\n&amp;quot;, var);&lt;br /&gt;
  /* 프로그램에 두번째 인자가 전달되었는지 확인하고, 두번째 인자로 환경변수에 값을 써넣는다. */&lt;br /&gt;
  if(argc == 3) {&lt;br /&gt;
    char *string;&lt;br /&gt;
    value = argv[2];&lt;br /&gt;
    string = malloc(strlen(var)+strlen(value)+2);&lt;br /&gt;
    if(!string) {&lt;br /&gt;
      fprintf(stderr, &amp;quot;메모리 부족\n&amp;quot;);&lt;br /&gt;
      return 1;&lt;br /&gt;
    }&lt;br /&gt;
    strcpy(string, var);&lt;br /&gt;
    strcat(string, &amp;quot;=&amp;quot;);&lt;br /&gt;
    strcat(string, value);&lt;br /&gt;
    printf(&amp;quot;putenv 함수를 이렇게 호출함: %s\n&amp;quot;, string);&lt;br /&gt;
    if(putenv(string) != 0) {&lt;br /&gt;
      fprintf(stderr, &amp;quot;putenv 실패\n&amp;quot;);&lt;br /&gt;
      free(string);&lt;br /&gt;
      return 1;&lt;br /&gt;
    }&lt;br /&gt;
    /* getenv 호출해서 변수가 바뀌었는지 확인 */&lt;br /&gt;
    value = getenv(var);&lt;br /&gt;
    if(value)&lt;br /&gt;
      printf(&amp;quot;%s의 새 값은 %s입니다.\n&amp;quot;, var, value);&lt;br /&gt;
    else&lt;br /&gt;
      printf(&amp;quot;%s에 새 값이 지정되지 않았습니다.\n&amp;quot;, var);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행화면은 다음과 같다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ ./environ HOME&lt;br /&gt;
환경변수 HOME는 /home/drake 값을 가지고 있음&lt;br /&gt;
$ ./environ FRED&lt;br /&gt;
환경변수 FRED는 값이 없음.&lt;br /&gt;
$ ./environ FRED hello&lt;br /&gt;
환경변수 FRED는 값이 없음.&lt;br /&gt;
putenv 함수를 이렇게 호출함: FRED=hello&lt;br /&gt;
FRED의 새 값은 hello입니다.&lt;br /&gt;
$ ./environ FRED&lt;br /&gt;
환경변수 FRED는 값이 없음.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 프로그램 내부에서 환경변수를 마음껏 써도 외부에 영향을 주지 않는다.&lt;br /&gt;
* 변수값이 쉘에게 전달되지 않기 때문.&lt;br /&gt;
* 다음 프로그램으로 environ 변수를 불러보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char **env = environ;&lt;br /&gt;
&lt;br /&gt;
  while(*env) {&lt;br /&gt;
    printf(&amp;quot;%s\n&amp;quot;, *env);&lt;br /&gt;
    env++;&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 코드는 쉘에서 export를 쳤을때랑 비슷하게 나올거다.&lt;br /&gt;
=== time ===&lt;br /&gt;
==== time ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
time_t time(time_t *tloc);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 시간을 처리하기 위한 데이터형은 time_t이다. 정수형이고, 날짜+시간을 초단위로 담는다. long타입.&lt;br /&gt;
* tloc 인자가 null이 아닐 경우 tloc에 값을 넣는다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* envtime.c */&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  int i;&lt;br /&gt;
  time_t the_time;&lt;br /&gt;
  for(i = 1; i &amp;lt;= 10; i++) {&lt;br /&gt;
    the_time = time((time_t *) 0);&lt;br /&gt;
    printf(&amp;quot;The time is %ld\n&amp;quot;, the_time);&lt;br /&gt;
    sleep(2);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행결과는 다음과 같다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ cc -o envtime envtime.c&lt;br /&gt;
drake@debian:~/cc$ ./envtime&lt;br /&gt;
The time is 1402826222&lt;br /&gt;
The time is 1402826224&lt;br /&gt;
The time is 1402826226&lt;br /&gt;
The time is 1402826228&lt;br /&gt;
The time is 1402826230&lt;br /&gt;
The time is 1402826232&lt;br /&gt;
The time is 1402826234&lt;br /&gt;
The time is 1402826236&lt;br /&gt;
The time is 1402826238&lt;br /&gt;
The time is 1402826240&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== difftime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
double difftime(time_t time1, time_t time2);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 두 시간의 차이를 double로 반환한다.&lt;br /&gt;
* 호환성을 위한 함수&lt;br /&gt;
&lt;br /&gt;
==== gmtime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct tm *gmtime(const time_t timeval);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* tm 구조체의 멤버&lt;br /&gt;
# int tm_sec - Seconds, 0~61&lt;br /&gt;
# int tm_min - Minutes, 0~59&lt;br /&gt;
# int tm_hour - Hours, 0~23&lt;br /&gt;
# int tm_mday - Day in month, 1~31&lt;br /&gt;
# int tm_mon - Month in the year, 0~11(1월은 0)&lt;br /&gt;
# int tm_year - 1900부터 시작&lt;br /&gt;
# int tm_wday - 무슨요일인지. 0~6(일요일이 0)&lt;br /&gt;
# int tm_yday - 1년중 몇일인지, 0~365&lt;br /&gt;
# int tm_isdst - 일광절약일인지&lt;br /&gt;
* tm_sec의 범위는 가끔씩 윤초를 허용하므로 61까지 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* gmtime.c */&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  struct tm *tm_ptr;&lt;br /&gt;
  time_t the_time;&lt;br /&gt;
  (void) time(&amp;amp;the_time);&lt;br /&gt;
  tm_ptr = gmtime(&amp;amp;the_time);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;Raw time is %ld\n&amp;quot;, the_time);&lt;br /&gt;
  printf(&amp;quot;gmtime gives:\n&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;date: %02d/%02d/%02d\n&amp;quot;, tm_ptr-&amp;gt;tm_year, tm_ptr-&amp;gt;tm_mon+1, tm_ptr-&amp;gt;tm_mday);&lt;br /&gt;
  printf(&amp;quot;time: %02d:%02d:%02d\n&amp;quot;, tm_ptr-&amp;gt;tm_hour, tm_ptr-&amp;gt;tm_min, tm_ptr-&amp;gt;tm_sec);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이건 다음과 같이 결과가 나온다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ ./gmtime&lt;br /&gt;
Raw time is 1402839108&lt;br /&gt;
gmtime gives:&lt;br /&gt;
date: 114/06/15&lt;br /&gt;
time: 13:31:48&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* year 부분이 이상하다. 원래 1900년으로부터 시작되니 그런거다. 정확히 나타내기 위해서는 1900을 더하면 된다.&lt;br /&gt;
* 실제 실행해본 사람은 현재 시각이 이상하다는걸 느낄거다. gmtime은 협정세계시를 기준으로 나타낸다.&lt;br /&gt;
&lt;br /&gt;
==== localtime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct tm *localtime(const time_t *timeval);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* gmtime 대신 localtime으로 실행하면 실제 지역 시간으로 나온다.&lt;br /&gt;
&lt;br /&gt;
==== mktime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
time_t mktime(struct tm *timeptr);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* mktime은 tm 구조체로 되어있는 시간을 기본 시간으로 바꿔준다.&lt;br /&gt;
&lt;br /&gt;
==== asctime, ctime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
asctime(const struct tm *timeptr);&lt;br /&gt;
char *ctime(const time_t *timeval);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* asctime은 tm 구조체를 받아서 리눅스 기본 시간문자열로 변환해준다.&lt;br /&gt;
* ctime은 기본 시간을 받아 리눅스 기본 시간문자열로 변환해준다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* ctime.c */&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  time_t timeval;&lt;br /&gt;
&lt;br /&gt;
  (void)time(&amp;amp;timeval);&lt;br /&gt;
  printf(&amp;quot;The date is: %s&amp;quot;, ctime(&amp;amp;timeval));&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행하면 다음과 같이 나온다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ ./ctime&lt;br /&gt;
The date is: Sun Jun 15 09:43:11 2014&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== strftime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
size_t strftime(char *s, size_t maxsize, const char *format, struct tm *timeptr);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* strftime은 printf문과 비슷한 형식으로 형식화해주는 함수다.&lt;br /&gt;
* 인자 s의 크기는 최소한 maxsize보다 커야 한다.&lt;br /&gt;
* 변환 식별자는 다음과 같다.&lt;br /&gt;
# %a - 단축형 주일 이름&lt;br /&gt;
# %A - 전체형 주일 이름&lt;br /&gt;
# %b - 단축형 달 이름&lt;br /&gt;
# %B - 전체형 달 이름&lt;br /&gt;
# %c - 날짜와 시간&lt;br /&gt;
# %d - 달 중 오늘이 며칠인지, 1~31&lt;br /&gt;
# %H - 24시간제 시간, 0~23&lt;br /&gt;
# %I - 12시간제 시간, 0-12&lt;br /&gt;
# %J - 연 중 오늘이 며칠인지, 1~366&lt;br /&gt;
# %m - 연중 달, 1~12&lt;br /&gt;
# %M - 분, 0~59&lt;br /&gt;
# %p - AM, PM&lt;br /&gt;
# %S - 초, 0~61&lt;br /&gt;
# %u - 지금 요일, 1~7(1은 월요일)&lt;br /&gt;
# %U - 연중 지금이 몇째주인지 1~53(일요일이 주중 첫째날이라고 본다)&lt;br /&gt;
# %V - 연중 지금이 몇째주인지 1~53(월요일이 주중 첫째날이라고 본다)&lt;br /&gt;
# %w - 지금 요일, 0~6(0은 일요일)&lt;br /&gt;
# %x - 지역 날짜&lt;br /&gt;
# %X - 지역 시간&lt;br /&gt;
# %y - 네자리 연도 2자리 뒷부분&lt;br /&gt;
# %Y - 네자리 연도&lt;br /&gt;
# %z - 시간 지대 이름&lt;br /&gt;
* 쉘에서 date로 출력되는 시간은 strftime으로 다음과 같은 format으로 하면 비슷하게 나온다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;%a %b %d %H:%M:%S %Y&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== strptime ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *strptime(const char *buf, const char *format, struct tm *timeptr);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* strftime와는 반대로, 문자열에서 변수로 변환한다.&lt;br /&gt;
* 꼭 맞아 떨어져야 잘 들어가는데, 쉽지 않다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  struct tm *tm_ptr, timestruct;&lt;br /&gt;
  time_t the_time;&lt;br /&gt;
  char buf[256];&lt;br /&gt;
  char *result;&lt;br /&gt;
&lt;br /&gt;
  (void) time(&amp;amp;the_time);&lt;br /&gt;
  tm_ptr = localtime(&amp;amp;the_time);&lt;br /&gt;
  strftime(buf, 256, &amp;quot;%A %d %B, %I:%S %p&amp;quot;, tm_ptr);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;strftime gives: %s\n&amp;quot;, buf);&lt;br /&gt;
&lt;br /&gt;
  strcpy(buf, &amp;quot;Tue 4 December 1995, 17:53 will do fine&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;calling strptime with: %s\n&amp;quot;, buf);&lt;br /&gt;
  tm_ptr = &amp;amp;timestruct;&lt;br /&gt;
&lt;br /&gt;
  result = strptime(buf, &amp;quot;%a %d %b %Y, %R&amp;quot;, tm_ptr);&lt;br /&gt;
 printf(&amp;quot;strptime consumed up to: %s\n&amp;quot;, result);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;strptime gives:\n&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;date: %02d/%02d/%02d\n&amp;quot;, tm_ptr-&amp;gt;tm_year, tm_ptr-&amp;gt;tm_mon+1, tm_ptr-&amp;gt;tm_mday);&lt;br /&gt;
  printf(&amp;quot;time: %02d:%02\n&amp;quot;, tm_ptr-&amp;gt;tm_hour, tm_ptr-&amp;gt;tm_min);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== tmpnam, tmpfile ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *tmpnam(char *s);&lt;br /&gt;
FILE *tmpfile(void);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* tmpnam 함수는 임시파일을 만들기 위한 파일이름을 생성한다. 무조건 기존과 다른 이름을 생성한다.&lt;br /&gt;
* tmpfile 함수는 임시파일을 만들고 표준 입출력으로 연다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* tmpnam.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char tmpname[L_tmpnam];&lt;br /&gt;
  char *filename;&lt;br /&gt;
  FILE *tmpfp;&lt;br /&gt;
&lt;br /&gt;
  filename = tmpnam(tmpname);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;임시파일 이름은:%s\n&amp;quot;, filename);&lt;br /&gt;
&lt;br /&gt;
  tmpfp = tmpfile();&lt;br /&gt;
  if(tmpfp)&lt;br /&gt;
    printf(&amp;quot;임시파일 열림\n&amp;quot;);&lt;br /&gt;
  else&lt;br /&gt;
    perror(&amp;quot;Failed to open temporary file.&amp;quot;);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이에 대한 실행 결과를 보자.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ ./tmpnam&lt;br /&gt;
임시파일 이름은:/tmp/fileVA6s2t&lt;br /&gt;
임시파일 열림&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== mktemp, mkstemp ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *mktemp(char *template);&lt;br /&gt;
int mkstemp(char *template);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* mktemp는 임시파일을 위해 template로부터 유일한 파일 이름을 만든다.&lt;br /&gt;
* mkstemp는 임시파일을 만들고 저수준 시스템 콜로 open한다.&lt;br /&gt;
=== getuid, getlogin ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uid_t getuid(void);&lt;br /&gt;
char *getlogin(void);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* getuid는 현재 프로그램이 실행되는 계정의 uid를 정수로 반환한다.&lt;br /&gt;
* getlogin은 현재 프로그램이 실행되는 계정을 문자열로 반환한다.&lt;br /&gt;
=== getpwuid, getpwnam ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct passwd *getpwuid(uid_t uid);&lt;br /&gt;
struct passwd *getpwnam(const char *name);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* passwd는 비밀번호 구조체다. 다음과 같은 구조로 되어 있다.&lt;br /&gt;
# char *pw_name - 계정명&lt;br /&gt;
# char uid_t pw_uid - 계정 번호&lt;br /&gt;
# char gid_t pw_gid - 그룹 번호&lt;br /&gt;
# char *pw_dir - 사용자의 홈 디렉토리&lt;br /&gt;
# char *pw_shell - 사용자의 기본 쉘&lt;br /&gt;
* getpwuid와 getpwnam은 둘다 passwd 구조체를 반환한다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* user.c */&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  uid_t uid;&lt;br /&gt;
  gid_t gid;&lt;br /&gt;
  struct passwd *pw;&lt;br /&gt;
&lt;br /&gt;
  uid = getuid();&lt;br /&gt;
  gid = getgid();&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;사용자는 %s\n&amp;quot;, getlogin());&lt;br /&gt;
  printf(&amp;quot;사용자 아이디: uid=%d, gid=%d\n&amp;quot;, uid, gid);&lt;br /&gt;
&lt;br /&gt;
  pw = getpwuid(uid);&lt;br /&gt;
  printf(&amp;quot;UID passwd entry:\n계정명=%s, uid=%d, gid=%d, home=%s, shell=%s\n&amp;quot;, pw-&amp;gt;pw_name, pw-&amp;gt;pw_uid, pw-&amp;gt;pw_gid, pw-&amp;gt;pw_dir, pw-&amp;gt;pw_shell);&lt;br /&gt;
&lt;br /&gt;
  pw = getpwnam(&amp;quot;root&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;root passwd entry:\n&amp;quot;);&lt;br /&gt;
  printf(&amp;quot;계정명=%s, uid=%d, gid=%d, home=%s, shell=%s\n&amp;quot;, pw-&amp;gt;pw_name, pw-&amp;gt;pw_uid, pw-&amp;gt;pw_gid, pw-&amp;gt;pw_dir, pw-&amp;gt;pw_shell);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 프로그램을 실행하면 다음과 같은 결과가 나온다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ ./user&lt;br /&gt;
사용자는 drake&lt;br /&gt;
사용자 아이디: uid=1000, gid=1000&lt;br /&gt;
UID passwd entry:&lt;br /&gt;
계정명=drake, uid=1000, gid=1000, home=/home/drake, shell=/bin/bash&lt;br /&gt;
root passwd entry:&lt;br /&gt;
계정명=root, uid=0, gid=0, home=/root, shell=/bin/bash&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== endpwent, getpwent, setpwent ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void endpwent(void);&lt;br /&gt;
struct passwd *getpwent(void);&lt;br /&gt;
void setpwent(void);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* getpwent는 사용자 목록을 읽는다.&lt;br /&gt;
* endpwent는 목록을 읽다 만다.&lt;br /&gt;
* setpwent는 사용자를 적어넣고 첫번째 엔트리로 간다.&lt;br /&gt;
=== geteuid, getgid, getegid, setuid, setgid ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uid_t geteuid(void);&lt;br /&gt;
gid_t getgid(void);&lt;br /&gt;
gid_t getegid(void);&lt;br /&gt;
int setuid(uid_t uid);&lt;br /&gt;
int setgid(gid_t gid);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* uid와 gid를 얻어내는 함수&lt;br /&gt;
* root만 setuid와 setgid를 쓸 수 있다.&lt;br /&gt;
=== gethostname ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int gethostname(char *name, size_t namelen);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* gethostname은 머신의 이름을 name에 기록한다.&lt;br /&gt;
=== uname ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int uname(struct utsname *name);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* uname은 name 포인터가 가리키는 구조체에 호스트정보를 기록한다. 그 내용은 다음과 같다.&lt;br /&gt;
# char sysname[] - OS 이름&lt;br /&gt;
# char nodename[] - 호스트이름&lt;br /&gt;
# char release[] - 시스템 릴리즈&lt;br /&gt;
# char version[] - 시스템 버전 번호&lt;br /&gt;
# char machine[] - 하드웨어 타입&lt;br /&gt;
* uname 함수는 성공할때는 양수를 반환하고, 에러시에는 -1을 반환하고 errorno가 설정된다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* hostget.c */&lt;br /&gt;
#include &amp;lt;sys/utsname.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char computer[256];&lt;br /&gt;
  struct utsname uts;&lt;br /&gt;
&lt;br /&gt;
  if(gethostname(computer, 255) != 0 || uname(&amp;amp;uts) &amp;lt; 0) {&lt;br /&gt;
    fprintf(stderr, &amp;quot;Could not get host information\n&amp;quot;);&lt;br /&gt;
    return 1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;Computer Host name is %s\n&amp;quot;, computer);&lt;br /&gt;
  printf(&amp;quot;System is %s on %s hardware \n&amp;quot;, uts.sysname, uts.machine);&lt;br /&gt;
  printf(&amp;quot;Nodename is %s\n&amp;quot;, uts.nodename);&lt;br /&gt;
  printf(&amp;quot;Version is %s, %s\n&amp;quot;, uts.release, uts.version);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행하면 다음과 같은 결과가 나온다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ ./hostget&lt;br /&gt;
Computer Host name is debian&lt;br /&gt;
System is Linux on i686 hardware&lt;br /&gt;
Nodename is debian&lt;br /&gt;
Version is 3.2.0-4-686-pae, #1 SMP Debian 3.2.51-1&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 쉘에서 uname이랑 거의 같다.&lt;br /&gt;
=== gethostid ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
long gethostid(void);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 호스트아이디는 컴퓨터의 식별번호로 쓰기 좋은 일련번호를 반환한다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;syslog.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void syslog(int priority, const char *message, arguments...);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 메세지 로그를 위한 함수.&lt;br /&gt;
* 다음은 유저단계다.&lt;br /&gt;
# LOG_USER - 유저 단계&lt;br /&gt;
# LOG_LOCAL1 - 로컬 1단계&lt;br /&gt;
# LOG_LOCAL2 - 로컬 2단계&lt;br /&gt;
# LOG_LOCAL3 - 로컬 3단계&lt;br /&gt;
# LOG_LOCAL4 - 로컬 4단계&lt;br /&gt;
# LOG_LOCAL5 - 로컬 5단계&lt;br /&gt;
# LOG_LOCAL6 - 로컬 6단계&lt;br /&gt;
# LOG_LOCAL7 - 로컬 7단계&lt;br /&gt;
* 다음은 우선순위.&lt;br /&gt;
# LOG_EMERG - 비상사태&lt;br /&gt;
# LOG_ALERT - 비상상황(DB 에러 등)&lt;br /&gt;
# LOG_CRIT - 임계에러(하드웨어 실패 등)&lt;br /&gt;
# LOG_ERR - 에러&lt;br /&gt;
# LOG_WARNING - 경고&lt;br /&gt;
# LOG_NOTICE - 주의사항&lt;br /&gt;
# LOG_INFO - 정보 메세지&lt;br /&gt;
# LOG_DEBUG - 디버그 메세지&lt;br /&gt;
* 위의 우선순위와 비상사태 단계 &lt;br /&gt;
* 일반적으로 LOG_EMERG 메세지는 모든 사용자에게 방송되고, LOG_ALERT는 관리자메일로 발송될 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* syslog.c */&lt;br /&gt;
#include &amp;lt;syslog.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  /* 없는 파일 읽기 */&lt;br /&gt;
  FILE *f;&lt;br /&gt;
&lt;br /&gt;
  f = fopen(&amp;quot;not_here&amp;quot;, &amp;quot;r&amp;quot;);&lt;br /&gt;
  if(!f)&lt;br /&gt;
    syslog(LOG_ERR|LOG_USER, &amp;quot;Oops - %m\n&amp;quot;);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행시에 출력되는건 없지만 dmesg | tail로 로그를 확인할 수 있다.&lt;br /&gt;
=== closelog, openlog, setlogmask ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;syslog.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void closelog(void);&lt;br /&gt;
void openlog(const char *ident, int logopt, int facility);&lt;br /&gt;
int setlogmask(int maskpri);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* openlog / closelog로 기록 메세지 표현방법을 변경할 수 있다.&lt;br /&gt;
* ident 설정은 다음과 같다. | 연산자로 여러가지 지정이 가능하다.&lt;br /&gt;
# LOG_PID - 메세지 안에 프로세스 식별자 포함&lt;br /&gt;
# LOG_CONS - 메세지 기록에 실패하면 콘솔로 보낸다.&lt;br /&gt;
# LOG_ODELAY - 연결은 메세지가 작성될 때 확립&lt;br /&gt;
# LOG_NDELAY - 연결 즉시 확립&lt;br /&gt;
* setlogmask로 예를 들어 LOG_DEBUG 메세지는 꺼버릴 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* logmask.c */&lt;br /&gt;
#include &amp;lt;syslog.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  int logmask;&lt;br /&gt;
&lt;br /&gt;
  openlog(&amp;quot;logmask&amp;quot;, LOG_PID|LOG_CONS, LOG_USER);&lt;br /&gt;
  syslog(LOG_INFO, &amp;quot;informative message, pid = %d&amp;quot;, getpid());&lt;br /&gt;
  syslog(LOG_DEBUG, &amp;quot;debug message, sould apeear&amp;quot;);&lt;br /&gt;
  logmask = setlogmask(LOG_MASK(LOG_DEBUG));&lt;br /&gt;
  syslog(LOG_DEBUG, &amp;quot;debug message, should not appear&amp;quot;);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 프로그램을 실행하면 출력은 없지만 /var/log/messages와 /var/log/debug에 로그가 추가된다.&lt;br /&gt;
=== getpriority, setpriority, getrlimit, setrlimit, getrusage ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/resource.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int getpriority(int which, id_t who);&lt;br /&gt;
int setpriority(int which, id_t who, int priority);&lt;br /&gt;
int getrlimit(int resource, struct rlimit *r_limit);&lt;br /&gt;
int setrlimit(int resource, const struct rlimit *r_limit);&lt;br /&gt;
int getrusage(int who, struct rusage *r_usage);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* id_t는 사용자와 그룹 식별자에 사용되는 정수&lt;br /&gt;
* rusage는 /usr/include/아키텍쳐-linux-gnu/sys/resource.h를 확인&lt;br /&gt;
* rusage구조체는 다음과 같다.&lt;br /&gt;
# struct timeval ru_utime - 사용된 사용자 시간&lt;br /&gt;
# struct timeval ru_stime - 사용된 시스템 시간&lt;br /&gt;
* timeval 구조체는 /usr/아키텍쳐-linux-gnu/sys/time.h에 정의되어 있음&lt;br /&gt;
* 사용자 시간은 유저모드로 돌아간 시간, 시스템 시간은 커널모드로 돌아간 시간이다.&lt;br /&gt;
* who는 다음 중 하나다.&lt;br /&gt;
# RUSAGE_SELF - 현재 프로그램 정보만 반환&lt;br /&gt;
# RUSAGE_CHILDREN - 자식 프로그램 정보도 포함해서 반환&lt;br /&gt;
* 응용프로그램은 getpriority와 setpriority로 우선순위를 측정하거나 변경한다.&lt;br /&gt;
* which는 다음중 하나를 선택한다.&lt;br /&gt;
# PRO_PROCESS - who는 프로세스 식별자&lt;br /&gt;
# PRO_PGRP - who는 프로세스 그룹&lt;br /&gt;
# PRO_USR - who는 사용자 식별자&lt;br /&gt;
* 현재 프로세스의 우선순위를 알아보려면 다음과 같이 호출할 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
priority = getpriority(PRIO_PROCESS, getpid());&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* setpriority는 우선순위변경이 가능할 경우 새로운 우선순위로 설정한다. 기본값은 0&lt;br /&gt;
* 음수는 높은 우선순위, 양수는 낮은 우선순위.&lt;br /&gt;
* getpriority는 성공하면 우선순위가 반환되고 실패하면 -1 반환&lt;br /&gt;
* 우선순위에 -1이 들어갈 수 있다. 그러므로 errno를 확인해야 한다.&lt;br /&gt;
* getlimit와 setrlimit는 rlimit 구조체를 사용한다. 구조체는 다음의 멤버를 가진다.&lt;br /&gt;
# rlim_t rlim_cur - soft인지 hard인지, 현재의 자원수준&lt;br /&gt;
# rlim_t rlim_max - 최대 자원&lt;br /&gt;
* resource에 지정하는 rlimit 관련 항목&lt;br /&gt;
# RLIMIT_CORE - 코어덤프 파일크기제한, 바이트 단위&lt;br /&gt;
# RLIMIT_CPU - CPU 시간제한, 초단위&lt;br /&gt;
# RLIMIT_DATA - 데이터 세그먼트 제한, 바이트 단위&lt;br /&gt;
# RLIMIT_FSIZE - 파일 사이즈 제한, 바이트 단위&lt;br /&gt;
# RLIMIT_NOFILE - 개방 파일 갯수 제한&lt;br /&gt;
# RLIMIT_STACK - 스택 크기 제한, 바이트 단위&lt;br /&gt;
# RLIMIT_AS - 주소 공간 제한, 바이트 단위&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* rlimit.c */&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/resource.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/time.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
/* work 함수는 임시파일에 10000번 쓰기 시도하고, CPU에 부하를 걸기 위해 약간의 산술 연산을 수행한다. */&lt;br /&gt;
void work()&lt;br /&gt;
{&lt;br /&gt;
  FILE *f;&lt;br /&gt;
  int i;&lt;br /&gt;
  double x = 4.5;&lt;br /&gt;
&lt;br /&gt;
  f = tmpfile();&lt;br /&gt;
  for(i = 0; i &amp;lt; 10000; i++) {&lt;br /&gt;
    fprintf(f, &amp;quot;Do some output\n&amp;quot;);&lt;br /&gt;
    if(ferror(f)) {&lt;br /&gt;
      fprintf(stderr, &amp;quot;임시파일 작성 실패\n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  for(i = 0; i &amp;lt; 10000; i++)&lt;br /&gt;
    x = log(x*x + 3.21);&lt;br /&gt;
}&lt;br /&gt;
/* main은 work를 부르고 getrusage를 써서 얼마만큼의 CPU시간을 소비했는지 알아보고, 이에 관한 정보를 출력한다. */&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  struct rusage r_usage;&lt;br /&gt;
  struct rlimit r_limit;&lt;br /&gt;
  int priority;&lt;br /&gt;
&lt;br /&gt;
  work();&lt;br /&gt;
  getrusage(RUSAGE_SELF, &amp;amp;r_usage);&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;CPU usage: Uer = %ld.%06ld, System = %ld.%06ld\n&amp;quot;, r_usage.ru_utime.tv_sec, r_usage.ru_utime.tv_usec, r_usage.ru_stime.tv_sec, r_usage.ru_stime.tv_usec);&lt;br /&gt;
&lt;br /&gt;
  /* getpriority와 getrlimit를 사용해 현재의 우선순위값과 파일크기 제한을 알아낸다. */&lt;br /&gt;
  priority = getpriority(PRIO_PROCESS, getpid());&lt;br /&gt;
  printf(&amp;quot;Current priority = %d\n&amp;quot;, priority);&lt;br /&gt;
&lt;br /&gt;
  getrlimit(RLIMIT_FSIZE, &amp;amp;r_limit);&lt;br /&gt;
  printf(&amp;quot;Current FSIZE limit: soft = %ld, hard = %ld\n&amp;quot;, r_limit.rlim_cur, r_limit.rlim_max);&lt;br /&gt;
&lt;br /&gt;
  r_limit.rlim_cur = 2048;&lt;br /&gt;
  r_limit.rlim_max = 4096;&lt;br /&gt;
  printf(&amp;quot;Setting a 2K file size limit\n&amp;quot;);&lt;br /&gt;
  setrlimit(RLIMIT_FSIZE, &amp;amp;r_limit);&lt;br /&gt;
&lt;br /&gt;
  work();&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행결과는 다음과 같다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
drake@debian:~/cc$ cc -o limits limits.c -lm&lt;br /&gt;
drake@debian:~/cc$ ./limits&lt;br /&gt;
CPU usage: Uer = 0.004000, System = 0.004000&lt;br /&gt;
Current priority = 0&lt;br /&gt;
Current FSIZE limit: soft = -1, hard = -1&lt;br /&gt;
Setting a 2K file size limit&lt;br /&gt;
File size limit exceeded&lt;br /&gt;
drake@debian:~/cc/wrox$ nice ./limits&lt;br /&gt;
CPU usage: Uer = 0.008000, System = 0.000000&lt;br /&gt;
Current priority = 10&lt;br /&gt;
Current FSIZE limit: soft = -1, hard = -1&lt;br /&gt;
Setting a 2K file size limit&lt;br /&gt;
File size limit exceeded&lt;br /&gt;
drake@debian:~/cc$&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Math 라이브러리를 사용했으니 -lm을 이용해 math 라이브러리를 포함해야 한다.&lt;br /&gt;
* nice로 우선순위를 좀 낮춰줄 수 있다.&lt;br /&gt;
=== malloc ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void *malloc(size_t size);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 동적 메모리 할당을 해준다.&lt;br /&gt;
* 원래 반환되는 데이터 타입은 void* 이다. 타입캐스트로 char*형으로 바꿔서 쓰는게 일반적이다.&lt;br /&gt;
* 32비트에서는 4GB까지 지정할 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* memory1.c */&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define A_MEGABYTE (1024 * 1024)&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  char *some_memory;&lt;br /&gt;
  int megabyte = A_MEGABYTE;&lt;br /&gt;
  int exit_code = EXIT_FAILURE;&lt;br /&gt;
&lt;br /&gt;
  some_memory = (char *)malloc(megabyte);&lt;br /&gt;
  if(some_memory != NULL) {&lt;br /&gt;
    sprintf(some_memory, &amp;quot;Hello World\n&amp;quot;);&lt;br /&gt;
    printf(&amp;quot;%s&amp;quot;, some_memory);&lt;br /&gt;
    exit_code = EXIT_SUCCESS;&lt;br /&gt;
  }&lt;br /&gt;
  return exit_code;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 메모리를 자기 물리 메모리만큼 잡아보자. 뻗나 안 뻗나.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* memory2.c */&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define A_MEGABYTE (1024 * 1024)&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  char *some_memory;&lt;br /&gt;
  size_t size_to allocate = A_MEGABYTE;&lt;br /&gt;
  int megs_obtained = 0;&lt;br /&gt;
&lt;br /&gt;
  while(megs_obtained &amp;lt; 8192) {&lt;br /&gt;
    some_memory = (char *)malloc(size_to_allocate);&lt;br /&gt;
    if(some_memory != NULL) {&lt;br /&gt;
      megs_obtained++;&lt;br /&gt;
      sprintf(some_memory, &amp;quot;Hello World&amp;quot;);&lt;br /&gt;
      printf(&amp;quot;%s - now allocated %d Megabytes\n&amp;quot;, some_memory, megs_obtained);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      exit(EXIT_FAILURE);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 2GB의 물리시스템을 가진 시스템에서 3056MB까지 버텼다.&lt;br /&gt;
* 좀 더 하드하게 해보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* memory3.c */&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ONE_K (1024)&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  char *some_memory;&lt;br /&gt;
  int size_to_allocate = ONE_K;&lt;br /&gt;
  int megs_obtained = 0;&lt;br /&gt;
  int ks_obtained = 0;&lt;br /&gt;
&lt;br /&gt;
  while(1) {&lt;br /&gt;
    for(ks_obtained = 0; ks_obtained &amp;lt; 1024; ks_obtained++) {&lt;br /&gt;
      some_memory = (char *)malloc(size_to_allocate);&lt;br /&gt;
      if(some_memory == NULL) exit(EXIT_FAILURE);&lt;br /&gt;
      sprintf(some_memory, &amp;quot;Hello World&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    megs_obtained++;&lt;br /&gt;
    printf(&amp;quot;Now allocated %d Megabytes\n&amp;quot;, megs_obtained);&lt;br /&gt;
  }&lt;br /&gt;
  exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 같은 시스템에서 3045MB까지 버텼다.&lt;br /&gt;
* 아마 64비트에서는 더 버틸거다.&lt;br /&gt;
* 메모리를 조금 할당하고 메모리 외부에 write를 시도해볼까?&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* memory4.c */&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define ONE_K (1024)&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  char *some_memory;&lt;br /&gt;
  char *scan_ptr;&lt;br /&gt;
&lt;br /&gt;
  some_memory = (char *)malloc(ONE_K);&lt;br /&gt;
  if(some_memory == NULL) exit(EXIT_FAILURE);&lt;br /&gt;
&lt;br /&gt;
  scan_ptr = some_memory;&lt;br /&gt;
  while(1) {&lt;br /&gt;
  *scan_ptr = '\0';&lt;br /&gt;
    scan_ptr++;&lt;br /&gt;
  }&lt;br /&gt;
  exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 세그먼트 폴트.&lt;br /&gt;
* [[윈도우]]에서 잘못된 메모리 접근도 다 이거다.&lt;br /&gt;
* 널포인터 접근을 보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* memory5.c */&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  char *some_memory = (char *)0;&lt;br /&gt;
&lt;br /&gt;
  printf(&amp;quot;A read from null %s\n&amp;quot;, some_memory);&lt;br /&gt;
  sprintf(some_memory, &amp;quot;A write to null\n&amp;quot;);&lt;br /&gt;
  exit(EXIT_SUCCESS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== free ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void free(void *ptr_to_memory);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 할당된 메모리를 해제하는 역할을 한다.&lt;br /&gt;
* c가 어렵다고 다들 이야기하는 부분이 이 부분이다.&lt;br /&gt;
=== calloc, realloc ===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void *calloc(size_t number_of_elements, size_t element_size);&lt;br /&gt;
void *realloc(void *existing_memory, size_t new_size);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* calloc는 배열 동적할당이다. number_of_elements가 원소 갯수, element_size가 원소의 크기.&lt;br /&gt;
* realloc는 재할당이다.크기조절에 실패하면 널포인터를 반환하는데 이게 좀 거시기하다.&lt;br /&gt;
* realloc을 사용하기보다는, 새로 할당하고 이전 할당된걸 해제하는 식으로 설계하는것이 좋다.&lt;br /&gt;
=== gdbm ===&lt;br /&gt;
* 데비안 계열(우분투 포함)에서는 libgdbm-dev 패키지를 설치하면 된다.&lt;br /&gt;
* dbm은 데이터블록과 키 데이터로 이뤄져 있다.&lt;br /&gt;
* 기본적으로는 FILE형과 유사하다.&lt;br /&gt;
* 데이터베이스 파일은 .dir과 .pag로 이루어져 있다.&lt;br /&gt;
==== dbm_open, dbm_store, dbm_fetch, dbm_close ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;gdbm.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
DBM *gdbm_open(const char *filename, int file_open_flags, mode_t file_mode);&lt;br /&gt;
int gdbm_store(DBM *database_descriptor, datum key, datum content, int store_mode);&lt;br /&gt;
datum gdbm_fetch(DBM *database_descriptor, datum key);&lt;br /&gt;
void gdbm_close(DBM *database_descriptor);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* gdbm_open은 존재하는 db를 열거나 새 db를 만드는 역할을 한다. open이랑 비슷. 성공하면 DBM, 실패하면 (DBM *)0 반환&lt;br /&gt;
* gdbm_store는 db에 데이터를 저장한다.&lt;br /&gt;
# store_mode를 dbm_insert로 설정하면 저장이 안되고 1을 반환&lt;br /&gt;
# store_mode를 dbm_replace로 설정하면 예전 데이터를 덮어쓰고 0을 반환&lt;br /&gt;
# 에러시에는 음수를 반환&lt;br /&gt;
* gdbm_fetch는 db에서 데이터를 가져온다. 반환에는 datum만 반환된다.&lt;br /&gt;
* gdbm_close는 db를 닫는다.&lt;br /&gt;
=== sqlite3 ===&lt;br /&gt;
* SQLite는 파일 기반의 RDBMS다.&lt;br /&gt;
* SQLite는 다른 RDBMS에 비해 작아서 좀더 여러 디바이스에서 사용한다.&lt;br /&gt;
* 일단 스마트폰에 들어가는 RDBMS는 다 이거라고 볼 수 있겠다.&lt;br /&gt;
* 2014년 현재 sqlite3가 주력으로 사용되고 있다.&lt;br /&gt;
* 라이브러리는 다음과 같이 설치가 가능하다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ sudo apt-get install libsqlite3-dev&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==== sqlite3_open, sqlite3_exec, sqlite3_close ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int sqlite3_open(const char *filename, sqlite3 **ppDb);&lt;br /&gt;
int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg);&lt;br /&gt;
sqlite3_close(sqlite3*);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* sqlite3_open은 디비를 연다. 파일이름은 utf8형식이다.&lt;br /&gt;
* sqlite3_exec는 SQL쿼리를 실행한다. sql은 sql문이고, [[callback 함수]]와 그에 들어가는 데이터를 집어넣을 수 있다.&lt;br /&gt;
* sqlite3_close는 디비를 닫는다.&lt;br /&gt;
* 일단 디비를 한번 열어보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* sqliteopen.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   sqlite3 *db;&lt;br /&gt;
   char *zErrMsg = 0;&lt;br /&gt;
   int rc;&lt;br /&gt;
&lt;br /&gt;
   rc = sqlite3_open(&amp;quot;test.db&amp;quot;, &amp;amp;db);&lt;br /&gt;
&lt;br /&gt;
   if( rc ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Can't open database: %s\n&amp;quot;, sqlite3_errmsg(db));&lt;br /&gt;
      return -1;&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stderr, &amp;quot;Opened database successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   sqlite3_close(db);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* mysql도 쉽지만, 이거에 비할바는 안되지.&lt;br /&gt;
* 컴파일시 -lsqlite3 만 붙이면 된다.&lt;br /&gt;
* db 여는걸 확인했으면 테이블을 한번 만들어 보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* sqlite3createtable.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
static int callback(void *NotUsed, int argc, char **argv, char **azColName){&lt;br /&gt;
   int i;&lt;br /&gt;
   for(i=0; i&amp;lt;argc; i++){&lt;br /&gt;
      printf(&amp;quot;%s = %s\n&amp;quot;, azColName[i], argv[i] ? argv[i] : &amp;quot;NULL&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   sqlite3 *db;&lt;br /&gt;
   char *zErrMsg = 0;&lt;br /&gt;
   int  rc;&lt;br /&gt;
   char *sql;&lt;br /&gt;
&lt;br /&gt;
   /* Open database */&lt;br /&gt;
   rc = sqlite3_open(&amp;quot;test.db&amp;quot;, &amp;amp;db);&lt;br /&gt;
   if( rc ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Can't open database: %s\n&amp;quot;, sqlite3_errmsg(db));&lt;br /&gt;
      return -1;&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stdout, &amp;quot;Opened database successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /* Create SQL statement */&lt;br /&gt;
   sql = &amp;quot;CREATE TABLE COMPANY(&amp;quot;  \&lt;br /&gt;
         &amp;quot;ID INT PRIMARY KEY     NOT NULL,&amp;quot; \&lt;br /&gt;
         &amp;quot;NAME           TEXT    NOT NULL,&amp;quot; \&lt;br /&gt;
         &amp;quot;AGE            INT     NOT NULL,&amp;quot; \&lt;br /&gt;
         &amp;quot;ADDRESS        CHAR(50),&amp;quot; \&lt;br /&gt;
         &amp;quot;SALARY         REAL );&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Execute SQL statement */&lt;br /&gt;
   rc = sqlite3_exec(db, sql, callback, 0, &amp;amp;zErrMsg);&lt;br /&gt;
   if( rc != SQLITE_OK ){&lt;br /&gt;
   fprintf(stderr, &amp;quot;SQL error: %s\n&amp;quot;, zErrMsg);&lt;br /&gt;
      sqlite3_free(zErrMsg);&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stdout, &amp;quot;Table created successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   sqlite3_close(db);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* SQL은 그냥 exec만 하면 된다. 별다를게 없다 정말...&lt;br /&gt;
* 테이블도 열렸는데 insert 한번 해보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* sqlite3insert.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
static int callback(void *NotUsed, int argc, char **argv, char **azColName){&lt;br /&gt;
   int i;&lt;br /&gt;
   for(i=0; i&amp;lt;argc; i++){&lt;br /&gt;
      printf(&amp;quot;%s = %s\n&amp;quot;, azColName[i], argv[i] ? argv[i] : &amp;quot;NULL&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   sqlite3 *db;&lt;br /&gt;
   char *zErrMsg = 0;&lt;br /&gt;
   int rc;&lt;br /&gt;
   char *sql;&lt;br /&gt;
&lt;br /&gt;
   /* Open database */&lt;br /&gt;
   rc = sqlite3_open(&amp;quot;test.db&amp;quot;, &amp;amp;db);&lt;br /&gt;
   if( rc ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Can't open database: %s\n&amp;quot;, sqlite3_errmsg(db));&lt;br /&gt;
      return -1;&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stderr, &amp;quot;Opened database successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /* Create SQL statement */&lt;br /&gt;
   sql = &amp;quot;INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) &amp;quot;  \&lt;br /&gt;
         &amp;quot;VALUES (1, 'Paul', 32, 'California', 20000.00 ); &amp;quot; \&lt;br /&gt;
         &amp;quot;INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) &amp;quot;  \&lt;br /&gt;
         &amp;quot;VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); &amp;quot;     \&lt;br /&gt;
         &amp;quot;INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)&amp;quot; \&lt;br /&gt;
         &amp;quot;VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );&amp;quot; \&lt;br /&gt;
         &amp;quot;INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)&amp;quot; \&lt;br /&gt;
         &amp;quot;VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Execute SQL statement */&lt;br /&gt;
   rc = sqlite3_exec(db, sql, callback, 0, &amp;amp;zErrMsg);&lt;br /&gt;
   if( rc != SQLITE_OK ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;SQL error: %s\n&amp;quot;, zErrMsg);&lt;br /&gt;
      sqlite3_free(zErrMsg);&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stdout, &amp;quot;Records created successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   sqlite3_close(db);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
* 값을 넣어봤으면 읽어오는것도 필요하지&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* sqlite3select.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
static int callback(void *data, int argc, char **argv, char **azColName){&lt;br /&gt;
   int i;&lt;br /&gt;
   fprintf(stderr, &amp;quot;%s: &amp;quot;, (const char*)data);&lt;br /&gt;
   for(i=0; i&amp;lt;argc; i++){&lt;br /&gt;
      printf(&amp;quot;%s = %s\n&amp;quot;, azColName[i], argv[i] ? argv[i] : &amp;quot;NULL&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   sqlite3 *db;&lt;br /&gt;
   char *zErrMsg = 0;&lt;br /&gt;
   int rc;&lt;br /&gt;
   char *sql;&lt;br /&gt;
   const char* data = &amp;quot;Callback function called&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Open database */&lt;br /&gt;
   rc = sqlite3_open(&amp;quot;test.db&amp;quot;, &amp;amp;db);&lt;br /&gt;
   if( rc ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Can't open database: %s\n&amp;quot;, sqlite3_errmsg(db));&lt;br /&gt;
      return -1;&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stderr, &amp;quot;Opened database successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /* Create SQL statement */&lt;br /&gt;
   sql = &amp;quot;SELECT * from COMPANY&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Execute SQL statement */&lt;br /&gt;
   rc = sqlite3_exec(db, sql, callback, (void*)data, &amp;amp;zErrMsg);&lt;br /&gt;
   if( rc != SQLITE_OK ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;SQL error: %s\n&amp;quot;, zErrMsg);&lt;br /&gt;
      sqlite3_free(zErrMsg);&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stdout, &amp;quot;Operation done successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   sqlite3_close(db);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* update도 한번 봅시당&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* sqlite3update.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
static int callback(void *data, int argc, char **argv, char **azColName){&lt;br /&gt;
   int i;&lt;br /&gt;
   fprintf(stderr, &amp;quot;%s: &amp;quot;, (const char*)data);&lt;br /&gt;
   for(i=0; i&amp;lt;argc; i++){&lt;br /&gt;
      printf(&amp;quot;%s = %s\n&amp;quot;, azColName[i], argv[i] ? argv[i] : &amp;quot;NULL&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   sqlite3 *db;&lt;br /&gt;
   char *zErrMsg = 0;&lt;br /&gt;
   int rc;&lt;br /&gt;
   char *sql;&lt;br /&gt;
   const char* data = &amp;quot;Callback function called&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Open database */&lt;br /&gt;
   rc = sqlite3_open(&amp;quot;test.db&amp;quot;, &amp;amp;db);&lt;br /&gt;
   if( rc ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Can't open database: %s\n&amp;quot;, sqlite3_errmsg(db));&lt;br /&gt;
      return -1;&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stderr, &amp;quot;Opened database successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /* Create merged SQL statement */&lt;br /&gt;
   sql = &amp;quot;UPDATE COMPANY set SALARY = 25000.00 where ID=1; &amp;quot; \&lt;br /&gt;
         &amp;quot;SELECT * from COMPANY&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Execute SQL statement */&lt;br /&gt;
   rc = sqlite3_exec(db, sql, callback, (void*)data, &amp;amp;zErrMsg);&lt;br /&gt;
   if( rc != SQLITE_OK ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;SQL error: %s\n&amp;quot;, zErrMsg);&lt;br /&gt;
      sqlite3_free(zErrMsg);&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stdout, &amp;quot;Operation done successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   sqlite3_close(db);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 같은 내용 지겹죠? 한번만 더 해봅시다 delete.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* sqlite3delete.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sqlite3.h&amp;gt; &lt;br /&gt;
&lt;br /&gt;
static int callback(void *data, int argc, char **argv, char **azColName){&lt;br /&gt;
   int i;&lt;br /&gt;
   fprintf(stderr, &amp;quot;%s: &amp;quot;, (const char*)data);&lt;br /&gt;
   for(i=0; i&amp;lt;argc; i++){&lt;br /&gt;
      printf(&amp;quot;%s = %s\n&amp;quot;, azColName[i], argv[i] ? argv[i] : &amp;quot;NULL&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char* argv[])&lt;br /&gt;
{&lt;br /&gt;
   sqlite3 *db;&lt;br /&gt;
   char *zErrMsg = 0;&lt;br /&gt;
   int rc;&lt;br /&gt;
   char *sql;&lt;br /&gt;
   const char* data = &amp;quot;Callback function called&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Open database */&lt;br /&gt;
   rc = sqlite3_open(&amp;quot;test.db&amp;quot;, &amp;amp;db);&lt;br /&gt;
   if( rc ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;Can't open database: %s\n&amp;quot;, sqlite3_errmsg(db));&lt;br /&gt;
      return -1;&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stderr, &amp;quot;Opened database successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   /* Create merged SQL statement */&lt;br /&gt;
   sql = &amp;quot;DELETE from COMPANY where ID=2; &amp;quot; \&lt;br /&gt;
         &amp;quot;SELECT * from COMPANY&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
   /* Execute SQL statement */&lt;br /&gt;
   rc = sqlite3_exec(db, sql, callback, (void*)data, &amp;amp;zErrMsg);&lt;br /&gt;
   if( rc != SQLITE_OK ){&lt;br /&gt;
      fprintf(stderr, &amp;quot;SQL error: %s\n&amp;quot;, zErrMsg);&lt;br /&gt;
      sqlite3_free(zErrMsg);&lt;br /&gt;
   }else{&lt;br /&gt;
      fprintf(stdout, &amp;quot;Operation done successfully\n&amp;quot;);&lt;br /&gt;
   }&lt;br /&gt;
   sqlite3_close(db);&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* sqlite3는 사용하는데 쫄지만 않으면 매우 쉽다고 볼 수 있다.&lt;br /&gt;
&lt;br /&gt;
=== MySQL ===&lt;br /&gt;
* 사용하려면 다음의 패키지를 설치해야 한다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ sudo apt-get install libmysqlclient-dev&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==== mysql_get_client_info ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* mysqlinfo.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;mysql.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
  printf(&amp;quot;MySQL Client version: %s\n&amp;quot;, mysql_get_client_info());&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 간단히 버전을 알아보는 프로그램이다.&lt;br /&gt;
* 컴파일 방법은 다음과 같다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cc -o mysqlinfo mysqlinfo.c `mysql_config --cflags --libs`&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
==== mysql_real_connect, mysql_query ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* mysqlcreatedb.c */&lt;br /&gt;
#include &amp;lt;my_global.h&amp;gt;&lt;br /&gt;
#include &amp;lt;mysql.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{  &lt;br /&gt;
  MYSQL *con = mysql_init(NULL);&lt;br /&gt;
&lt;br /&gt;
  if (con == NULL) &lt;br /&gt;
  {&lt;br /&gt;
      fprintf(stderr, &amp;quot;%s\n&amp;quot;, mysql_error(con));&lt;br /&gt;
      exit(1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (mysql_real_connect(con, &amp;quot;localhost&amp;quot;, &amp;quot;root&amp;quot;, &amp;quot;root_pswd&amp;quot;, &lt;br /&gt;
          NULL, 0, NULL, 0) == NULL) &lt;br /&gt;
  {&lt;br /&gt;
      fprintf(stderr, &amp;quot;%s\n&amp;quot;, mysql_error(con));&lt;br /&gt;
      mysql_close(con);&lt;br /&gt;
      exit(1);&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  if (mysql_query(con, &amp;quot;CREATE DATABASE testdb&amp;quot;)) &lt;br /&gt;
  {&lt;br /&gt;
      fprintf(stderr, &amp;quot;%s\n&amp;quot;, mysql_error(con));&lt;br /&gt;
      mysql_close(con);&lt;br /&gt;
      exit(1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  mysql_close(con);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 위의 프로그램은 testdb라는 데이터베이스를 추가한다.&lt;br /&gt;
* root를 사용할 수 있는데서만 쓸 수 있으니, 교육용으로는 별로 좋지 않다.&lt;br /&gt;
* 그러므로, 유저를 하나 만들어 보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;mysql&amp;quot;&amp;gt;&lt;br /&gt;
mysql&amp;gt; CREATE USER testdb@localhost IDENTIFIED BY '34klq*';&lt;br /&gt;
mysql&amp;gt; GRANT ALL ON testdb.* to testdb@localhost;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* testdb라는 아이디에 34klq*라는 비밀번호를 주고 testdb의 권한을 주는거다.&lt;br /&gt;
* phpmyadmin으로 해도 되고, 위의 프로그램에 쿼리문을 변경하여 사용해도 된다.&lt;br /&gt;
* testdb라는 데이터베이스가 있고, testdb라는 유저가 testdb에 접근할 수 있다는 가정 하에 값을 입력하는걸 짜보자.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* mysqlinsert.c */&lt;br /&gt;
#include &amp;lt;my_global.h&amp;gt;&lt;br /&gt;
#include &amp;lt;mysql.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void finish_with_error(MYSQL *con)&lt;br /&gt;
{&lt;br /&gt;
  fprintf(stderr, &amp;quot;%s\n&amp;quot;, mysql_error(con));&lt;br /&gt;
  mysql_close(con);&lt;br /&gt;
  exit(1);        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
  MYSQL *con = mysql_init(NULL);&lt;br /&gt;
  &lt;br /&gt;
  if (con == NULL) &lt;br /&gt;
  {&lt;br /&gt;
      fprintf(stderr, &amp;quot;%s\n&amp;quot;, mysql_error(con));&lt;br /&gt;
      exit(1);&lt;br /&gt;
  }  &lt;br /&gt;
&lt;br /&gt;
  if (mysql_real_connect(con, &amp;quot;localhost&amp;quot;, &amp;quot;testdb&amp;quot;, &amp;quot;34klq*&amp;quot;, &lt;br /&gt;
          &amp;quot;testdb&amp;quot;, 0, NULL, 0) == NULL) &lt;br /&gt;
  {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }    &lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;DROP TABLE IF EXISTS Cars&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;CREATE TABLE Cars(Id INT, Name TEXT, Price INT)&amp;quot;)) {      &lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(1,'Audi',52642)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(2,'Mercedes',57127)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(3,'Skoda',9000)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(4,'Volvo',29000)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(5,'Bentley',350000)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(6,'Citroen',21000)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(7,'Hummer',41400)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;INSERT INTO Cars VALUES(8,'Volkswagen',21600)&amp;quot;)) {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  mysql_close(con);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 프로그램을 컴파일해서 실행하고 phpmyadmin이나 콘솔로 확인해보면 데이터가 들어가있는걸 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
==== mysql_store_result, mysql_num_fields, mysql_fetch_row ====&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* mysqlfetch.c */&lt;br /&gt;
#include &amp;lt;my_global.h&amp;gt;&lt;br /&gt;
#include &amp;lt;mysql.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void finish_with_error(MYSQL *con)&lt;br /&gt;
{&lt;br /&gt;
  fprintf(stderr, &amp;quot;%s\n&amp;quot;, mysql_error(con));&lt;br /&gt;
  mysql_close(con);&lt;br /&gt;
  exit(1);        &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{      &lt;br /&gt;
  MYSQL *con = mysql_init(NULL);&lt;br /&gt;
  &lt;br /&gt;
  if (con == NULL)&lt;br /&gt;
  {&lt;br /&gt;
      fprintf(stderr, &amp;quot;mysql_init() failed\n&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
  }  &lt;br /&gt;
  &lt;br /&gt;
  if (mysql_real_connect(con, &amp;quot;localhost&amp;quot;, &amp;quot;testdb&amp;quot;, &amp;quot;34klq*&amp;quot;, &lt;br /&gt;
          &amp;quot;testdb&amp;quot;, 0, NULL, 0) == NULL) &lt;br /&gt;
  {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }    &lt;br /&gt;
  &lt;br /&gt;
  if (mysql_query(con, &amp;quot;SELECT * FROM Cars&amp;quot;)) &lt;br /&gt;
  {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  MYSQL_RES *result = mysql_store_result(con);&lt;br /&gt;
  &lt;br /&gt;
  if (result == NULL) &lt;br /&gt;
  {&lt;br /&gt;
      finish_with_error(con);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  int num_fields = mysql_num_fields(result);&lt;br /&gt;
&lt;br /&gt;
  MYSQL_ROW row;&lt;br /&gt;
  &lt;br /&gt;
  while ((row = mysql_fetch_row(result))) &lt;br /&gt;
  { &lt;br /&gt;
      for(int i = 0; i &amp;lt; num_fields; i++) &lt;br /&gt;
      { &lt;br /&gt;
          printf(&amp;quot;%s &amp;quot;, row[i] ? row[i] : &amp;quot;NULL&amp;quot;); &lt;br /&gt;
      } &lt;br /&gt;
          printf(&amp;quot;\n&amp;quot;); &lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  mysql_free_result(result);&lt;br /&gt;
  mysql_close(con);&lt;br /&gt;
  &lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이제 데이터베이스에서 뽑아오는것도 할 수 있다.&lt;/div&gt;</summary>
		<author><name>122.36.132.209</name></author>
	</entry>
	<entry>
		<id>https://old.wiki.ubuntu-kr.org/index.php?title=GUI(QT)_Programming&amp;diff=2816</id>
		<title>GUI(QT) Programming</title>
		<link rel="alternate" type="text/html" href="https://old.wiki.ubuntu-kr.org/index.php?title=GUI(QT)_Programming&amp;diff=2816"/>
		<updated>2017-11-17T05:43:16Z</updated>

		<summary type="html">&lt;p&gt;122.36.132.209: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== QT란 무엇인가? ==&lt;br /&gt;
* 리눅스나 유닉스에서 X-Window용 프로그램을 개발하려면 많은 지식이 필요하다.&lt;br /&gt;
* 다음과 같은 특징이 있다.&lt;br /&gt;
# C++ 기반 - 고급 언어들에 비해 어느정도 속도도 나오고, C에 비하면 좀더 모듈화가 되어 있어 확장이 용이&lt;br /&gt;
# 객체지향 - 라이브러리들이 모듈화가 잘 되어 있음&lt;br /&gt;
# 멀티플랫폼 - 다양한 플랫폼을 지원하고, 플랫폼이 바뀐다고 해서 전체를 싹 갈아엎지 않아도 된다.&lt;br /&gt;
# 시그널 &amp;amp; 슬롯 - 이벤트 처리 모델이 정형화되어 있다. 즉, 시그널 &amp;amp; 슬롯만 알면 콜백함수 등 실수할 여지가 줄어든다.&lt;br /&gt;
# Internationalization - 16비트 유니코드 완벽지원.&lt;br /&gt;
# API - 200개가 넘는 클래스를 지원한다. 웬만한 프로그램은 QT 안에 있는 라이브러리들로 해결 가능.&lt;br /&gt;
# 안정성 - 기업 베이스다. 개발은 아무나 할 수 있지만 커밋은 기업 내에서 이루어진다. 일반적으로 산으로 가는 프로젝트를 만들지 않는다.&lt;br /&gt;
&lt;br /&gt;
== QT 프로그램 구경하기 ==&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=VsT1yKRKkXE&amp;amp;list=PLumkkj1MBmYs-WArrEkw2R6wO9Agj3FoX&lt;br /&gt;
* QT 프로그램은 Ubuntu의 경우 소프트웨어센터에서 설치할 수 있다.&lt;br /&gt;
[[파일:Qt_1_install.png]]&lt;br /&gt;
* 새 프로젝트(New Project)를 선택하면 다음과 같은 화면이 나온다.&lt;br /&gt;
[[파일:Qt_1_new.png]]&lt;br /&gt;
* 위젯 어플리케이션을 선택하면 다음과 같은 화면이 나온다.&lt;br /&gt;
* 프로젝트 이름을 정하고 컴파일 키트를 선택한다.&lt;br /&gt;
# 프로젝트 이름은 임의로 작성하고, 컴파일 키트는 기본 옵션으로 설정하면 된다.&lt;br /&gt;
* 클래스 설정 화면은 다음과 같다.&lt;br /&gt;
# Base Class를 다음과 같이 QDialog로 변경한다.&lt;br /&gt;
[[파일:Qt_1_new_1.png]]&lt;br /&gt;
* Github 등을 사용한다면 본인 계정 등을 설정하도록 한다. 이 내용은 [[QT/Github]] 항목을 참조.&lt;br /&gt;
* 여기서는 그냥 버전컨트롤 없이 진행해도 상관없다.&lt;br /&gt;
* Form에 *.ui 를 더블클릭하여 선택하면 다음과 같이 디자이너 모드로 변경된다.&lt;br /&gt;
* 어디서 많이 보던것 같지 않은가? Visual Studio의 편집 화면과 비슷하다. Microsoft Visual Studio를 사용해본 경험이 있다면 거의 비슷하게 사용할 수 있다.&lt;br /&gt;
[[파일:Qt_1_newWin_0.png]]&lt;br /&gt;
* 자, 이제 버튼과 텍스트박스를 집어넣어봅시다.&lt;br /&gt;
* 왼쪽에 있는 컴포넌트에서 드래그해서 넣을 수 있다.&lt;br /&gt;
[[파일:Qt_1_Intro_0.png]]&lt;br /&gt;
* PushButton의 이름을 바꾸는건 간단하다. PushButton 항목을 선택하고, 오른쪽 속성창의 값을 변경해주면 끝.&lt;br /&gt;
[[파일:Qt_1_Intro_1.png]]&lt;br /&gt;
* 화면 구성을 했으니 버튼에 이벤트를 넣어봅시다.&lt;br /&gt;
# 인사하기에서 우클릭을 하고 Go to Slot을 선택합니다.&lt;br /&gt;
[[파일:Qt_1_Intro_2.png]]&lt;br /&gt;
# Go to Slot을 선택하면 다음과 같은 내용이 나옵니다.&lt;br /&gt;
[[파일:Qt_1_Intro_2_1.png ]]&lt;br /&gt;
# Clicked를 선택하면 코드 입력 부분이 나오는데, 다음과 같이 입력합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;Hello World&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# 지우기 부분 코드&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# 종료하기 부분 코드&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
this.close();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 기본 문법 ==&lt;br /&gt;
=== 변수와 상수 사용하기 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=tHzPBCUi0G8&amp;amp;list=PLumkkj1MBmYs-WArrEkw2R6wO9Agj3FoX&lt;br /&gt;
* 변수는 프로그램 내에서 수시로 값이 (변)할수 있는 (수)를 말합니다. 반면에 상수는 항(상) 같은 값을 유지하는 (수)를 말하는거죠.&lt;br /&gt;
* 프로젝트를 하나 만들고 시작해 보겠습니다.&lt;br /&gt;
[[파일:Qt 1 pro 0.png]]&lt;br /&gt;
* C++의 경우 변수를 사용하기 위해서는 선언을 해야 합니다. 일반적으로 헤더파일에 선언을 하죠. 여기서는 data라는 변수를 추가해 보겠습니다.&lt;br /&gt;
* 또한, 값을 확인하기 위한 디버그 모듈을 사용할 것입니다.&lt;br /&gt;
* 헤더에 QDebug를 사용한다고 선언하고, 정수형 data를 미리 선언합니다.&lt;br /&gt;
[[파일:Qt_1_pro_1.png]]&lt;br /&gt;
* 그리고, 다이얼로그가 열릴 때 처리될 수 있도록 다음과 같이 코드를 넣어주면 됩니다.&lt;br /&gt;
* qDebug() 함수를 사용할 때, 앞에 q는 소문자임에 유의해 주세요. qDebug() 함수는 c++의 cout과 같은 기능을 한다고 보시면 됩니다.&lt;br /&gt;
* 실행하면 아래 디버그 창에 값이 출력되는걸 확인할 수 있습니다.&lt;br /&gt;
[[파일:Qt_1_pro_2.png]]&lt;br /&gt;
* 여기서 사용된 data는 사용자가 임의로 만들 수 있는 변수입니다. 변수는 프로그램 내에서 숫자나 문자 등을 보관하는 역할을 합니다.&lt;br /&gt;
* 변수는 필요에 따라 얼마든지 만들어 사용할 수 있습니다.&lt;br /&gt;
* = 기호는 수학의 등호가 아닙니다. 오른쪽의 값을 왼쪽의 변수에 기억시키는 (또는 할당하는) 연산자입니다.&lt;br /&gt;
* 위의 프로그램에서 data 변수는 처음에 100을 기억했다가 다시 200을 기억합니다.&lt;br /&gt;
* 이와 같이 변수는 다른 값을 가질 수 있습니다. 그래서 변수입니다.&lt;br /&gt;
* 그에 반해 100이나 200같은 숫자는 상수라고 합니다. 이 숫자들은 프로그램이 아무리 실행되어도 항상 100과 200을 유지합니다. 그래서 상수입니다.&lt;br /&gt;
* 이제 여러가지 형식의 변수를 선언하고 이용해보도록 하겠습니다.&lt;br /&gt;
[[파일:Qt_1_pro_3.png]]&lt;br /&gt;
[[파일:Qt_1_pro_4.png]]&lt;br /&gt;
* 정수형 변수 dataint는 정수를 기억합니다. 컴퓨터가 가장 빠른 연산을 할 수 있는 데이터형입니다.&lt;br /&gt;
* 실수형 변수 datadou는 소수점 이하의 수를 기억합니다. 내부적으로는 지수 형태로 기억하지만, 일반적으로 소숫점이 있는 수를 저장할 때 많이 사용합니다.&lt;br /&gt;
* 논리형 변수 databoo는 true와 false 논리 상수를 기억합니다. 일반적으로 flag같은 값을 많이들 저장합니다.&lt;br /&gt;
* 문자열형 변수 datastr은 할당할 문자열을 반드시 겹따옴표 사이에 기술해야 합니다. 문자열은 문자의 집합을 의미합니다.&lt;br /&gt;
* 변수의 종류를 말할 때 위와 같이 데이터형에 따라 정수형 변수, 실수형 변수, 문자열형 변수, ...와 같이 구분합니다. 근데 또 다른 관점에서 구분하는 경우도 있습니다.&lt;br /&gt;
* 변수가 영향을 미치는 유효 범위에 따라 다음과 같이 구분하기도 합니다.&lt;br /&gt;
# 프로시져 변수 - 프로시져(중괄호{}) 내부에 선언된 변수. 프로시져 안에서만 쓸 수 있다. 보통 지역변수라고들 많이 이야기한다.&lt;br /&gt;
# 모듈 변수 - 모듈(파일) 내부에 선언된 변수. 그 파일 안에서만 쓸 수 있다.&lt;br /&gt;
# 전역 변수 - 헤더파일에 Public으로 선언한 변수. 다른 모듈에서도 갖다 쓸 수 있다.&lt;br /&gt;
# 정적 변수 - 프로시져 내부에 Static으로 선언하는 변수. 프로시져가 종료되어도 값을 유지한다.&lt;br /&gt;
* 이에 대해 알아보기 위해 간단하게 프로그램을 하나 작성해보도록 하겠습니다.&lt;br /&gt;
[[파일:Qt_1_pro_5.png]]&lt;br /&gt;
[[파일:Qt_1_pro_6.png]]&lt;br /&gt;
* 위와 같이 해놓으면 에러가 발생할 것입니다.&lt;br /&gt;
* 이를 어떻게 해결하냐면, 이걸 헤더 내에 모듈 변수로 선언을 하면 됩니다.&lt;br /&gt;
* 실행해보면 제대로 출력되는걸 볼 수 있을겁니다.&lt;br /&gt;
[[파일:Qt_1_pro_7.png]]&lt;br /&gt;
[[파일:Qt_1_pro_8.png]]&lt;br /&gt;
* const라는 게 있습니다.&lt;br /&gt;
* 상수를 변수처럼 사용할 수 있게 만들어 주는거죠.&lt;br /&gt;
* 예를 들어, 파이값같은걸 쓴다치면, 계속 3.1415926이라는 값을 입력하면 귀찮으니, pi라는 변수처럼 생긴 놈 안에다가 그 값을 넣어두는 겁니다.&lt;br /&gt;
* const 선언을 하게 되면, 그 값을 바꿀 수 없습니다. Ansi-C에서는 #define이라는 전처리기(Preprocessor)를 사용했었는데, C++ 계열에서는 거의 대부분 const로 해결합니다. 이해도 쉽고, const를 쓰는게 좋습니다.&lt;br /&gt;
[[파일:Qt_1_pro_9_.png]]&lt;br /&gt;
[[파일:Qt_1_pro_10_.png]]&lt;br /&gt;
&lt;br /&gt;
=== 연산자 ===&lt;br /&gt;
* 다음과 같이 연산자를 사용할 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int data1;&lt;br /&gt;
int data2;&lt;br /&gt;
&lt;br /&gt;
data1 = 10;&lt;br /&gt;
data2 = 3;&lt;br /&gt;
&lt;br /&gt;
// 산술 연산&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 + data2 = &amp;quot; &amp;lt;&amp;lt; data1 + data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 - data2 = &amp;quot; &amp;lt;&amp;lt; data1 - data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 * data2 = &amp;quot; &amp;lt;&amp;lt; data1 * data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 / data2 = &amp;quot; &amp;lt;&amp;lt; data1 / data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 % data2 = &amp;quot; &amp;lt;&amp;lt; data1 % data2;&lt;br /&gt;
&lt;br /&gt;
// 논리 연산&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; QString(&amp;quot;(data1 &amp;lt; 11) &amp;amp;&amp;amp; (data2 &amp;gt; 2) = %1&amp;quot;).arg((data1 &amp;lt; 11) &amp;amp;&amp;amp; (data2 &amp;gt; 2));&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; QString(&amp;quot;(data1 &amp;lt; 11) || (data2 &amp;lt; 2) = %1&amp;quot;).arg((data1 &amp;lt; 11) || (data2 &amp;lt; 2));&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; QString(&amp;quot;!(data1 &amp;lt; 11) = %1&amp;quot;).arg(!(data1 &amp;lt; 11));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 조건문 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=b-mylI0gTY8&lt;br /&gt;
* if는 다음과 같이 사용할 수 있습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if(조건식) { 명령문; }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 1개의 조건문 예시&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int jumsu;&lt;br /&gt;
&lt;br /&gt;
jumsu = 50;&lt;br /&gt;
&lt;br /&gt;
if(jumsu &amp;lt; 60)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;낙제입니다&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;재수강 신청하세요&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;마감일은 12월 20일입니다&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;낙제가 아닙니다&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;재수강 신청하지 마세요&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;마감일 신경쓰지 마세요&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;점수는 &amp;quot; &amp;lt;&amp;lt; jumsu &amp;lt;&amp;lt; &amp;quot;점 입니다.&amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* elseif 예시&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int jumsu;&lt;br /&gt;
&lt;br /&gt;
jumsu = 50;&lt;br /&gt;
&lt;br /&gt;
if(jumsu &amp;gt;= 90)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;A 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if(jumsu &amp;gt;= 80)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;B 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if(jumsu &amp;gt;= 70)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;C 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if(jumsu &amp;gt;= 60)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;D 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else // elseif가 아님&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;F 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* switch 문은 일반적으로 enum과 함께 쓰입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
enum weekday {&lt;br /&gt;
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int today, yesterday;&lt;br /&gt;
&lt;br /&gt;
today = Saturday;&lt;br /&gt;
&lt;br /&gt;
yesterday = today -1;&lt;br /&gt;
&lt;br /&gt;
switch(yesterday) {&lt;br /&gt;
    case Friday:&lt;br /&gt;
    case Saturday: qDebug() &amp;lt;&amp;lt; &amp;quot;Burning&amp;quot;; break;&lt;br /&gt;
    case Monday: qDebug() &amp;lt;&amp;lt; &amp;quot;What the Hell&amp;quot;; break;&lt;br /&gt;
    default:&lt;br /&gt;
        qDebug(&amp;quot;Groomy Working Day&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* enum은 위와 같이 사용합니다. 자세한 사용법은 구글님께.&lt;br /&gt;
&lt;br /&gt;
=== 반복문 ===&lt;br /&gt;
* for는 다음과 같이 사용합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
for(변수 = 초기값; 최종값에 대한 식; 변수를 어떻게 증감할건지)&lt;br /&gt;
{&lt;br /&gt;
  명령문들;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 예제를 하나 보도록 하죠.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
for(int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
{&lt;br /&gt;
  res += i;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;까지의 합은 &amp;quot; &amp;lt;&amp;lt; res &amp;lt;&amp;lt; &amp;quot;입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* do~while문은 다음과 같이 사용합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  명령문들;&lt;br /&gt;
} while (최종값에 대한 식);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이것도 역시 예제를 위의 for와 같은걸 해보도록 하죠.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int i = 0; // 이처럼 변수 선언을 하면서 초기값을 설정할 수 있습니다.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  i++;&lt;br /&gt;
  res += i;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;까지의 합은 &amp;quot; &amp;lt;&amp;lt; res &amp;lt;&amp;lt; &amp;quot;입니다.&amp;quot;;&lt;br /&gt;
} while (i &amp;lt; 3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 자, for문과 do~while문의 차이점은 뭘까요?&lt;br /&gt;
# for는 괄호 안에 모든 내용을 다 집어넣었지요? 사람들은 반복문을 사용할 때 for를 더 많이 사용하는 이유가 있지요.&lt;br /&gt;
# for는 루프 내에서만 사용되는 변수를 지정할 수 있습니다. while은 미리 변수를 선언해야 하고요.&lt;br /&gt;
# while은 또 한가지 유의할 점이 있습니다. *무조건* 한번은 프로시져가 실행된다는 점이죠.&lt;br /&gt;
=== 배열 ===&lt;br /&gt;
* 프로그램에서 데이터를 임시로 저장하기 위해서 변수를 사용한다는건 아실겁니다.&lt;br /&gt;
* 그런데 변수중에 '배열'이라는걸 들어보셨을거에요.그걸 왜 쓰는지 궁금하실겁니다.&lt;br /&gt;
* 일단 '배열'이라는건 같은 데이터 타입을 가지는 변수의 '집단'이라고 할 수 있습니다.&lt;br /&gt;
* 예를 들어 10개의 과목에 대한 점수를 기억하려면 다음과 같이 10개의 정수형 변수가 필요할 것입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int score1;&lt;br /&gt;
int score2;&lt;br /&gt;
int score3;&lt;br /&gt;
int score4;&lt;br /&gt;
int score5;&lt;br /&gt;
int score6;&lt;br /&gt;
int score7;&lt;br /&gt;
int score8;&lt;br /&gt;
int score9;&lt;br /&gt;
int score10;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 보세요. 보기만 해도 선언도 귀찮고 기억하기도 힘들겠죠?&lt;br /&gt;
* 근데, 이걸 100명분을 작성한다고 칩시다.&lt;br /&gt;
* 이럴땐 다음과 같이 배열로 하면 좀더 쉽게 작성할 수 있습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
타입 변수명[갯수];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 예제를 하나 보죠.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int score[100];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이런식으로 사용합니다. 다음은 1부터 10까지 돌면서 해당 값에 2를 곱해서 저장하는 프로그램입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int score[10];&lt;br /&gt;
for(int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
{&lt;br /&gt;
  score[i] = i * 2;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;i = &amp;quot; &amp;lt;&amp;lt; score[i];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행 결과는 다음과 같을 것입니다.&lt;br /&gt;
[[파일:Qt_2_script_0.png]]&lt;br /&gt;
* 이걸 보고 이상하다는 생각이 들지 않나요?&lt;br /&gt;
* 컴퓨터한테는 첫번째 숫자가 1이 아니라 0입니다.&lt;br /&gt;
* 이걸 1부터 시작해서 10으로 끝나게 만들려면 어떻게 해야 할까요? 한번 고민해보고 만들어보시기 바랍니다. :)&lt;br /&gt;
&lt;br /&gt;
=== 동적 배열 ===&lt;br /&gt;
* 그런데 배열의ㅈㅈ습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int* 변수이름 = new 타입[갯수];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 타입 뒤에 *가 들어갑니다. 중요합니다.&lt;br /&gt;
* 또한, 할당하고 나서 다음과 같이 꼭 해제를 해줘야 합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
delete[] 변수이름;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 요즘 인기있는 언어들이 Garbage Collector를 포함하며, 인터프리터를 지향하고 있는 이유는 해제할 타이밍이 애매한 경우가 많아서입니다.&lt;br /&gt;
* 하지만, 조금 크게 메모리를 할당하거나 하는 방법으로 메모리 해제 타이밍을 잡을 수 있습니다.&lt;br /&gt;
* 또한 QT에서는 QT 데이터타입을 사용하면 내부적으로 Garbage Collector를 적용한다고 합니다.&lt;br /&gt;
* 아무튼 예제를 하나 보도록 하겠습니다. 마찬가지로 위와 같은 프로그램입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int* score = new int[10];&lt;br /&gt;
for(int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
{&lt;br /&gt;
  score[i] = i * 2;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;i = &amp;quot; &amp;lt;&amp;lt; score[i];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 다차원배열 ===&lt;br /&gt;
* 지금까지 본건 1차원 배열입니다.&lt;br /&gt;
* QT를 컴파일하는 gcc의 경우 10차원이 넘는 배열을 선언할 수 있습니다.&lt;br /&gt;
* 간단한 프로그램을 작성해 봅시다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int data[3][5];&lt;br /&gt;
for(int i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
{&lt;br /&gt;
  for(int j = 0; j &amp;lt; 5; j++)&lt;br /&gt;
  {&lt;br /&gt;
    data[i][j] = i * j;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;*&amp;quot; &amp;lt;&amp;lt; &amp;quot;j&amp;quot; &amp;lt;&amp;lt; &amp;quot;=&amp;quot; &amp;lt;&amp;lt; data[i][j];&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 대충 무슨 프로그램인지 보이시지요?&lt;br /&gt;
* 자 이걸 구구단으로 바꿔보세요.&lt;br /&gt;
=== 구조체 ===&lt;br /&gt;
* 구조체는 다음과 같이 사용합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct {&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== 함수 ===&lt;br /&gt;
&lt;br /&gt;
== GUI 기초 및 응용 ==&lt;br /&gt;
=== 컨트롤 ===&lt;br /&gt;
[[파일:Layouts.png]][[파일:Spacers.png]][[파일:Buttons.png]][[파일:Item Views.png]][[파일:Item Widget.png]][[파일:Containers.png]][[파일:Input Widget.png]][[파일:Display Widget.png]]&lt;br /&gt;
=== 프로그램을 작성하는 순서 ===&lt;br /&gt;
* 일반적으로 프로그램은 다음과 같은 순서로 작성합니다.&lt;br /&gt;
# GUI 구상 - 어떤 GUI를 만들 것인지 구상합니다.&lt;br /&gt;
# 객체 배치 - 컨트롤을 사용하여 객체들을 폼 위에 배치합니다.&lt;br /&gt;
# 속성 조절 - 속성창에서 조절할 필요가 있는 속성들을 지정합니다.&lt;br /&gt;
# 슬롯 선택 - 객체별로 필요한 슬롯을 선택하고 코딩을 합니다. 이때 프로그램에서 제어할 필요가 있는 속성은 객체-&amp;gt;속성으로 지정하고, 객체-&amp;gt;메소드나 함수, 명령문을 사용하여 객체의 이벤트를 완성합니다.&lt;br /&gt;
# 디버깅 - 실행을 하고 에러가 있으면 수정을 해서 다시 실행합니다.&lt;br /&gt;
* 물론 이것이 정석적인 방법이라고 볼 수는 없겠습니다만, 일반적인 취향이라고 볼 수 있겠습니다.&lt;br /&gt;
=== 컨트롤을 쉽게 배치하는 방법 ===&lt;br /&gt;
* 폼 위에 객체를 그리다 보면 동일한 객체를 여러개 그려야 하는 경우가 많습니다. 이들의 크기나 위치등을 하나씩 배치할수도 있겠으나, 우리는 도구를 쓰도록 합시다.&lt;br /&gt;
&lt;br /&gt;
[[파일:Qt 2 gui 0.png]]&lt;br /&gt;
[[파일:Qt 2 gui 1.png]]&lt;br /&gt;
[[파일:Qt 2 gui 2.png]]&lt;br /&gt;
p;;;;;&lt;br /&gt;
&lt;br /&gt;
=== QPushButton 컨트롤 사용하기 ===&lt;br /&gt;
* 버튼입니다. 프로그램 만들면 많이들 사용하는 컨트롤이죠.&lt;br /&gt;
* 이 버튼은 대개 누르면 작업이 실행되게 하는 용도로 사용되죠.&lt;br /&gt;
* Enabled라는 속성에 대해 좀 중점적으로 보시면 좋을듯 합니다.&lt;br /&gt;
* 다음과 같은 프로그램을 만들어봅시다.&lt;br /&gt;
[[file:First Qt App.png]]&lt;br /&gt;
* QPushButton 3개와 QLabel 1개를 배치해 봅시다.&lt;br /&gt;
* 그리고 QPushButton에 Clicked 슬롯을 만들고 다음과 같이 작성해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Dialog::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(&amp;quot;하드웨어 지원 최강&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;pushButton-&amp;gt;setEnabled(false);&lt;br /&gt;
    ui-&amp;gt;pushButton_2-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_3-&amp;gt;setEnabled(true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Dialog::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(&amp;quot;유저가 최강&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;pushButton-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_2-&amp;gt;setEnabled(false);&lt;br /&gt;
    ui-&amp;gt;pushButton_3-&amp;gt;setEnabled(true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Dialog::on_pushButton_3_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(&amp;quot;스타벅스 가냐?&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;pushButton-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_2-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_3-&amp;gt;setEnabled(false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 유의할 점은 void Dialog::on_pushButton_clicked() &amp;lt;- 이 부분은 직접 코딩하는게 &amp;lt;b&amp;gt;아닙니다!!&amp;lt;/b&amp;gt;&lt;br /&gt;
* 슬롯을 전부 만드시고 위와 같이 코드를 작성하셨다면 누른 버튼이 비활성화되는게 보이실겁니다.&lt;br /&gt;
&lt;br /&gt;
=== QLineEdit 컨트롤 사용하기 ===&lt;br /&gt;
* 주로 주관식 데이터를 입력하기 위해 많이 사용하는 LineEdit 컨트롤을 지정해 봅시다.&lt;br /&gt;
* 성적을 계산하는 프로그램인데, 텍스트상자를 이용해서 이름과 점수를 입력합니다.&lt;br /&gt;
* 다음과 같은 프로그램을 만들 것입니다.&lt;br /&gt;
[[파일:Qt_App_2.png]]&lt;br /&gt;
* Grid Layout을 이용하면 의외로 간단하게 화면 구성이 가능합니다.&lt;br /&gt;
* 다음과 같이 그리드 레이아웃을 만들고 왼쪽에는 Label을, 오른쪽에는 LineEdit를 드래그해서 집어넣습니다.&lt;br /&gt;
[[파일:Qt_2_drag_drop_0.png]]&lt;br /&gt;
[[파일:Qt_2_drag_drop_1.png]]&lt;br /&gt;
[[파일:Qt_2_drag_drop_2.png]]&lt;br /&gt;
* 그리고 버튼도 Horizontal Layout을 이용하면 쉽게 배열이 가능합니다.&lt;br /&gt;
* 레이블과 버튼, 라인에디트를 배열하고 각각 속성에서 제목을 적어줍니다.&lt;br /&gt;
* 헤더파일에 QDebug를 include하고, 다음과 같이 변수를 선언해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QString name;&lt;br /&gt;
int kor;&lt;br /&gt;
int eng;&lt;br /&gt;
int math;&lt;br /&gt;
&lt;br /&gt;
int total;&lt;br /&gt;
int avg;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 각 버튼의 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    name = ui-&amp;gt;lineEdit-&amp;gt;text();&lt;br /&gt;
    kor = ui-&amp;gt;lineEdit_2-&amp;gt;text().toInt();&lt;br /&gt;
    eng = ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt();&lt;br /&gt;
    math = ui-&amp;gt;lineEdit_4-&amp;gt;text().toInt();&lt;br /&gt;
    total = kor + eng + math;&lt;br /&gt;
    avg = total /3;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; &amp;quot;이름      국어 영어 수학 총점 평균&amp;quot;;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; name &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; kor &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; eng &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; math &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; total &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; avg;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실제 입력에 따라 다음과 같이 결과가 출력되는걸 볼 수 있습니다.&lt;br /&gt;
결과 나오는 화면&lt;br /&gt;
[[파일:Qt_App_2_Result.png]]&lt;br /&gt;
&lt;br /&gt;
=== QCheckBox 컨트롤 사용하기 ===&lt;br /&gt;
* 체크박스는 체크 표시된 항목을 선택하는 기능을 제공합니다.&lt;br /&gt;
* 아마도 웹사이트에서 많이 보셨을겁니다.&lt;br /&gt;
* 이것의 특징은, 라디오버튼과 달리 여러개의 항목을 동시에 선택할 수 있다는 겁니다.&lt;br /&gt;
* 남자가 결혼하기 전에 사야 할 물품을 정리해 보았습니다.&lt;br /&gt;
* 폼에 판매 품목과 가격을 체크상자로 표시하고, 소비자가 상자를 선택하고 총액계산 버튼을 누르면 텍스트 상자에 총액이 표시되도록 하는것이 목표입니다.&lt;br /&gt;
실행 화면&lt;br /&gt;
&lt;br /&gt;
[[파일:checkbox_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 헤더에 변수를 하나 선언합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int sum;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 위 폼은 쉽게 만들 수 있을것이라 생각하고, 각 버튼의 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    sum = 0;&lt;br /&gt;
    if(ui-&amp;gt;checkBox-&amp;gt;isChecked())&lt;br /&gt;
        sum += 650000;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_2-&amp;gt;isChecked())&lt;br /&gt;
        sum += 550000;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_3-&amp;gt;isChecked())&lt;br /&gt;
        sum += 150000;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_4-&amp;gt;isChecked())&lt;br /&gt;
        sum += 250000;&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(QString::number(sum));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;checkBox-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_2-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_3-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_4-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 체크버튼을 누르면 바로 적용되도록 만들 수 있을 것입니다.&lt;br /&gt;
* 이건 직접 해보시는게 어떨까요?&lt;br /&gt;
&lt;br /&gt;
=== QRadioButton 컨트롤 사용하기 ===&lt;br /&gt;
* 라디오버튼은 옵션 버튼이라고도 합니다.&lt;br /&gt;
* 체크 상자와 비슷하게 항목을 선택할 때 사용되지만, 옵션 버튼은 여러개 중에서 한개만 선택할 수 있는데에 많이 사용됩니다.&lt;br /&gt;
* 체크버튼가지고도 코드 부분을 좀 수정하면 라디오버튼과 같은 동작을 하게 만들수 있습니다.&lt;br /&gt;
* 특정 버튼을 선택했다가 다른 버튼을 선택하면 이전에 선택했던 버튼의 체크표시는 지워집니다.&lt;br /&gt;
* 아래 프로그램을 한번 만들어 보도록 하겠습니다. 라디오버튼과 체크버튼을 같이 쓰니까 비교하기가 쉬울겁니다.&lt;br /&gt;
[[파일:Qt_3_result_0.png]]&lt;br /&gt;
* 자신의 연령대를 선택하고 연애인을 선택한 후 결과보기 버튼을 누르면 텍스트 상자에 결과가 표시됩니다.&lt;br /&gt;
* 다시보기 버튼을 누르면 내용이 싹 지워져서 새로 선택하기 편하도록 편의성을 높였습니다.&lt;br /&gt;
* 헤더에 추가할 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QString age;&lt;br /&gt;
QString singer;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드에 추가할 내용입니다. PushButton에 슬롯으로 작성하는건 이제 다들 익숙해지셨으리라 생각합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    singer = &amp;quot;&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;10대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_2-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;20대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_3-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;30대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_4-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;40대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_5-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;외계인&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;소녀시대 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_2-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;2ne1 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_3-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;이선희 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_4-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;걸스데이 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_5-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;EXO &amp;quot;;&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(age + &amp;quot;인 당신은 &amp;quot; + singer +&amp;quot;를 좋아하네요.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;radioButton-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_2-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_3-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_4-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_5-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_2-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_3-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_4-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_5-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QGroupBox ===&lt;br /&gt;
* 그룹박스는 다른 객체들을 묶는 역할을 합니다.&lt;br /&gt;
* 다른 여러 프로그램상에서 많이들 보셨을겁니다.&lt;br /&gt;
* 이건 말보다 프로그램을 직접 보시는게 나을듯.&lt;br /&gt;
실행화면&lt;br /&gt;
&lt;br /&gt;
[[파일:QGroupBox_1.png]]&lt;br /&gt;
&lt;br /&gt;
[[파일:QGroupBox_2.png]]&lt;br /&gt;
&lt;br /&gt;
* 보시면 2개의 그룹박스를 사용하고 있습니다.&lt;br /&gt;
* PC 보유현황과 주변장치현황이 프레임입니다.&lt;br /&gt;
* 나머지 내용은 위의 QRadiobutton강좌와 같다고 보시면 됩니다.&lt;br /&gt;
* 헤더에는 변수를 선언해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QString com;&lt;br /&gt;
QString phr;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 다음은 버튼에 관한 코드입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    phr = &amp;quot;&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;radioButton_2-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton_2-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;radioButton_3-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton_3-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;radioButton_4-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton_4-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox_2-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox_2-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox_3-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox_3-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox_4-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox_4-&amp;gt;text();&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;당신은 &amp;quot; + com + &amp;quot;컴퓨터와 &amp;quot; + phr + &amp;quot;주변장치를 보유중입니다.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QListWidget ===&lt;br /&gt;
* ListWidget 컨트롤은 상자 안에 항목들을 나열하는 기능을 제공합니다.&lt;br /&gt;
* 이거랑 ComboBoxWidget이 목록을 제공하는 대표적인 컨트롤입니다.&lt;br /&gt;
* ListWidget은 여러개의 항목 선택을 할 수 있도록 되어 있으며, Shift나 Ctrl등을 이용해서 선택할 수 있도록 되어 있습니다.&lt;br /&gt;
[[파일:listwidget_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 코드는 매우 간단합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;listWidget-&amp;gt;addItem(ui-&amp;gt;lineEdit-&amp;gt;text());&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QComboBox ===&lt;br /&gt;
* 콤보박스 컨트롤은 펼침 목록 기능을 제공합니다.&lt;br /&gt;
* 웹사이트를 방문해보면 주소 입력하는데 대부분 이거 씁니다.&lt;br /&gt;
* 프로그래밍에서도 종종 씁니다.&lt;br /&gt;
* ListWidget과 사용법은 비슷합니다.&lt;br /&gt;
결과화면&lt;br /&gt;
&lt;br /&gt;
[[파일:combobox_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 이번에는 버튼을 만들지 않고, 콤보박스의 내용이 변경되는 즉시 반영되도록 해봅시다.&lt;br /&gt;
* 슬롯 선택시 다음과 같이 선택하세요.&lt;br /&gt;
[[파일:combobox_slot.png]]&lt;br /&gt;
* 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_comboBox_currentIndexChanged(int index)&lt;br /&gt;
{&lt;br /&gt;
    if(index == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;연남동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;서교동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;동교동&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if(index == 1)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;삼청동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;사직동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;계동&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if(index == 2)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;신사동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;논현동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;도곡동&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_comboBox_2_currentIndexChanged(int index)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;선택된 주소는 &amp;quot; + ui-&amp;gt;comboBox-&amp;gt;currentText() + &amp;quot; &amp;quot; + ui-&amp;gt;comboBox_2-&amp;gt;currentText() + &amp;quot;입니다.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Slider &amp;amp; Dial ===&lt;br /&gt;
* 슬라이더를 봅시다.&lt;br /&gt;
* 각각의 슬라이더의 값 변화에 따라 레이블도 변화하도록 해봅시다.&lt;br /&gt;
* Dial은 꼭 옛날 전축에 있던거랑 비슷하게 생겼지요?&lt;br /&gt;
결과화면&lt;br /&gt;
&lt;br /&gt;
[[파일:sliders_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 슬롯 하나하나마다 다음과 같이 슬롯을 작성하고&lt;br /&gt;
슬롯 선택&lt;br /&gt;
* 코드는 다음과 같이 작성하면 된다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_horizontalScrollBar_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
    ui-&amp;gt;dial-&amp;gt;setValue(value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_horizontalSlider_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label_2-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_verticalScrollBar_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label_3-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_verticalSlider_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label_4-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QTimer ===&lt;br /&gt;
* 타이머는 시간과 관련된 컨트롤입니다.&lt;br /&gt;
* 다음과 같이 시계를 만들어 보도록 하겠습니다.&lt;br /&gt;
실행화면&lt;br /&gt;
&lt;br /&gt;
[[파일:clock_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 시계는 코드에 직접 작성해 주어야 합니다.&lt;br /&gt;
* 헤더파일에 QTimer와 QDateTime을 include해줍니다.&lt;br /&gt;
* QTimer는 타이머고, QDateTime은 현재시각을 받아오기 위해 사용합니다.&lt;br /&gt;
* private:에 timer를 하나 선언하고, private slots:에 tupdate() 함수를 등록해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
    QTimer* timer;&lt;br /&gt;
&lt;br /&gt;
private slots:&lt;br /&gt;
    int tupdate();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 프로그램이 실행되면서 타이머가 동작하도록 아래의 코드를 메인 위젯 안에 넣어줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
timer = new QTimer(this); // 타이머 생성&lt;br /&gt;
connect(timer, SIGNAL(timeout()), this, SLOT(tupdate())); // 타이머가 타임아웃이 되면 tupdate()를 호출&lt;br /&gt;
timer-&amp;gt;start(1000); // 1000은 밀리세컨드 단위. 타임아웃을 몇 ms로 할것인지 정함. 여기서는 1초마다 한번씩.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 그리고, tupdate() 함수를 다음과 같이 작성합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int Widget::tupdate()&lt;br /&gt;
{&lt;br /&gt;
    QDateTime local(QDateTime::currentDateTime());&lt;br /&gt;
    ui-&amp;gt;label_3-&amp;gt;setText(local.toString());&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QFileDialog ===&lt;br /&gt;
* 파일 컨트롤은 파일을 선택하거나, 파일을 저장할 때에 많이 사용되는 컨트롤입니다.&lt;br /&gt;
* 이건 기본 컨트롤엔 없으나, 사용 빈도가 굉장히 높습니다.&lt;br /&gt;
실행화면&lt;br /&gt;
&lt;br /&gt;
[[파일:file_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 파일 다이얼로그를 사용하기 위해서는 QFileDialog를 include해야 합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;QFileDialog&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 그리고 버튼에 대한 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QString file = QFileDialog::getOpenFileName();&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(file);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 파일 컨트롤도 참 쉽죠?&lt;br /&gt;
* 속성도 지정할 수 있습니다. png 파일만 연다든지.. 이 부분은 직접 해보세요 :)&lt;br /&gt;
=== QGraphicsView ===&lt;br /&gt;
* GraphicsView는 각종 도형, 텍스트 등을 좀 더 유연하게 사용할 수 있도록 만들어진 Canvas같은 개념의 컨트롤입니다.&lt;br /&gt;
* 단독으로는 아무것도 할 수 없고, GraphicsScene과 함께 동작합니다.&lt;br /&gt;
* 그림파일을 하나 불러와 보여주는 프로그램을 작성해 보겠습니다.&lt;br /&gt;
[[파일:Qt graphic result.png]]&lt;br /&gt;
* 헤더파일의 수정은 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// 헤더를 include해줍니다.&lt;br /&gt;
#include &amp;lt;QGraphicsScene&amp;gt;&lt;br /&gt;
#include &amp;lt;QPixmap&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// private 선언부에 scene 변수를 선언해 둡니다.&lt;br /&gt;
QGraphicsScene scene;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Widget 안 setupUi 이후에 다음과 같은 코드를 삽입합니다.&lt;br /&gt;
    QPixmap pix(&amp;quot;hello.png&amp;quot;);&lt;br /&gt;
    scene.addPixmap(pix);&lt;br /&gt;
    ui-&amp;gt;graphicsView-&amp;gt;setScene(&amp;amp;scene);&lt;br /&gt;
    ui-&amp;gt;graphicsView-&amp;gt;show();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 실행파일과 같은 디렉토리에 hello.png (png 파일 아무거나 넣어보세요)가 있다면 그 그림파일이 출력될 것입니다.&lt;br /&gt;
* 과제 : 전에 배운 FileOpenDialog를 이용해서, 파일을 선택해 보여줄 수 있도록 만들어 봅시다.&lt;br /&gt;
=== QTabWidget ===&lt;br /&gt;
* 탭 컨트롤에 대해 알아보겠습니다.&lt;br /&gt;
* 보통, 설정같이 내용은 많고, 각각의 성격에 따라 분류하고 싶을 경우 많이들 사용합니다.&lt;br /&gt;
* 코드로 작성하기보다는 일반적으로 디자인에서 다 하는 경우가 많습니다.&lt;br /&gt;
[[파일:Settings-ss00.png]]&lt;br /&gt;
=== QProgressBar ===&lt;br /&gt;
* 프로그레스바에 대해 알아보도록 하겠습니다.&lt;br /&gt;
* 가짜로 만든 로딩바 입니다.&lt;br /&gt;
[[파일:Progressbar-ss00.png]]&lt;br /&gt;
* 헤더는 다음과 같습니다&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// QTimer를 include해줍니다&lt;br /&gt;
#include &amp;lt;QTimer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// 함수 정의에 다음과 같이 해줍니다.&lt;br /&gt;
private:&lt;br /&gt;
    Ui::Widget *ui;&lt;br /&gt;
    QTimer* timer;&lt;br /&gt;
    int tick;&lt;br /&gt;
&lt;br /&gt;
private slots:&lt;br /&gt;
    int tupdate();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// setupUi 다음에 넣어줍니다.&lt;br /&gt;
    timer = new QTimer(this);&lt;br /&gt;
    connect(timer, SIGNAL(timeout()), this, SLOT(tupdate()));&lt;br /&gt;
    tick = 0;&lt;br /&gt;
    timer-&amp;gt;start(10);&lt;br /&gt;
&lt;br /&gt;
// tupdate 함수는 다음과 같습니다.&lt;br /&gt;
int Widget::tupdate()&lt;br /&gt;
{&lt;br /&gt;
    if(tick == 100) ui-&amp;gt;label-&amp;gt;setText(&amp;quot;Loading Complete&amp;quot;);&lt;br /&gt;
    if(tick &amp;lt; 100) tick++;&lt;br /&gt;
    ui-&amp;gt;progressBar-&amp;gt;setValue(tick);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 계산기 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=3FT3c7mFQFI&lt;br /&gt;
* 흔히 집에 하나씩 있는 천원짜리 계산기를 한번 만들어 보도록 하겠습니다.&lt;br /&gt;
[[파일:calculator_result.png]]&lt;br /&gt;
*새로운 개념이 추가된 것은 없습니다. 기존에 배운 개념을 활용하여 만들 수 있습니다.&lt;br /&gt;
*소스코드는 아래와 같습니다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_1_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;2&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;2&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_3_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;3&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;3&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_4_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;4&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;4&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_5_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;5&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;5&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_6_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;6&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;6&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_7_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;7&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;7&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_8_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;8&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;8&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_9_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;9&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;9&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_11_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;10&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;10&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_10_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;lineEdit_3-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;lineEdit_4-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_13_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;+&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_14_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;-&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_15_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;*&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_16_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;/&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_12_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;+&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) + ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
    else if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;-&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) - ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
    else if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;*&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) * ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
    else if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;/&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) / ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 파일 다루기 ==&lt;br /&gt;
=== 메모장 프로그램 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=5wbMaH50GdM&lt;br /&gt;
* 메모장 프로그램을 한번 만들어 봅시다.&lt;br /&gt;
[[파일:Editor_result.png]]&lt;br /&gt;
* 간단하게 만들어 본 프로그램입니다.&lt;br /&gt;
* TextEdit 컨트롤과 ListWidget 컨트롤, PushButton 컨트롤을 사용하였습니다.&lt;br /&gt;
* 헤더파일에 추가할 내용은 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// 헤더 include&lt;br /&gt;
#include &amp;lt;QFileDialog&amp;gt;&lt;br /&gt;
#include &amp;lt;QMessageBox&amp;gt;&lt;br /&gt;
// Private 변수&lt;br /&gt;
    QDir dir;&lt;br /&gt;
    QFileInfoList list;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_4_clicked()&lt;br /&gt;
{&lt;br /&gt;
    dir = QFileDialog::getExistingDirectory();&lt;br /&gt;
    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);&lt;br /&gt;
    ui-&amp;gt;listWidget-&amp;gt;clear();&lt;br /&gt;
    list = dir.entryInfoList();&lt;br /&gt;
    for (int i = 0; i &amp;lt; list.size(); ++i) {&lt;br /&gt;
        QFileInfo fileInfo = list.at(i);&lt;br /&gt;
        ui-&amp;gt;listWidget-&amp;gt;addItem(QString(&amp;quot;%1&amp;quot;).arg(fileInfo.fileName()));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QString path, filename;&lt;br /&gt;
    filename = QString(&amp;quot;%1&amp;quot;).arg(list.at(ui-&amp;gt;listWidget-&amp;gt;currentIndex().row()).absoluteFilePath());&lt;br /&gt;
    QFile file(filename);&lt;br /&gt;
    file.open(QIODevice::ReadOnly);&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;clear();&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;append(file.readAll());&lt;br /&gt;
    file.close();&lt;br /&gt;
    QMessageBox msgbox;&lt;br /&gt;
    msgbox.setText(&amp;quot;File Opened&amp;quot;);&lt;br /&gt;
    msgbox.exec();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QString path, filename;&lt;br /&gt;
    filename = QString(&amp;quot;%1&amp;quot;).arg(list.at(ui-&amp;gt;listWidget-&amp;gt;currentIndex().row()).absoluteFilePath());&lt;br /&gt;
    QFile file(filename + &amp;quot;.text&amp;quot;);&lt;br /&gt;
    QByteArray bytearray = ui-&amp;gt;textEdit-&amp;gt;toPlainText().toUtf8().left(ui-&amp;gt;textEdit-&amp;gt;toPlainText().length());&lt;br /&gt;
    file.open(QIODevice::WriteOnly);&lt;br /&gt;
    file.write(bytearray);&lt;br /&gt;
    file.close();&lt;br /&gt;
    QMessageBox msgbox;&lt;br /&gt;
    msgbox.setText(&amp;quot;File Saved&amp;quot;);&lt;br /&gt;
    msgbox.exec();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_3_clicked()&lt;br /&gt;
{&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_listWidget_doubleClicked(const QModelIndex &amp;amp;index)&lt;br /&gt;
{&lt;br /&gt;
    QString path, filename;&lt;br /&gt;
    filename = QString(&amp;quot;%1&amp;quot;).arg(list.at(index.row()).absoluteFilePath());&lt;br /&gt;
    QFile file(filename);&lt;br /&gt;
    file.open(QIODevice::ReadOnly);&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;clear();&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;append(file.readAll());&lt;br /&gt;
    file.close();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 좀 길어보이긴 하지만 다 했던 내용입니다.&lt;br /&gt;
* 연습문제 : 상단 메뉴바가 있는 MainWindow 프로그램으로 변환해 보세요.&lt;br /&gt;
&lt;br /&gt;
== 데이터베이스 다루기 ==&lt;br /&gt;
* sqlite를 이용하여 간단한 일기장을 만들어 보도록 하겠습니다.&lt;br /&gt;
[[파일:simple_diary_result.png]]&lt;br /&gt;
* QT에서는 기본적으로 sqlite3를 지원해 줍니다.&lt;br /&gt;
* ubuntu에서는 기본으로 sqlite2지만, sqlite3를 설치하면 됩니다.&lt;br /&gt;
* SQL 관련 내용을 사용하기 위해서는 pro 파일도 수정해야 합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QT       += core gui sql&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 위와 같이 sql을 추가해 줍니다.&lt;br /&gt;
* 추가하지 않으면 헤더를 추가해도 라이브러리가 참조되지 않아, 컴파일 에러가 납니다. 꼭 추가해 주어야 합니다.&lt;br /&gt;
* 이제, 헤더에 다음과 같은 내용을 추가합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// 헤더 include&lt;br /&gt;
#include &amp;lt;QtSql/QtSql&amp;gt;&lt;br /&gt;
// private 변수&lt;br /&gt;
    QSqlDatabase db;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* sql 파일의 위치는 이따 소스코드에 직접 지정해 주세요.&lt;br /&gt;
* sql 파일은 sqlite3에서 다음과 같은 명령어로 생성하였습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sqlite&amp;gt; create table note ( id INTEGER PRIMARY KEY AUTOINCREMENT, date text, title text, content text);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_calendarWidget_clicked(const QDate &amp;amp;date)&lt;br /&gt;
{&lt;br /&gt;
    qWarning() &amp;lt;&amp;lt; date.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pbOpen_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QSqlQuery query;&lt;br /&gt;
    QString exeq;&lt;br /&gt;
&lt;br /&gt;
    int exist = 0;&lt;br /&gt;
&lt;br /&gt;
    query.clear();&lt;br /&gt;
    exeq = &amp;quot;select * from note where date ='&amp;quot; + ui-&amp;gt;calendarWidget-&amp;gt;selectedDate().toString() + &amp;quot;';&amp;quot;;&lt;br /&gt;
    query.exec(exeq);&lt;br /&gt;
    while(query.next())&lt;br /&gt;
    {&lt;br /&gt;
        QString date = query.value(0).toString();&lt;br /&gt;
        ui-&amp;gt;leTitle-&amp;gt;setText(query.value(&amp;quot;title&amp;quot;).toString());&lt;br /&gt;
        ui-&amp;gt;teContent-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;teContent-&amp;gt;appendPlainText(query.value(&amp;quot;content&amp;quot;).toString());&lt;br /&gt;
        exist = 1;&lt;br /&gt;
    }&lt;br /&gt;
    if(!exist)&lt;br /&gt;
        qWarning() &amp;lt;&amp;lt; &amp;quot;None&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pbExit_clicked()&lt;br /&gt;
{&lt;br /&gt;
    db.close();&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pbSave_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QSqlQuery query;&lt;br /&gt;
    QString exeq;&lt;br /&gt;
&lt;br /&gt;
    query.clear();&lt;br /&gt;
    exeq = &amp;quot;insert into note (date, title, content) values ('&amp;quot; + ui-&amp;gt;calendarWidget-&amp;gt;selectedDate().toString()+&amp;quot;', '&amp;quot;+ui-&amp;gt;leTitle-&amp;gt;text()+&amp;quot;', '&amp;quot;+ui-&amp;gt;teContent-&amp;gt;toPlainText()+&amp;quot;');&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 연습문제 : 노트패드의 경우와 같이, 메뉴가 되어 있는 프로그램으로 변경해 봅시다. 데이터베이스 생성도 같이.&lt;br /&gt;
&lt;br /&gt;
== 네트워크 프로그래밍 ==&lt;br /&gt;
=== 채팅 ===&lt;br /&gt;
* 네트워크 어플리케이션의 시작은 채팅 프로그램입니다.&lt;br /&gt;
* 아래 파일은 서버 / 클라이언트가 함께 동작하는 예제 프로그램입니다.&lt;br /&gt;
[[File:qt-network-chat.zip]]&lt;/div&gt;</summary>
		<author><name>122.36.132.209</name></author>
	</entry>
	<entry>
		<id>https://old.wiki.ubuntu-kr.org/index.php?title=GUI(QT)_Programming&amp;diff=2815</id>
		<title>GUI(QT) Programming</title>
		<link rel="alternate" type="text/html" href="https://old.wiki.ubuntu-kr.org/index.php?title=GUI(QT)_Programming&amp;diff=2815"/>
		<updated>2017-11-17T05:41:00Z</updated>

		<summary type="html">&lt;p&gt;122.36.132.209: /* QT란 무엇인가? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== QT란 무엇인가? ==&lt;br /&gt;
* 리눅스나 유닉스에서 X-Window용 프로그램을 개발하려면 많은 지식이 필요하다.&lt;br /&gt;
* 다음과 같은 특징이 있다.&lt;br /&gt;
# C++ 기반 - 고급 언어들에 비해 어느정도 속도도 나오고, C에 비하면 좀더 모듈화가 되어 있어 확장이 용이&lt;br /&gt;
# 객체지향 - 라이브러리들이 모듈화가 잘 되어 있음&lt;br /&gt;
# 멀티플랫폼 - 다양한 플랫폼을 지원하고, 플랫폼이 바뀐다고 해서 전체를 싹 갈아엎지 않아도 된다.&lt;br /&gt;
# 시그널 &amp;amp; 슬롯 - 이벤트 처리 모델이 정형화되어 있다. 즉, 시그널 &amp;amp; 슬롯만 알면 콜백함수 등 실수할 여지가 줄어든다.&lt;br /&gt;
# Internationalization - 16비트 유니코드 완벽지원.&lt;br /&gt;
# API - 200개가 넘는 클래스를 지원한다. 웬만한 프로그램은 QT 안에 있는 라이브러리들로 해결 가능.&lt;br /&gt;
# 안정성 - 기업 베이스다. 개발은 아무나 할 수 있지만 커밋은 기업 내에서 이루어진다. 일반적으로 산으로 가는 프로젝트를 만들지 않는다.&lt;br /&gt;
&lt;br /&gt;
== QT 프로그램 구경하기 ==&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=VsT1yKRKkXE&amp;amp;list=PLumkkj1MBmYs-WArrEkw2R6wO9Agj3FoX&lt;br /&gt;
* QT 프로그램은 Ubuntu의 경우 소프트웨어센터에서 설치할 수 있다.&lt;br /&gt;
[[파일:Qt_1_install.png]]&lt;br /&gt;
* 새 프로젝트(New Project)를 선택하면 다음과 같은 화면이 나온다.&lt;br /&gt;
[[파일:Qt_1_new.png]]&lt;br /&gt;
* 위젯 어플리케이션을 선택하면 다음과 같은 화면이 나온다.&lt;br /&gt;
* 프로젝트 이름을 정하고 컴파일 키트를 선택한다.&lt;br /&gt;
# 프로젝트 이름은 임의로 작성하고, 컴파일 키트는 기본 옵션으로 설정하면 된다.&lt;br /&gt;
* 클래스 설정 화면은 다음과 같다.&lt;br /&gt;
# Base Class를 다음과 같이 QDialog로 변경한다.&lt;br /&gt;
[[파일:Qt_1_new_1.png]]&lt;br /&gt;
* Github 등을 사용한다면 본인 계정 등을 설정하도록 한다. 이 내용은 [[QT/Github]] 항목을 참조.&lt;br /&gt;
* 여기서는 그냥 버전컨트롤 없이 진행해도 상관없다.&lt;br /&gt;
* Form에 *.ui 를 더블클릭하여 선택하면 다음과 같이 디자이너 모드로 변경된다.&lt;br /&gt;
* 어디서 많이 보던것 같지 않은가? Visual Studio의 편집 화면과 비슷하다. Microsoft Visual Studio를 사용해본 경험이 있다면 거의 비슷하게 사용할 수 있다.&lt;br /&gt;
[[파일:Qt_1_newWin_0.png]]&lt;br /&gt;
* 자, 이제 버튼과 텍스트박스를 집어넣어봅시다.&lt;br /&gt;
* 왼쪽에 있는 컴포넌트에서 드래그해서 넣을 수 있다.&lt;br /&gt;
[[파일:Qt_1_Intro_0.png]]&lt;br /&gt;
* PushButton의 이름을 바꾸는건 간단하다. PushButton 항목을 선택하고, 오른쪽 속성창의 값을 변경해주면 끝.&lt;br /&gt;
[[파일:Qt_1_Intro_1.png]]&lt;br /&gt;
* 화면 구성을 했으니 버튼에 이벤트를 넣어봅시다.&lt;br /&gt;
# 인사하기에서 우클릭을 하고 Go to Slot을 선택합니다.&lt;br /&gt;
[[파일:Qt_1_Intro_2.png]]&lt;br /&gt;
# Go to Slot을 선택하면 다음과 같은 내용이 나옵니다.&lt;br /&gt;
[[파일:Qt_1_Intro_2_1.png ]]&lt;br /&gt;
# Clicked를 선택하면 코드 입력 부분이 나오는데, 다음과 같이 입력합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;Hello World&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# 지우기 부분 코드&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
# 종료하기 부분 코드&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
this.close();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 기본 문법 ==&lt;br /&gt;
=== 변수와 상수 사용하기 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=tHzPBCUi0G8&amp;amp;list=PLumkkj1MBmYs-WArrEkw2R6wO9Agj3FoX&lt;br /&gt;
* 변수는 프로그램 내에서 수시로 값이 (변)할수 있는 (수)를 말합니다. 반면에 상수는 항(상) 같은 값을 유지하는 (수)를 말하는거죠.&lt;br /&gt;
* 프로젝트를 하나 만들고 시작해 보겠습니다.&lt;br /&gt;
[[파일:Qt 1 pro 0.png]]&lt;br /&gt;
* C++의 경우 변수를 사용하기 위해서는 선언을 해야 합니다. 일반적으로 헤더파일에 선언을 하죠. 여기서는 data라는 변수를 추가해 보겠습니다.&lt;br /&gt;
* 또한, 값을 확인하기 위한 디버그 모듈을 사용할 것입니다.&lt;br /&gt;
* 헤더에 QDebug를 사용한다고 선언하고, 정수형 data를 미리 선언합니다.&lt;br /&gt;
[[파일:Qt_1_pro_1.png]]&lt;br /&gt;
* 그리고, 다이얼로그가 열릴 때 처리될 수 있도록 다음과 같이 코드를 넣어주면 됩니다.&lt;br /&gt;
* qDebug() 함수를 사용할 때, 앞에 q는 소문자임에 유의해 주세요. qDebug() 함수는 c++의 cout과 같은 기능을 한다고 보시면 됩니다.&lt;br /&gt;
* 실행하면 아래 디버그 창에 값이 출력되는걸 확인할 수 있습니다.&lt;br /&gt;
[[파일:Qt_1_pro_2.png]]&lt;br /&gt;
* 여기서 사용된 data는 사용자가 임의로 만들 수 있는 변수입니다. 변수는 프로그램 내에서 숫자나 문자 등을 보관하는 역할을 합니다.&lt;br /&gt;
* 변수는 필요에 따라 얼마든지 만들어 사용할 수 있습니다.&lt;br /&gt;
* = 기호는 수학의 등호가 아닙니다. 오른쪽의 값을 왼쪽의 변수에 기억시키는 (또는 할당하는) 연산자입니다.&lt;br /&gt;
* 위의 프로그램에서 data 변수는 처음에 100을 기억했다가 다시 200을 기억합니다.&lt;br /&gt;
* 이와 같이 변수는 다른 값을 가질 수 있습니다. 그래서 변수입니다.&lt;br /&gt;
* 그에 반해 100이나 200같은 숫자는 상수라고 합니다. 이 숫자들은 프로그램이 아무리 실행되어도 항상 100과 200을 유지합니다. 그래서 상수입니다.&lt;br /&gt;
* 이제 여러가지 형식의 변수를 선언하고 이용해보도록 하겠습니다.&lt;br /&gt;
[[파일:Qt_1_pro_3.png]]&lt;br /&gt;
[[파일:Qt_1_pro_4.png]]&lt;br /&gt;
* 정수형 변수 dataint는 정수를 기억합니다. 컴퓨터가 가장 빠른 연산을 할 수 있는 데이터형입니다. &amp;lt;s&amp;gt;요새 컴퓨터는 존나 빨라서 뭘 써도 안느림&amp;lt;/s&amp;gt;&lt;br /&gt;
* 실수형 변수 datadou는 소수점 이하의 수를 기억합니다. 내부적으로는 지수 형태로 기억하지만, 일반적으로 소숫점이 있는 수를 저장할 때 많이 사용합니다.&lt;br /&gt;
* 논리형 변수 databoo는 true와 false 논리 상수를 기억합니다. 일반적으로 flag같은 값을 많이들 저장합니다. &amp;lt;s&amp;gt;근데 왜 64비트나 처먹어&amp;lt;/s&amp;gt;&lt;br /&gt;
* 문자열형 변수 datastr은 할당할 문자열을 반드시 겹따옴표 사이에 기술해야 합니다. 문자열은 문자의 집합을 의미합니다.&lt;br /&gt;
* 변수의 종류를 말할 때 위와 같이 데이터형에 따라 정수형 변수, 실수형 변수, 문자열형 변수, ...와 같이 구분합니다. 근데 또 다른 관점에서 구분하는 경우도 있습니다.&lt;br /&gt;
* 변수가 영향을 미치는 유효 범위에 따라 다음과 같이 구분하기도 합니다.&lt;br /&gt;
# 프로시져 변수 - 프로시져(중괄호{}) 내부에 선언된 변수. 프로시져 안에서만 쓸 수 있다. 보통 지역변수라고들 많이 이야기한다.&lt;br /&gt;
# 모듈 변수 - 모듈(파일) 내부에 선언된 변수. 그 파일 안에서만 쓸 수 있다.&lt;br /&gt;
# 전역 변수 - 헤더파일에 Public으로 선언한 변수. 다른 모듈에서도 갖다 쓸 수 있다.&amp;lt;s&amp;gt;이딴거 쓰지 말라고 승질 뻗치니까...&amp;lt;/s&amp;gt;&lt;br /&gt;
# 정적 변수 - 프로시져 내부에 Static으로 선언하는 변수. 프로시져가 종료되어도 값을 유지한다.&lt;br /&gt;
* 이에 대해 알아보기 위해 간단하게 프로그램을 하나 작성해보도록 하겠습니다.&lt;br /&gt;
[[파일:Qt_1_pro_5.png]]&lt;br /&gt;
[[파일:Qt_1_pro_6.png]]&lt;br /&gt;
* 위와 같이 해놓으면 에러가 발생할 것입니다.&amp;lt;s&amp;gt;햄보칼수가 없어&amp;lt;/s&amp;gt;&lt;br /&gt;
* 이를 어떻게 해결하냐면, 이걸 헤더 내에 모듈 변수로 선언을 하면 됩니다.&lt;br /&gt;
* 실행해보면 제대로 출력되는걸 볼 수 있을겁니다.&lt;br /&gt;
[[파일:Qt_1_pro_7.png]]&lt;br /&gt;
[[파일:Qt_1_pro_8.png]]&lt;br /&gt;
* const라는 게 있습니다.&lt;br /&gt;
* 상수를 변수처럼 사용할 수 있게 만들어 주는거죠.&lt;br /&gt;
* 예를 들어, 파이값같은걸 쓴다치면, 계속 3.1415926이라는 값을 입력하면 귀찮으니, pi라는 변수처럼 생긴 놈 안에다가 그 값을 넣어두는 겁니다.&lt;br /&gt;
* const 선언을 하게 되면, 그 값을 바꿀 수 없습니다. Ansi-C에서는 #define이라는 전처리기(Preprocessor)를 사용했었는데, C++ 계열에서는 거의 대부분 const로 해결합니다. 이해도 쉽고, const를 쓰는게 좋습니다.&lt;br /&gt;
[[파일:Qt_1_pro_9_.png]]&lt;br /&gt;
[[파일:Qt_1_pro_10_.png]]&lt;br /&gt;
&lt;br /&gt;
=== 연산자 ===&lt;br /&gt;
* 다음과 같이 연산자를 사용할 수 있다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int data1;&lt;br /&gt;
int data2;&lt;br /&gt;
&lt;br /&gt;
data1 = 10;&lt;br /&gt;
data2 = 3;&lt;br /&gt;
&lt;br /&gt;
// 산술 연산&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 + data2 = &amp;quot; &amp;lt;&amp;lt; data1 + data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 - data2 = &amp;quot; &amp;lt;&amp;lt; data1 - data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 * data2 = &amp;quot; &amp;lt;&amp;lt; data1 * data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 / data2 = &amp;quot; &amp;lt;&amp;lt; data1 / data2;&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;data1 % data2 = &amp;quot; &amp;lt;&amp;lt; data1 % data2;&lt;br /&gt;
&lt;br /&gt;
// 논리 연산&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; QString(&amp;quot;(data1 &amp;lt; 11) &amp;amp;&amp;amp; (data2 &amp;gt; 2) = %1&amp;quot;).arg((data1 &amp;lt; 11) &amp;amp;&amp;amp; (data2 &amp;gt; 2));&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; QString(&amp;quot;(data1 &amp;lt; 11) || (data2 &amp;lt; 2) = %1&amp;quot;).arg((data1 &amp;lt; 11) || (data2 &amp;lt; 2));&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; QString(&amp;quot;!(data1 &amp;lt; 11) = %1&amp;quot;).arg(!(data1 &amp;lt; 11));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 조건문 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=b-mylI0gTY8&lt;br /&gt;
* if는 다음과 같이 사용할 수 있습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
if(조건식) { 명령문; }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 1개의 조건문 예시&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int jumsu;&lt;br /&gt;
&lt;br /&gt;
jumsu = 50;&lt;br /&gt;
&lt;br /&gt;
if(jumsu &amp;lt; 60)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;낙제입니다&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;재수강 신청하세요&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;마감일은 12월 20일입니다&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;낙제가 아닙니다&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;재수강 신청하지 마세요&amp;quot;;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;마감일 신경쓰지 마세요&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
qDebug() &amp;lt;&amp;lt; &amp;quot;점수는 &amp;quot; &amp;lt;&amp;lt; jumsu &amp;lt;&amp;lt; &amp;quot;점 입니다.&amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* elseif 예시&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int jumsu;&lt;br /&gt;
&lt;br /&gt;
jumsu = 50;&lt;br /&gt;
&lt;br /&gt;
if(jumsu &amp;gt;= 90)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;A 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if(jumsu &amp;gt;= 80)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;B 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if(jumsu &amp;gt;= 70)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;C 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else if(jumsu &amp;gt;= 60)&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;D 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else // elseif가 아님&lt;br /&gt;
{&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;F 학점입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* switch 문은 일반적으로 enum과 함께 쓰입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
enum weekday {&lt;br /&gt;
    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int today, yesterday;&lt;br /&gt;
&lt;br /&gt;
today = Saturday;&lt;br /&gt;
&lt;br /&gt;
yesterday = today -1;&lt;br /&gt;
&lt;br /&gt;
switch(yesterday) {&lt;br /&gt;
    case Friday:&lt;br /&gt;
    case Saturday: qDebug() &amp;lt;&amp;lt; &amp;quot;Burning&amp;quot;; break;&lt;br /&gt;
    case Monday: qDebug() &amp;lt;&amp;lt; &amp;quot;What the Hell&amp;quot;; break;&lt;br /&gt;
    default:&lt;br /&gt;
        qDebug(&amp;quot;Groomy Working Day&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* enum은 위와 같이 사용합니다. 자세한 사용법은 구글님께.&lt;br /&gt;
&lt;br /&gt;
=== 반복문 ===&lt;br /&gt;
* for는 다음과 같이 사용합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
for(변수 = 초기값; 최종값에 대한 식; 변수를 어떻게 증감할건지)&lt;br /&gt;
{&lt;br /&gt;
  명령문들;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 예제를 하나 보도록 하죠.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
for(int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
{&lt;br /&gt;
  res += i;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;까지의 합은 &amp;quot; &amp;lt;&amp;lt; res &amp;lt;&amp;lt; &amp;quot;입니다.&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* do~while문은 다음과 같이 사용합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  명령문들;&lt;br /&gt;
} while (최종값에 대한 식);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이것도 역시 예제를 위의 for와 같은걸 해보도록 하죠.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int i = 0; // 이처럼 변수 선언을 하면서 초기값을 설정할 수 있습니다.&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
  i++;&lt;br /&gt;
  res += i;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;까지의 합은 &amp;quot; &amp;lt;&amp;lt; res &amp;lt;&amp;lt; &amp;quot;입니다.&amp;quot;;&lt;br /&gt;
} while (i &amp;lt; 3);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 자, for문과 do~while문의 차이점은 뭘까요?&lt;br /&gt;
# for는 괄호 안에 모든 내용을 다 집어넣었지요? 사람들은 반복문을 사용할 때 for를 더 많이 사용하는 이유가 있지요.&lt;br /&gt;
# for는 루프 내에서만 사용되는 변수를 지정할 수 있습니다. while은 미리 변수를 선언해야 하고요.&lt;br /&gt;
# while은 또 한가지 유의할 점이 있습니다. *무조건* 한번은 프로시져가 실행된다는 점이죠.&lt;br /&gt;
=== 배열 ===&lt;br /&gt;
* 프로그램에서 데이터를 임시로 저장하기 위해서 변수를 사용한다는건 아실겁니다.&lt;br /&gt;
* 그런데 변수중에 '배열'이라는걸 들어보셨을거에요.그걸 왜 쓰는지 궁금하실겁니다.&lt;br /&gt;
* 일단 '배열'이라는건 같은 데이터 타입을 가지는 변수의 '집단'이라고 할 수 있습니다.&lt;br /&gt;
* 예를 들어 10개의 과목에 대한 점수를 기억하려면 다음과 같이 10개의 정수형 변수가 필요할 것입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int score1;&lt;br /&gt;
int score2;&lt;br /&gt;
int score3;&lt;br /&gt;
int score4;&lt;br /&gt;
int score5;&lt;br /&gt;
int score6;&lt;br /&gt;
int score7;&lt;br /&gt;
int score8;&lt;br /&gt;
int score9;&lt;br /&gt;
int score10;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 보세요. 보기만 해도 선언도 &amp;lt;s&amp;gt;존나&amp;lt;/s&amp;gt; 귀찮고 기억하기도 힘들겠죠?&lt;br /&gt;
* 근데, 이걸 100명분을 작성한다고 칩시다 &amp;lt;s&amp;gt;씨발 장난하자는거야?&amp;lt;/s&amp;gt;&lt;br /&gt;
* 이럴땐 다음과 같이 배열로 하면 좀더 쉽게 작성할 수 있습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
타입 변수명[갯수];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 예제를 하나 보죠.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int score[100];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 이런식으로 사용합니다. 다음은 1부터 10까지 돌면서 해당 값에 2를 곱해서 저장하는 프로그램입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int score[10];&lt;br /&gt;
for(int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
{&lt;br /&gt;
  score[i] = i * 2;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;i = &amp;quot; &amp;lt;&amp;lt; score[i];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실행 결과는 다음과 같을 것입니다.&lt;br /&gt;
[[파일:Qt_2_script_0.png]]&lt;br /&gt;
* 이걸 보고 이상하다는 생각이 들지 않나요? &amp;lt;s&amp;gt;이상하다는 생각이 안든다면 공대생일거야 아마&amp;lt;/s&amp;gt;&lt;br /&gt;
* 컴퓨터한테는 첫번째 숫자가 1이 아니라 0입니다.&lt;br /&gt;
* 이걸 1부터 시작해서 10으로 끝나게 만들려면 어떻게 해야 할까요? 한번 고민해보고 만들어보시기 바랍니다. :)&lt;br /&gt;
&lt;br /&gt;
=== 동적 배열 ===&lt;br /&gt;
* 그런데 배열의ㅈㅈ습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int* 변수이름 = new 타입[갯수];&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 타입 뒤에 *가 들어갑니다. 중요합니다.&lt;br /&gt;
* 또한, 할당하고 나서 다음과 같이 꼭 해제를 해줘야 합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
delete[] 변수이름;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 요즘 인기있는 언어들이 Garbage Collector를 포함하며, 인터프리터를 지향하고 있는 이유는 해제할 타이밍이 애매한 경우가 많아서입니다.&lt;br /&gt;
* 하지만, 조금 크게 메모리를 할당하거나 하는 방법으로 메모리 해제 타이밍을 잡을 수 있습니다.&lt;br /&gt;
* 또한 QT에서는 QT 데이터타입을 사용하면 내부적으로 Garbage Collector를 적용한다고 합니다.&lt;br /&gt;
* 아무튼 예제를 하나 보도록 하겠습니다. 마찬가지로 위와 같은 프로그램입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int* score = new int[10];&lt;br /&gt;
for(int i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
{&lt;br /&gt;
  score[i] = i * 2;&lt;br /&gt;
  qDebug() &amp;lt;&amp;lt; &amp;quot;i = &amp;quot; &amp;lt;&amp;lt; score[i];&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 다차원배열 ===&lt;br /&gt;
* 지금까지 본건 1차원 배열입니다.&lt;br /&gt;
* QT를 컴파일하는 gcc의 경우 10차원이 넘는 배열을 선언할 수 있습니다. &amp;lt;s&amp;gt;근데 4차원만 넘어가도 일반적으로 미친놈이라고 하잖아?&amp;lt;/s&amp;gt;&lt;br /&gt;
* 간단한 프로그램을 작성해 봅시다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int data[3][5];&lt;br /&gt;
for(int i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
{&lt;br /&gt;
  for(int j = 0; j &amp;lt; 5; j++)&lt;br /&gt;
  {&lt;br /&gt;
    data[i][j] = i * j;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; i &amp;lt;&amp;lt; &amp;quot;*&amp;quot; &amp;lt;&amp;lt; &amp;quot;j&amp;quot; &amp;lt;&amp;lt; &amp;quot;=&amp;quot; &amp;lt;&amp;lt; data[i][j];&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 대충 무슨 프로그램인지 보이시지요?&lt;br /&gt;
* 자 이걸 구구단으로 바꿔보세요.&lt;br /&gt;
=== 구조체 ===&lt;br /&gt;
* 구조체는 다음과 같이 사용합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
struct {&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== 함수 ===&lt;br /&gt;
&lt;br /&gt;
== GUI 기초 및 응용 ==&lt;br /&gt;
=== 컨트롤 ===&lt;br /&gt;
[[파일:Layouts.png]][[파일:Spacers.png]][[파일:Buttons.png]][[파일:Item Views.png]][[파일:Item Widget.png]][[파일:Containers.png]][[파일:Input Widget.png]][[파일:Display Widget.png]]&lt;br /&gt;
=== 프로그램을 작성하는 순서 ===&lt;br /&gt;
* 일반적으로 프로그램은 다음과 같은 순서로 작성합니다.&lt;br /&gt;
# GUI 구상 - 어떤 GUI를 만들 것인지 구상합니다.&lt;br /&gt;
# 객체 배치 - 컨트롤을 사용하여 객체들을 폼 위에 배치합니다.&lt;br /&gt;
# 속성 조절 - 속성창에서 조절할 필요가 있는 속성들을 지정합니다.&lt;br /&gt;
# 슬롯 선택 - 객체별로 필요한 슬롯을 선택하고 코딩을 합니다. 이때 프로그램에서 제어할 필요가 있는 속성은 객체-&amp;gt;속성으로 지정하고, 객체-&amp;gt;메소드나 함수, 명령문을 사용하여 객체의 이벤트를 완성합니다.&lt;br /&gt;
# 디버깅 - 실행을 하고 에러가 있으면 수정을 해서 다시 실행합니다.&lt;br /&gt;
* 물론 이것이 정석적인 방법이라고 볼 수는 없겠습니다만, 일반적인 취향이라고 볼 수 있겠습니다.&lt;br /&gt;
=== 컨트롤을 쉽게 배치하는 방법 ===&lt;br /&gt;
* 폼 위에 객체를 그리다 보면 동일한 객체를 여러개 그려야 하는 경우가 많습니다. 이들의 크기나 위치등을 하나씩 &amp;lt;s&amp;gt;존나 신컨으로&amp;lt;/s&amp;gt; 배치할수도 있겠으나, 우리는 &amp;lt;s&amp;gt;짐승이 아니므로&amp;lt;/s&amp;gt; 도구를 쓰도록 합시다.&lt;br /&gt;
&lt;br /&gt;
[[파일:Qt 2 gui 0.png]]&lt;br /&gt;
[[파일:Qt 2 gui 1.png]]&lt;br /&gt;
[[파일:Qt 2 gui 2.png]]&lt;br /&gt;
p;;;;;&lt;br /&gt;
&lt;br /&gt;
=== QPushButton 컨트롤 사용하기 ===&lt;br /&gt;
* 버튼입니다. 프로그램 만들면 많이들 사용하는 컨트롤이죠.&lt;br /&gt;
* 이 버튼은 대개 누르면 작업이 실행되게 하는 용도로 사용되죠.&lt;br /&gt;
* Enabled라는 속성에 대해 좀 중점적으로 보시면 좋을듯 합니다.&lt;br /&gt;
* 다음과 같은 프로그램을 만들어봅시다.&lt;br /&gt;
[[file:First Qt App.png]]&lt;br /&gt;
* QPushButton 3개와 QLabel 1개를 배치해 봅시다.&lt;br /&gt;
* 그리고 QPushButton에 Clicked 슬롯을 만들고 다음과 같이 작성해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Dialog::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(&amp;quot;하드웨어 지원 최강&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;pushButton-&amp;gt;setEnabled(false);&lt;br /&gt;
    ui-&amp;gt;pushButton_2-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_3-&amp;gt;setEnabled(true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Dialog::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(&amp;quot;유저가 최강&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;pushButton-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_2-&amp;gt;setEnabled(false);&lt;br /&gt;
    ui-&amp;gt;pushButton_3-&amp;gt;setEnabled(true);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Dialog::on_pushButton_3_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(&amp;quot;스타벅스 가냐?&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;pushButton-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_2-&amp;gt;setEnabled(true);&lt;br /&gt;
    ui-&amp;gt;pushButton_3-&amp;gt;setEnabled(false);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 유의할 점은 void Dialog::on_pushButton_clicked() &amp;lt;- 이 부분은 직접 코딩하는게 &amp;lt;b&amp;gt;아닙니다!!&amp;lt;/b&amp;gt;&lt;br /&gt;
* 슬롯을 전부 만드시고 위와 같이 코드를 작성하셨다면 누른 버튼이 비활성화되는게 보이실겁니다.&lt;br /&gt;
&lt;br /&gt;
=== QLineEdit 컨트롤 사용하기 ===&lt;br /&gt;
* 주로 주관식 데이터를 입력하기 위해 많이 사용하는 LineEdit 컨트롤을 지정해 봅시다.&lt;br /&gt;
* 성적을 계산하는 프로그램인데, 텍스트상자를 이용해서 이름과 점수를 입력합니다.&lt;br /&gt;
* 다음과 같은 프로그램을 만들 것입니다.&lt;br /&gt;
[[파일:Qt_App_2.png]]&lt;br /&gt;
* Grid Layout을 이용하면 의외로 간단하게 화면 구성이 가능합니다.&lt;br /&gt;
* 다음과 같이 그리드 레이아웃을 만들고 왼쪽에는 Label을, 오른쪽에는 LineEdit를 드래그해서 집어넣습니다.&lt;br /&gt;
[[파일:Qt_2_drag_drop_0.png]]&lt;br /&gt;
[[파일:Qt_2_drag_drop_1.png]]&lt;br /&gt;
[[파일:Qt_2_drag_drop_2.png]]&lt;br /&gt;
* 그리고 버튼도 Horizontal Layout을 이용하면 쉽게 배열이 가능합니다.&lt;br /&gt;
* 레이블과 버튼, 라인에디트를 배열하고 각각 속성에서 제목을 적어줍니다.&lt;br /&gt;
* 헤더파일에 QDebug를 include하고, 다음과 같이 변수를 선언해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QString name;&lt;br /&gt;
int kor;&lt;br /&gt;
int eng;&lt;br /&gt;
int math;&lt;br /&gt;
&lt;br /&gt;
int total;&lt;br /&gt;
int avg;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 각 버튼의 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    name = ui-&amp;gt;lineEdit-&amp;gt;text();&lt;br /&gt;
    kor = ui-&amp;gt;lineEdit_2-&amp;gt;text().toInt();&lt;br /&gt;
    eng = ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt();&lt;br /&gt;
    math = ui-&amp;gt;lineEdit_4-&amp;gt;text().toInt();&lt;br /&gt;
    total = kor + eng + math;&lt;br /&gt;
    avg = total /3;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; &amp;quot;이름      국어 영어 수학 총점 평균&amp;quot;;&lt;br /&gt;
    qDebug() &amp;lt;&amp;lt; name &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; kor &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; eng &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; math &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; total &amp;lt;&amp;lt; &amp;quot; &amp;quot; &amp;lt;&amp;lt; avg;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 실제 입력에 따라 다음과 같이 결과가 출력되는걸 볼 수 있습니다.&lt;br /&gt;
결과 나오는 화면&lt;br /&gt;
[[파일:Qt_App_2_Result.png]]&lt;br /&gt;
&lt;br /&gt;
=== QCheckBox 컨트롤 사용하기 ===&lt;br /&gt;
* 체크박스는 체크 표시된 항목을 선택하는 기능을 제공합니다.&lt;br /&gt;
* 아마도 웹사이트에서 많이 보셨을겁니다.&lt;br /&gt;
* 이것의 특징은, 라디오버튼과 달리 여러개의 항목을 동시에 선택할 수 있다는 겁니다.&lt;br /&gt;
* 남자가 결혼하기 전에 사야 할 물품을 정리해 보았습니다.&lt;br /&gt;
* 폼에 판매 품목과 가격을 체크상자로 표시하고, 소비자가 상자를 선택하고 총액계산 버튼을 누르면 텍스트 상자에 총액이 표시되도록 하는것이 목표입니다.&lt;br /&gt;
실행 화면&lt;br /&gt;
&lt;br /&gt;
[[파일:checkbox_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 헤더에 변수를 하나 선언합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int sum;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 위 폼은 쉽게 만들 수 있을것이라 생각하고, 각 버튼의 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    sum = 0;&lt;br /&gt;
    if(ui-&amp;gt;checkBox-&amp;gt;isChecked())&lt;br /&gt;
        sum += 650000;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_2-&amp;gt;isChecked())&lt;br /&gt;
        sum += 550000;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_3-&amp;gt;isChecked())&lt;br /&gt;
        sum += 150000;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_4-&amp;gt;isChecked())&lt;br /&gt;
        sum += 250000;&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(QString::number(sum));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;checkBox-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_2-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_3-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_4-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 체크버튼을 누르면 바로 적용되도록 만들 수 있을 것입니다.&lt;br /&gt;
* 이건 직접 해보시는게 어떨까요?&lt;br /&gt;
&lt;br /&gt;
=== QRadioButton 컨트롤 사용하기 ===&lt;br /&gt;
* 라디오버튼은 옵션 버튼이라고도 합니다.&lt;br /&gt;
* 체크 상자와 비슷하게 항목을 선택할 때 사용되지만, 옵션 버튼은 여러개 중에서 한개만 선택할 수 있는데에 많이 사용됩니다.&lt;br /&gt;
* 체크버튼가지고도 코드 부분을 좀 수정하면 라디오버튼과 같은 동작을 하게 만들수 있습니다. &amp;lt;s&amp;gt;근데 개귀찮아&amp;lt;/s&amp;gt;&lt;br /&gt;
* 특정 버튼을 선택했다가 다른 버튼을 선택하면 이전에 선택했던 버튼의 체크표시는 지워집니다.&lt;br /&gt;
* 아래 프로그램을 한번 만들어 보도록 하겠습니다. 라디오버튼과 체크버튼을 같이 쓰니까 비교하기가 쉬울겁니다.&lt;br /&gt;
[[파일:Qt_3_result_0.png]]&lt;br /&gt;
* 자신의 연령대를 선택하고 연애인을 선택한 후 결과보기 버튼을 누르면 텍스트 상자에 결과가 표시됩니다.&lt;br /&gt;
* 다시보기 버튼을 누르면 내용이 싹 지워져서 새로 선택하기 편하도록 편의성을 높였습니다.&lt;br /&gt;
* 헤더에 추가할 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QString age;&lt;br /&gt;
QString singer;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드에 추가할 내용입니다. PushButton에 슬롯으로 작성하는건 이제 다들 익숙해지셨으리라 생각합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    singer = &amp;quot;&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;10대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_2-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;20대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_3-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;30대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_4-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;40대&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton_5-&amp;gt;isChecked())&lt;br /&gt;
        age = &amp;quot;외계인&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;소녀시대 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_2-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;2ne1 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_3-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;이선희 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_4-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;걸스데이 &amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;checkBox_5-&amp;gt;isChecked())&lt;br /&gt;
        singer += &amp;quot;EXO &amp;quot;;&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(age + &amp;quot;인 당신은 &amp;quot; + singer +&amp;quot;를 좋아하네요.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;radioButton-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_2-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_3-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_4-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;radioButton_5-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_2-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_3-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_4-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;checkBox_5-&amp;gt;setChecked(false);&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QGroupBox ===&lt;br /&gt;
* 그룹박스는 다른 객체들을 묶는 역할을 합니다.&lt;br /&gt;
* 다른 여러 프로그램상에서 많이들 보셨을겁니다.&lt;br /&gt;
* 이건 말보다 프로그램을 직접 보시는게 나을듯.&lt;br /&gt;
실행화면&lt;br /&gt;
&lt;br /&gt;
[[파일:QGroupBox_1.png]]&lt;br /&gt;
&lt;br /&gt;
[[파일:QGroupBox_2.png]]&lt;br /&gt;
&lt;br /&gt;
* 보시면 2개의 그룹박스를 사용하고 있습니다.&lt;br /&gt;
* PC 보유현황과 주변장치현황이 프레임입니다.&lt;br /&gt;
* 나머지 내용은 위의 QRadiobutton강좌와 같다고 보시면 됩니다.&lt;br /&gt;
* 헤더에는 변수를 선언해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QString com;&lt;br /&gt;
QString phr;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 다음은 버튼에 관한 코드입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    phr = &amp;quot;&amp;quot;;&lt;br /&gt;
    if(ui-&amp;gt;radioButton-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;radioButton_2-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton_2-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;radioButton_3-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton_3-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;radioButton_4-&amp;gt;isChecked())&lt;br /&gt;
        com = ui-&amp;gt;radioButton_4-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox_2-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox_2-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox_3-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox_3-&amp;gt;text();&lt;br /&gt;
    if(ui-&amp;gt;checkBox_4-&amp;gt;isChecked())&lt;br /&gt;
        phr += ui-&amp;gt;checkBox_4-&amp;gt;text();&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;당신은 &amp;quot; + com + &amp;quot;컴퓨터와 &amp;quot; + phr + &amp;quot;주변장치를 보유중입니다.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QListWidget ===&lt;br /&gt;
* ListWidget 컨트롤은 상자 안에 항목들을 나열하는 기능을 제공합니다.&lt;br /&gt;
* 이거랑 ComboBoxWidget이 목록을 제공하는 대표적인 컨트롤입니다.&lt;br /&gt;
* ListWidget은 여러개의 항목 선택을 할 수 있도록 되어 있으며, Shift나 Ctrl등을 이용해서 선택할 수 있도록 되어 있습니다.&lt;br /&gt;
[[파일:listwidget_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 코드는 매우 간단합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;listWidget-&amp;gt;addItem(ui-&amp;gt;lineEdit-&amp;gt;text());&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QComboBox ===&lt;br /&gt;
* 콤보박스 컨트롤은 펼침 목록 기능을 제공합니다.&lt;br /&gt;
* 웹사이트를 방문해보면 주소 입력하는데 대부분 이거 씁니다.&lt;br /&gt;
* 프로그래밍에서도 종종 씁니다.&lt;br /&gt;
* ListWidget과 사용법은 비슷합니다.&lt;br /&gt;
결과화면&lt;br /&gt;
&lt;br /&gt;
[[파일:combobox_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 이번에는 버튼을 만들지 않고, 콤보박스의 내용이 변경되는 즉시 반영되도록 해봅시다.&lt;br /&gt;
* 슬롯 선택시 다음과 같이 선택하세요.&lt;br /&gt;
[[파일:combobox_slot.png]]&lt;br /&gt;
* 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_comboBox_currentIndexChanged(int index)&lt;br /&gt;
{&lt;br /&gt;
    if(index == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;연남동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;서교동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;동교동&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if(index == 1)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;삼청동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;사직동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;계동&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if(index == 2)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;신사동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;논현동&amp;quot;);&lt;br /&gt;
        ui-&amp;gt;comboBox_2-&amp;gt;addItem(&amp;quot;도곡동&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_comboBox_2_currentIndexChanged(int index)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;선택된 주소는 &amp;quot; + ui-&amp;gt;comboBox-&amp;gt;currentText() + &amp;quot; &amp;quot; + ui-&amp;gt;comboBox_2-&amp;gt;currentText() + &amp;quot;입니다.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Slider &amp;amp; Dial ===&lt;br /&gt;
* 슬라이더를 봅시다.&amp;lt;s&amp;gt;오빠이 슬라이더라는 일본게임을 생각하면 이해가 쉬울것임&amp;lt;/s&amp;gt;&lt;br /&gt;
* 각각의 슬라이더의 값 변화에 따라 레이블도 변화하도록 해봅시다.&lt;br /&gt;
* Dial은 꼭 옛날 전축에 있던거랑 비슷하게 생겼지요?&lt;br /&gt;
결과화면&lt;br /&gt;
&lt;br /&gt;
[[파일:sliders_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 슬롯 하나하나마다 다음과 같이 슬롯을 작성하고&lt;br /&gt;
슬롯 선택&lt;br /&gt;
* 코드는 다음과 같이 작성하면 된다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_horizontalScrollBar_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
    ui-&amp;gt;dial-&amp;gt;setValue(value);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_horizontalSlider_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label_2-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_verticalScrollBar_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label_3-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_verticalSlider_valueChanged(int value)&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;label_4-&amp;gt;setText(QString(&amp;quot;%1&amp;quot;).arg(value));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QTimer ===&lt;br /&gt;
* 타이머는 시간과 관련된 컨트롤입니다.&lt;br /&gt;
* 다음과 같이 시계를 만들어 보도록 하겠습니다.&lt;br /&gt;
실행화면&lt;br /&gt;
&lt;br /&gt;
[[파일:clock_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 시계는 코드에 직접 작성해 주어야 합니다&amp;lt;s&amp;gt;짜증&amp;lt;/s&amp;gt;&lt;br /&gt;
* 헤더파일에 QTimer와 QDateTime을 include해줍니다.&lt;br /&gt;
* QTimer는 타이머고, QDateTime은 현재시각을 받아오기 위해 사용합니다.&lt;br /&gt;
* private:에 timer를 하나 선언하고, private slots:에 tupdate() 함수를 등록해 줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
    QTimer* timer;&lt;br /&gt;
&lt;br /&gt;
private slots:&lt;br /&gt;
    int tupdate();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 프로그램이 실행되면서 타이머가 동작하도록 아래의 코드를 메인 위젯 안에 넣어줍니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
timer = new QTimer(this); // 타이머 생성&lt;br /&gt;
connect(timer, SIGNAL(timeout()), this, SLOT(tupdate())); // 타이머가 타임아웃이 되면 tupdate()를 호출&lt;br /&gt;
timer-&amp;gt;start(1000); // 1000은 밀리세컨드 단위. 타임아웃을 몇 ms로 할것인지 정함. 여기서는 1초마다 한번씩.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 그리고, tupdate() 함수를 다음과 같이 작성합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int Widget::tupdate()&lt;br /&gt;
{&lt;br /&gt;
    QDateTime local(QDateTime::currentDateTime());&lt;br /&gt;
    ui-&amp;gt;label_3-&amp;gt;setText(local.toString());&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QFileDialog ===&lt;br /&gt;
* 파일 컨트롤은 파일을 선택하거나, 파일을 저장할 때에 많이 사용되는 컨트롤입니다.&lt;br /&gt;
* 이건 기본 컨트롤엔 없으나, 사용 빈도가 굉장히 높습니다.&lt;br /&gt;
실행화면&lt;br /&gt;
&lt;br /&gt;
[[파일:file_result.png]]&lt;br /&gt;
&lt;br /&gt;
* 파일 다이얼로그를 사용하기 위해서는 QFileDialog를 include해야 합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;QFileDialog&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 그리고 버튼에 대한 코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QString file = QFileDialog::getOpenFileName();&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(file);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 파일 컨트롤도 참 쉽죠?&lt;br /&gt;
* 속성도 지정할 수 있습니다. png 파일만 연다든지.. 이 부분은 직접 해보세요 :)&lt;br /&gt;
=== QGraphicsView ===&lt;br /&gt;
* GraphicsView는 각종 도형, 텍스트 등을 좀 더 유연하게 사용할 수 있도록 만들어진 Canvas같은 개념의 컨트롤입니다.&lt;br /&gt;
* 단독으로는 아무것도 할 수 없고, GraphicsScene과 함께 동작합니다.&lt;br /&gt;
* 그림파일을 하나 불러와 보여주는 프로그램을 작성해 보겠습니다.&lt;br /&gt;
[[파일:Qt graphic result.png]]&lt;br /&gt;
* 헤더파일의 수정은 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// 헤더를 include해줍니다.&lt;br /&gt;
#include &amp;lt;QGraphicsScene&amp;gt;&lt;br /&gt;
#include &amp;lt;QPixmap&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// private 선언부에 scene 변수를 선언해 둡니다.&lt;br /&gt;
QGraphicsScene scene;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드입니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Widget 안 setupUi 이후에 다음과 같은 코드를 삽입합니다.&lt;br /&gt;
    QPixmap pix(&amp;quot;hello.png&amp;quot;);&lt;br /&gt;
    scene.addPixmap(pix);&lt;br /&gt;
    ui-&amp;gt;graphicsView-&amp;gt;setScene(&amp;amp;scene);&lt;br /&gt;
    ui-&amp;gt;graphicsView-&amp;gt;show();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 실행파일과 같은 디렉토리에 hello.png (png 파일 아무거나 넣어보세요)가 있다면 그 그림파일이 출력될 것입니다.&lt;br /&gt;
* 과제 : 전에 배운 FileOpenDialog를 이용해서, 파일을 선택해 보여줄 수 있도록 만들어 봅시다.&lt;br /&gt;
=== QTabWidget ===&lt;br /&gt;
* 탭 컨트롤에 대해 알아보겠습니다.&lt;br /&gt;
* 보통, 설정같이 내용은 많고, 각각의 성격에 따라 분류하고 싶을 경우 많이들 사용합니다.&lt;br /&gt;
* 코드로 작성하기보다는 일반적으로 디자인에서 다 하는 경우가 많습니다.&lt;br /&gt;
[[파일:Settings-ss00.png]]&lt;br /&gt;
=== QProgressBar ===&lt;br /&gt;
* 프로그레스바에 대해 알아보도록 하겠습니다.&lt;br /&gt;
* 가짜로 만든 로딩바 입니다.&amp;lt;s&amp;gt;요샌 컴터들이 존내 빨라서 뭘 로딩해도 몇 밀리초면 끝나 ㅅㅂ&amp;lt;/s&amp;gt;&lt;br /&gt;
[[파일:Progressbar-ss00.png]]&lt;br /&gt;
* 헤더는 다음과 같습니다&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// QTimer를 include해줍니다&lt;br /&gt;
#include &amp;lt;QTimer&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// 함수 정의에 다음과 같이 해줍니다.&lt;br /&gt;
private:&lt;br /&gt;
    Ui::Widget *ui;&lt;br /&gt;
    QTimer* timer;&lt;br /&gt;
    int tick;&lt;br /&gt;
&lt;br /&gt;
private slots:&lt;br /&gt;
    int tupdate();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// setupUi 다음에 넣어줍니다.&lt;br /&gt;
    timer = new QTimer(this);&lt;br /&gt;
    connect(timer, SIGNAL(timeout()), this, SLOT(tupdate()));&lt;br /&gt;
    tick = 0;&lt;br /&gt;
    timer-&amp;gt;start(10);&lt;br /&gt;
&lt;br /&gt;
// tupdate 함수는 다음과 같습니다.&lt;br /&gt;
int Widget::tupdate()&lt;br /&gt;
{&lt;br /&gt;
    if(tick == 100) ui-&amp;gt;label-&amp;gt;setText(&amp;quot;Loading Complete&amp;quot;);&lt;br /&gt;
    if(tick &amp;lt; 100) tick++;&lt;br /&gt;
    ui-&amp;gt;progressBar-&amp;gt;setValue(tick);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 계산기 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=3FT3c7mFQFI&lt;br /&gt;
* 흔히 집에 하나씩 있는 천원짜리 계산기를 한번 만들어 보도록 하겠습니다.&lt;br /&gt;
[[파일:calculator_result.png]]&lt;br /&gt;
*새로운 개념이 추가된 것은 없습니다. 기존에 배운 개념을 활용하여 만들 수 있습니다.&lt;br /&gt;
*소스코드는 아래와 같습니다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_1_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;1&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;2&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;2&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_3_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;3&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;3&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_4_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;4&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;4&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_5_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;5&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;5&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_6_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;6&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;6&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_7_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;7&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;7&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_8_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;8&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;8&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_9_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;9&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;9&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_11_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (QString::compare (ui-&amp;gt;lineEdit_2-&amp;gt;text(), &amp;quot;&amp;quot;) == 0)&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit-&amp;gt;setText(ui-&amp;gt;lineEdit-&amp;gt;text() + &amp;quot;10&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        ui-&amp;gt;lineEdit_3-&amp;gt;setText(ui-&amp;gt;lineEdit_3-&amp;gt;text() + &amp;quot;10&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_10_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;lineEdit_3-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
    ui-&amp;gt;lineEdit_4-&amp;gt;setText(&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_13_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;+&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_14_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;-&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_15_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;*&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_16_clicked()&lt;br /&gt;
{&lt;br /&gt;
    ui-&amp;gt;lineEdit_2-&amp;gt;setText(&amp;quot;/&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_12_clicked()&lt;br /&gt;
{&lt;br /&gt;
    if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;+&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) + ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
    else if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;-&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) - ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
    else if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;*&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) * ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
    else if (ui-&amp;gt;lineEdit_2-&amp;gt;text() == &amp;quot;/&amp;quot;)&lt;br /&gt;
        ui-&amp;gt;lineEdit_4-&amp;gt;setText(QString::number(ui-&amp;gt;lineEdit-&amp;gt;text().toInt(NULL, 10) / ui-&amp;gt;lineEdit_3-&amp;gt;text().toInt(NULL, 10)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 파일 다루기 ==&lt;br /&gt;
=== 메모장 프로그램 ===&lt;br /&gt;
* Youtube : https://www.youtube.com/watch?v=5wbMaH50GdM&lt;br /&gt;
* 메모장 프로그램을 한번 만들어 봅시다.&lt;br /&gt;
[[파일:Editor_result.png]]&lt;br /&gt;
* 간단하게 만들어 본 프로그램입니다.&lt;br /&gt;
* TextEdit 컨트롤과 ListWidget 컨트롤, PushButton 컨트롤을 사용하였습니다.&lt;br /&gt;
* 헤더파일에 추가할 내용은 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// 헤더 include&lt;br /&gt;
#include &amp;lt;QFileDialog&amp;gt;&lt;br /&gt;
#include &amp;lt;QMessageBox&amp;gt;&lt;br /&gt;
// Private 변수&lt;br /&gt;
    QDir dir;&lt;br /&gt;
    QFileInfoList list;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_pushButton_4_clicked()&lt;br /&gt;
{&lt;br /&gt;
    dir = QFileDialog::getExistingDirectory();&lt;br /&gt;
    dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);&lt;br /&gt;
    ui-&amp;gt;listWidget-&amp;gt;clear();&lt;br /&gt;
    list = dir.entryInfoList();&lt;br /&gt;
    for (int i = 0; i &amp;lt; list.size(); ++i) {&lt;br /&gt;
        QFileInfo fileInfo = list.at(i);&lt;br /&gt;
        ui-&amp;gt;listWidget-&amp;gt;addItem(QString(&amp;quot;%1&amp;quot;).arg(fileInfo.fileName()));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QString path, filename;&lt;br /&gt;
    filename = QString(&amp;quot;%1&amp;quot;).arg(list.at(ui-&amp;gt;listWidget-&amp;gt;currentIndex().row()).absoluteFilePath());&lt;br /&gt;
    QFile file(filename);&lt;br /&gt;
    file.open(QIODevice::ReadOnly);&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;clear();&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;append(file.readAll());&lt;br /&gt;
    file.close();&lt;br /&gt;
    QMessageBox msgbox;&lt;br /&gt;
    msgbox.setText(&amp;quot;File Opened&amp;quot;);&lt;br /&gt;
    msgbox.exec();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_2_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QString path, filename;&lt;br /&gt;
    filename = QString(&amp;quot;%1&amp;quot;).arg(list.at(ui-&amp;gt;listWidget-&amp;gt;currentIndex().row()).absoluteFilePath());&lt;br /&gt;
    QFile file(filename + &amp;quot;.text&amp;quot;);&lt;br /&gt;
    QByteArray bytearray = ui-&amp;gt;textEdit-&amp;gt;toPlainText().toUtf8().left(ui-&amp;gt;textEdit-&amp;gt;toPlainText().length());&lt;br /&gt;
    file.open(QIODevice::WriteOnly);&lt;br /&gt;
    file.write(bytearray);&lt;br /&gt;
    file.close();&lt;br /&gt;
    QMessageBox msgbox;&lt;br /&gt;
    msgbox.setText(&amp;quot;File Saved&amp;quot;);&lt;br /&gt;
    msgbox.exec();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pushButton_3_clicked()&lt;br /&gt;
{&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_listWidget_doubleClicked(const QModelIndex &amp;amp;index)&lt;br /&gt;
{&lt;br /&gt;
    QString path, filename;&lt;br /&gt;
    filename = QString(&amp;quot;%1&amp;quot;).arg(list.at(index.row()).absoluteFilePath());&lt;br /&gt;
    QFile file(filename);&lt;br /&gt;
    file.open(QIODevice::ReadOnly);&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;clear();&lt;br /&gt;
    ui-&amp;gt;textEdit-&amp;gt;append(file.readAll());&lt;br /&gt;
    file.close();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 좀 길어보이긴 하지만 다 했던 내용입니다.&lt;br /&gt;
* 연습문제 : 상단 메뉴바가 있는 MainWindow 프로그램으로 변환해 보세요.&lt;br /&gt;
&lt;br /&gt;
== 데이터베이스 다루기 ==&lt;br /&gt;
* sqlite를 이용하여 간단한 일기장을 만들어 보도록 하겠습니다.&lt;br /&gt;
[[파일:simple_diary_result.png]]&lt;br /&gt;
* QT에서는 기본적으로 sqlite3를 지원해 줍니다.&lt;br /&gt;
* ubuntu에서는 기본으로 sqlite2지만, sqlite3를 설치하면 됩니다.&lt;br /&gt;
* SQL 관련 내용을 사용하기 위해서는 pro 파일도 수정해야 합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
QT       += core gui sql&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 위와 같이 sql을 추가해 줍니다.&lt;br /&gt;
* 추가하지 않으면 헤더를 추가해도 라이브러리가 참조되지 않아, 컴파일 에러가 납니다. 꼭 추가해 주어야 합니다.&lt;br /&gt;
* 이제, 헤더에 다음과 같은 내용을 추가합니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// 헤더 include&lt;br /&gt;
#include &amp;lt;QtSql/QtSql&amp;gt;&lt;br /&gt;
// private 변수&lt;br /&gt;
    QSqlDatabase db;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* sql 파일의 위치는 이따 소스코드에 직접 지정해 주세요.&lt;br /&gt;
* sql 파일은 sqlite3에서 다음과 같은 명령어로 생성하였습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sqlite&amp;gt; create table note ( id INTEGER PRIMARY KEY AUTOINCREMENT, date text, title text, content text);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 소스코드는 다음과 같습니다.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void Widget::on_calendarWidget_clicked(const QDate &amp;amp;date)&lt;br /&gt;
{&lt;br /&gt;
    qWarning() &amp;lt;&amp;lt; date.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pbOpen_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QSqlQuery query;&lt;br /&gt;
    QString exeq;&lt;br /&gt;
&lt;br /&gt;
    int exist = 0;&lt;br /&gt;
&lt;br /&gt;
    query.clear();&lt;br /&gt;
    exeq = &amp;quot;select * from note where date ='&amp;quot; + ui-&amp;gt;calendarWidget-&amp;gt;selectedDate().toString() + &amp;quot;';&amp;quot;;&lt;br /&gt;
    query.exec(exeq);&lt;br /&gt;
    while(query.next())&lt;br /&gt;
    {&lt;br /&gt;
        QString date = query.value(0).toString();&lt;br /&gt;
        ui-&amp;gt;leTitle-&amp;gt;setText(query.value(&amp;quot;title&amp;quot;).toString());&lt;br /&gt;
        ui-&amp;gt;teContent-&amp;gt;clear();&lt;br /&gt;
        ui-&amp;gt;teContent-&amp;gt;appendPlainText(query.value(&amp;quot;content&amp;quot;).toString());&lt;br /&gt;
        exist = 1;&lt;br /&gt;
    }&lt;br /&gt;
    if(!exist)&lt;br /&gt;
        qWarning() &amp;lt;&amp;lt; &amp;quot;None&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pbExit_clicked()&lt;br /&gt;
{&lt;br /&gt;
    db.close();&lt;br /&gt;
    this-&amp;gt;close();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Widget::on_pbSave_clicked()&lt;br /&gt;
{&lt;br /&gt;
    QSqlQuery query;&lt;br /&gt;
    QString exeq;&lt;br /&gt;
&lt;br /&gt;
    query.clear();&lt;br /&gt;
    exeq = &amp;quot;insert into note (date, title, content) values ('&amp;quot; + ui-&amp;gt;calendarWidget-&amp;gt;selectedDate().toString()+&amp;quot;', '&amp;quot;+ui-&amp;gt;leTitle-&amp;gt;text()+&amp;quot;', '&amp;quot;+ui-&amp;gt;teContent-&amp;gt;toPlainText()+&amp;quot;');&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* 연습문제 : 노트패드의 경우와 같이, 메뉴가 되어 있는 프로그램으로 변경해 봅시다. 데이터베이스 생성도 같이.&lt;br /&gt;
&lt;br /&gt;
== 네트워크 프로그래밍 ==&lt;br /&gt;
=== 채팅 ===&lt;br /&gt;
* 네트워크 어플리케이션의 시작은 채팅 프로그램입니다.&lt;br /&gt;
* 아래 파일은 서버 / 클라이언트가 함께 동작하는 예제 프로그램입니다.&lt;br /&gt;
[[File:qt-network-chat.zip]]&lt;/div&gt;</summary>
		<author><name>122.36.132.209</name></author>
	</entry>
</feed>