블로그 이미지
조이키트 블로그
아두이노, 라즈베리파이, 반도체 센서/모듈 활용

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Notice

250x250
728x90
반응형

TEA5767

 

TEA5767 라디오 모듈은 라디오 수신을 위한 인기 있는 모듈 중 하나이다.

이 모듈은 다양한 라디오 수신기에 사용되며, 아날로그 FM 라디오 수신을 가능하게 한다.

주로 아두이노와 같은 마이크로컨트롤러와 함께 사용되어 프로젝트에 라디오 수신 기능을 추가할 때 편리하게 활용된다.

TEA5767 모듈은 I2C 인터페이스를 통해 제어되며, 사용자는 주파수, 볼륨 및 기타 설정을 조정할 수 있다.

이 모듈은 낮은 전력 소비와 높은 성능을 제공하여 휴대용 라디오에 이상적이다.

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

https://link.coupang.com/a/b13Sh8

 

TEA5767 라디오 모듈 - 라디오 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

https://link.coupang.com/a/b2vSOT

 

ATmega328P 마이크로 컨트롤러가 있는 아두이노 우노 R3 개발 보드 - 액세서리 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

https://link.coupang.com/a/b2vTO0

 

아두이노 LCD1602 16x2 4핀 디스플레이 모듈/ Arduino LCD1602 Module - 액세서리 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

 

TEA5767 아두이노 우노 R3 LCD 1602

 

이예제는 TEA5767 라디오 모듈을 사용하여 시리얼 모니터의 주파수 값을 키보드 "+" 와 "-"으로 조정하는 예제이다.

주파수 현시는 LCD 1602 디스플레이 모듈을 사용하였다.

 

회로 연결:

TEA5767  VCC  아두이노 5V
TEA5767  GND
아두이노 GND
TEA5767  SDA 아두이노 SDA
TEA5767  SCL 아두이노 SCL
LCD1602 VCC 아두이노 5V
LCD1602 GND 아두이노 GND
LCD1602 SDA 아두이노 A4
LCD1602 SCL
아두이노 A5

 

아두이노 라디오 회로도

 

전체 코딩:

#include <Wire.h>
#include <TEA5767Radio.h>
#include <LiquidCrystal_I2C.h>  // LCE패널 함수 선언

unsigned char frequencyH = 0;
unsigned char frequencyL = 0;
unsigned int frequencyB;

double frequency = 0;
LiquidCrystal_I2C lcd (0x27,16,2);   

void setup()
{
  lcd.init();           // LCD 초기화
  lcd.backlight();      // LCD 뒷 전등 켬
  Wire.begin();
  frequency = 88.7; //starting frequency
  setFrequency();
  Serial.begin(9600);
  Serial.println(frequency);
}

void loop()
{
  if(Serial.available()) {
    int rc = Serial.read();
    if(rc == '+' && frequency <= 108.0) {
      frequency += 0.1;
      setFrequency();
      Serial.println(frequency);
    } else if(rc == '-' && frequency >= 88.0) {
      frequency -= 0.1;
      setFrequency();
      Serial.println(frequency);
    } 
  }

  // LCD의 커서를 첫번째 열에 첫번째행으로 설정     
  lcd.setCursor(0, 0);

  // 측정된 주파수 값을 LCD에현시
  lcd.print("RADIO FM:");
  lcd.print(frequency);     //주파수
  lcd.print("Hz");
}

void setFrequency()
{
  frequencyB = 4 * (frequency * 1000000 + 225000) / 32768;
  frequencyH = frequencyB >> 8;
  frequencyL = frequencyB & 0XFF;
  delay(100);
  Wire.beginTransmission(0x60);
  Wire.write(frequencyH);
  Wire.write(frequencyL);
  Wire.write(0xB0);
  Wire.write(0x10);
  Wire.write((byte)0x00);
  Wire.endTransmission();
  delay(100);  
}

 

위와 같이 회로 연결을 한다음 코딩을 하고 파일을 업로드 한다.

다음 아두이노 IDE의 Tools 메뉴에서 Serial Monitor를 선택한다.

그리고 키보드의 "+"를 누르면 주파수가 하나씩 증가하고, "-"를 누르면 주파수가 하나씩 감소하는 것을 볼 수 있다.

다음은 주파수가 증가하는 모습니다. 

시리얼 모니터 출력결과

 

시리얼 모니터 출력과 LCD1602  출력 결과

 

https://www.youtube.com/watch?v=O7S4utZjfj4

 

728x90
반응형
posted by 조이키트 블로그
728x90
반응형

유량센서 YF-S401은 액체 유량을 측정하는 데 사용되는 감지 장치이다.

 

 

YF-S401

 
이 센서의 기능은 주로 다음과 같다.

  1. 유량 측정: YF-S401은 액체가 흐르는 속도나 양을 측정한다. 이를 통해 액체가 특정 시간 동안 얼마나 많은 양으로 흐르는지 측정할 수 있다.
  2. 디지털 출력: 이 센서는 디지털 출력을 생성하여 다른 장치에 전송할 수 있다. 일반적으로 펄스 출력 또는 디지털 시그널을 사용하여 유량 정보를 전송한다.
  3. 내구성: YF-S401은 내구성이 뛰어나고 경제적인 장치이다. 플라스틱 또는 금속으로 만들어진 센서가 있으며, 액체가 흐르는 환경에 적합한 다양한 모델이 있다.
  4. 낮은 소비 전력: 일반적으로 YF-S401은 낮은 전력을 소비하므로 배터리 또는 기타 전원 공급 장치로 작동할 수 있다.
  5. 애플리케이션: 주로 급유 시스템, 농업 자동화, 산업 프로세스 모니터링 등 다양한 응용 분야에서 사용된다.

유량센서 YF-S401는 아두이노와 함께 사용하여 다양한 프로젝트에 활용할 수 있다. 아래는 YF-S401을 아두이노와 함께 사용하는 간단한 예제이다.
 

 

부품 : 아두이노 우노 R3, YF-S401 유량센서, 12V 소형양수기, 16X2 LCD 디스플레이

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

https://link.coupang.com/a/b13YHl

 

아두이노용 유량센서 YF-S401 | 물흐름 감지센서 - 양수기 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

https://link.coupang.com/a/b131DK

 

DC12V 초조용 브러시리스 버클형 소형양수기 - 양수기 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

https://link.coupang.com/a/b2vSOT

 

ATmega328P 마이크로 컨트롤러가 있는 아두이노 우노 R3 개발 보드 - 액세서리 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

https://link.coupang.com/a/b2vTO0

 

아두이노 LCD1602 16x2 4핀 디스플레이 모듈/ Arduino LCD1602 Module - 액세서리 | 쿠팡

쿠팡에서 0.0 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 0 제품도 바로 쿠팡에서 확인할 수 있습니다.

www.coupang.com

 

아두이노 우노 R3 YF-S401 유량센서 12V 소형 양수기 1602 LCD 디스플레이

 
결선 방법

YF-S401유량센서  RED 아두이노 5V
YF-S401유량센서 BLACK 아두이노 GND
YF-S401유량센서 YELLOW 아두이노 D2
12V 소형 양수기 RED / BLACK 전원12V / GND
LCD1602   VCC 아두이노 5V
LCD1602  GND 아두이노 GND
LCD1602  SDA 아두이노 A4
LCD1602  SCL  아두이노 A5


아래 코드는 YF-S401 센서로부터 펄스를 받아 유량을 계산하고 시리얼 모니터를 통해 표시한다. 펄스 수를 측정하여 시간당 유량을 계산하고 누적된 총 유량을 추적한다. 

#include <LiquidCrystal_I2C.h>  // LCE패널 함수 선언

const int sensorPin = 2;  // YF-S401 센서 신호 핀
volatile int pulseCount;  // 펄스 카운터
float flowRate;           // 유량
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;
unsigned long oldTime;

 LiquidCrystal_I2C lcd (0x27,16,2);   

void setup() {
  lcd.init();           // LCD 초기화
  lcd.backlight();      // LCD 뒷 전등 켬
  Serial.begin(9600);
  pinMode(sensorPin, INPUT);
  pulseCount = 0;
  flowRate = 0.0;
  flowMilliLitres = 0;
  totalMilliLitres = 0;
  oldTime = 0;
  attachInterrupt(0, pulseCounter, FALLING);
}

void loop() {
  if ((millis() - oldTime) > 1000) {
    detachInterrupt(0);
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / 7.5;  // 7.5는 센서의 각 유량당 펄스 수
    oldTime = millis();
    flowMilliLitres = (flowRate / 60) * 1000;
    totalMilliLitres += flowMilliLitres;
    pulseCount = 0;
    attachInterrupt(0, pulseCounter, FALLING);
  }
  Serial.print("유량: ");
  Serial.print(flowRate);
  Serial.print(" L/min\t");
  Serial.print("총 양: ");
  Serial.print(totalMilliLitres);
  Serial.println(" mL");

  // LCD에서 한번 현시되고 측정된 값이 바뀌면 지우고 다시 현시 
  lcd.clear();
  // LCD의 커서를 첫번째 열에 첫번째행으로 설정     
  lcd.setCursor(0, 0);

  // 측정된 거리값을 LCD에현시
  lcd.print("flowRate:");
  lcd.print(flowRate);     // 유량
  lcd.print("L/min\t");

  // LCD의 커서를 첫번째 열에 두번째행으로 설정     
  lcd.setCursor(0, 1);
  lcd.print("total:");
  lcd.print(totalMilliLitres);  //총양
  lcd.print("mL");
  delay(200);     // 0.2초간 지연
}

void pulseCounter() {
  pulseCount++;
}

 
아래 영상은 유량 측정기의 유량 및 총양을 시리얼 모니터와 LCD 디스플레이로 출력하는 모습이다.
https://www.youtube.com/watch?v=g6Wszr02FHU&t=2s

 
이 코드를 사용하여 유압 시스템, 농업 자동화, 물 관리 시스템 등 다양한 프로젝트에 적용할 수 있다.
 
 
 
 

728x90
반응형
posted by 조이키트 블로그
2024. 4. 20. 14:59 쇼핑몰 홈페이지
728x90
반응형

먼저 구글에서 카페24 홈페이지를 검색한다.

https://www.cafe24.com/

 

카페24 - No.1 글로벌 전자상거래 플랫폼

회원가입만 하면 글로벌 쇼핑몰부터 제작, 배송, 마케팅까지 이커머스에 필요한 솔루션과 인프라를 원스톱으로 제공

www.cafe24.com

 

여기서 먼저 회원가입을 해야 하므로 우측 상단에 쇼핑몰 만들기를 클릭한다.

그러면 다음과 같이 회원가입 창이 나온다

 

여기서 사업자이신 분들은 개인사업자나 법인/기관을 선택하면 되고 아직 사업자 등록을 하지 않으신 분들은 일반회원으로 가입하여도 상관이 없다.  저는 사업자로 이미 가입이 되어 있으므로 일반회원으로 가입해보겠다.

 

이름, 생년월일, 휴대폰번호 인증을 마치면 아이디와 비밀번호 입력창이 나온다.

 

 

여기서 아이디와 비밀번호를 입력하고 약관동의하고 다음으로 넘어간다.

 

여기서 어떤 상품을 팔것인지 선택하고 다음으로 넘어간다.

위와 같이 쇼핑몰 디자인이 나오는데 자기가 마음에 드는 디지인을 선택하고 다음으로 넘어간다.

참고로 디자인은 나중에 변경할 수 있으니 일단 고민하지 말고 적당한거 하나 선택한다.

 

 

쇼핑몰 정보 입력창이 나오는데 여기에 자신의 쇼핑몰 이름과 이메일 주소를 입력하고 다음으로 넘어가면 드디어 쇼핑몰이 완성된다.

 

 

위와 같이 카테고리란에 주문, 상품, 고객 등 목록이 나오는데 여기서 디자인(PC/모바일)을 선택하고 디자인 미리보기를 클릭하면 자신의 쇼핑몰을 볼 수 있다.

 

 

 

 

오늘은 카페24로 쇼핑몰 홈페이지를 생성하는데까지 해보았다.

다음에는 쇼핑몰디자인을 자신의 취향에 맞게 변경하는 법을 해보려고 한다.

728x90
반응형
posted by 조이키트 블로그
2024. 1. 15. 18:40 파이썬 GUI
728x90
반응형

여기서는 tkinter 캔버스 위젯을 사용해 GUI에 극적인 색상 효과를 추가하는 방법을 보여준다.

 

먼저 GUI에 새로운 탭 tab3을 만든다.

tab3 = ttk.Frame(tabControl)
tabControl.add(tab3, text='Tab 3') # 세번째 탭 추가하기
tabControl.pack(expand=1, fill="both")  # 탭을 나타내기 위 패킹하기

 

다음으로 tkinter의 또 다른 내장 위젯 Canvas를 호출한다.

# Tab Control 3
tab3_frame = tk.Frame(tab3, bg='blue')
tab3_frame.pack()
for orange_color in range(2):
    canvas = tk.Canvas(tab3_frame, width=150, height=80, highlightthickness=0, bg='orange')
    canvas.grid(row=orange_color, column=orange_color)

 

코드 설명

새탭을 만든 후에는 일반 tk.Frame을 배치하고 배경색을 파란색으로 지정한다. 

루프에서 두 개의 tk.Canvas 위젯을 만들어 그리드 좌표 0, 0과  1, 1에 오랜지색을 할당한다.  또한 두 개의 다른 격자 위치에서 tk.Frame의 파란색 배경색을 볼 수 있다. 

 

전체 코드

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import scrolledtext
from tkinter import Menu
from tkinter import messagebox as msg
from tkinter import Spinbox
from tkinter import SCROLL
from time import sleep


win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("파이썬 GUI")   # 제목을 설정하기 위한 인스턴스 변수 사용
win.iconbitmap('pyc.ico')
tabControl = ttk.Notebook(win) # 탭 컨트롤 생성하기
tab1 = ttk.Frame(tabControl)   # 탭 생성하기
tabControl.add(tab1, text='Tab 1') # 탭 추가하기

tab2 = ttk.Frame(tabControl)
tabControl.add(tab2, text='Tab 2')  # 두번째 탭 추가하기
tabControl.pack(expand=1, fill="both")

tab3 = ttk.Frame(tabControl)
tabControl.add(tab3, text='Tab 3') # 세번째 탭 추가하기
tabControl.pack(expand=1, fill="both")  # 탭을 나타내기 위 패킹하기

# tab1을 부모로 사용한 라벨프레임
mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
mighty.grid(column=0, row=0, padx=8, pady=4)

# mighty를 부모로 사용한 라벨
a_label = ttk.Label(mighty, text="Enter a name:")
a_label.grid(column=0, row=0, sticky='W')

name = tk.StringVar()  # StringVar 변수를 생성하고 tkinter의 별칭으로 tk를 사용
name_entered = ttk.Entry(mighty, width=12, textvariable=name) # ttk.Entry 위젯을 생성하고 다른 변수에 할당
name_entered.grid(column=0, row=1) # 위젯의 위치 지정
name_entered.focus()

# 다른 라벨 추가하기
ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)

number = tk.StringVar()
number_chosen = ttk.Combobox(mighty, width=12, textvariable=number)  # ttk.Combobox 위젯 생성
number_chosen['values'] = (1, 2, 4, 10, 100) # 콤보박스 위젯 값 할당
number_chosen.grid(column=1, row=1) # 콤보박스 위젯 위치 지정
number_chosen.current(0)

def click_me():  # click_me() 함수 정의 
    action.configure(text='Hello ' + name.get())
    a_label.configure(foreground='red')
    

action = ttk.Button(mighty, text="Click Me!", command=click_me) # ttkfmf 사용해 버튼을 생성하고 text 속성을 전잘 
action.grid(column=2, row=1)
action.configure(state='enable')

# Spinbox 콜백
def _spin():
    value = spin.get()
    print(value)
#    scrol.insert(tk.INSERT, value + 'n')

# Spinbox2 콜백
def _spin2():
    value = spin2.get()
    print(value)
 #   scrol.insert(tk.INSERT, value + '\n')

# Spinbox 위젯 추가하기
spin = Spinbox(mighty, from_=0, to=10, width=10, bd=8, command=_spin)
spin.grid(column=0, row=2)
spin2 = Spinbox(mighty, values=('0 50 100'), width=10, bd=8, command=_spin2, relief=tk.RIDGE)
spin2.grid(column=1, row=2)
spin3 = Spinbox(mighty, values=('0 50 100'), width=10, bd=8, command=_spin2, relief=tk.FLAT)
spin3.grid(column=2, row=2)


# 스크롤되는 텍스트 위젯
scrol_w = 50  # 높이와 넓이를 위한 변수 정의 
scrol_h = 5

# ScrolledText 위젯 생성
scr = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scr.grid(column=0, row=5, sticky='WE', columnspan=3) # 스크롤 위젯의 위치 지정

mighty2 = ttk.LabelFrame(tab2, text= 'The Snake ')
mighty2.grid(column=0, row=0, padx=8, pady=4)

chVarDis = tk.IntVar()
check1 = tk.Checkbutton(mighty2, text="Disabled", variable=chVarDis, state='disabled')
check1.select()  # 상태를 select로 설정
check1.grid(column=0, row=4, sticky=tk.W, padx= 20, pady=10)  # 체크박스 위치 지정

chVarUn = tk.IntVar()  
check2 = tk.Checkbutton(mighty2, text="UnChecked", variable=chVarUn)
check2.deselect()  # 상태를 deselect로 설정
check2.grid(column=1, row=4, sticky=tk.W, padx= 20, pady=10)

chVarEn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check3 = tk.Checkbutton(mighty2, text="Enabled", variable=chVarEn)
check3.select()  # 상태를 select로 설정
check3.grid(column=2, row=4, sticky=tk.W, padx= 20, pady=10)

# 생상 이름을 저장하는 모듈 레벨의 전역변수 생성
COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

# 라디오 버튼을 위한 콜백함수 생성
def radCall():
    radSel=radVar.get()
    if   radSel == 1: mighty2.configure(tex=COLOR1)
    elif radSel == 2: mighty2.configure(text=COLOR2)
    elif radSel == 3: mighty2.configure(text=COLOR3)

# 1개의 변수를 사용하여 3개의 라디오버튼 생성
radVar = tk.IntVar()
 
# 3개의 tk 라디오 버튼 생성
for col in range(3):
    curRad = tk.Radiobutton(mighty2, variable=radVar, value=col, command=radCall)
    curRad.grid(column=col, row=6, sticky=tk.W)

# Tab2에 프로그레스바 추가
    progress_bar = ttk.Progressbar(tab2, orient='horizontal', length=286, mode='determinate')
    progress_bar.grid(column=0, row=3, pady=2)

# 콜백 함수에서 상태바 업데이트 하기
def run_progressbar():
    progress_bar["maximum"] = 100
    for i in range(101):
        sleep(0.05)
        progress_bar["value"] = i # 프로그레스바 증가시키기
        progress_bar.update()     # 순환문에서 update() 호출
        progress_bar["value"] = 0 # 프로그레스바 리셋 및 정리

# start 프로그레스바
def start_progressbar():
    progress_bar.start()

# stop 프로그레스바
def stop_progressbar():
    progress_bar.stop()

# 0.1초 후 프로그레스바 stop 
def progressbar_stop_after(wait_ms=1000):
    win.after(wait_ms, progress_bar.stop)

# 프로그레스바를 담기 위한 컨테이너 생성
buttons_frame = ttk.LabelFrame(mighty2, text=' ProgressBar ')
buttons_frame.grid(column=0, row=7, sticky='W', columnspan=2, padx=20, pady=40)

# Progressbar 명령 버튼을 추가
ttk.Button(buttons_frame, text=" Run Progressbar ", command=run_progressbar).grid(column=0, row=0, sticky='W')
ttk.Button(buttons_frame, text=" Start Progressbar ", command=start_progressbar).grid(column=0, row=1, sticky='W')
ttk.Button(buttons_frame, text=" Stop immediately ", command=stop_progressbar).grid(column=0, row=2, sticky='W')
ttk.Button(buttons_frame, text=" Stop after second ", command=progressbar_stop_after).grid(column=0, row=3, sticky='W')

# 순환문에 buttons_frame의 자식인 추가적인 패딩 추가
for child in buttons_frame.winfo_children():
    child.grid_configure(padx=2, pady=2)

# Tab2의 자식으로 추가적인 패딩 추가
for child in mighty2.winfo_children():
    child.grid_configure(padx=8, pady=2)


# 각 라벨 주변에 공간 추가하기
for child in mighty.winfo_children():
    child.grid_configure(padx=8)

for child in mighty2.winfo_children():
    child.grid_configure(padx=8)

# Tab Control 3
tab3_frame = tk.Frame(tab3, bg='blue')
tab3_frame.pack()
for orange_color in range(2):
    canvas = tk.Canvas(tab3_frame, width=150, height=80, highlightthickness=0, bg='orange')
    canvas.grid(row=orange_color, column=orange_color)

# 메뉴바 생성하기
menu_bar = Menu(win)
win.config(menu=menu_bar)

def _quit():
    win.quit()
    win.destroy()
    exit()

# 메뉴를 생성하고 메뉴 아이템 추가하기
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

def _msgBox():
    msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter' 'This year is 2024.')
    msg.showwarning('Python Message Warning Box', 'A Python GUI created using tkinter' '\nWarning: There might be a bug in this code.')
    msg.showerror('Python Message Error Box', 'A Python GUI created using tkinter:' '\nError : Houston ~ we Do have a serious PROBLEM!')
    answer = msg.askyesnocancel("Python Message Multi Choice Box", "Are you sure you really wish to do this?")


help_menu = Menu(menu_bar, tearoff=0)
help_menu.add_command(label="About", command=_msgBox)
menu_bar.add_cascade(label="Help", menu=help_menu)


win.mainloop()

 

 

 

728x90
반응형
posted by 조이키트 블로그
2024. 1. 8. 20:21 파이썬 GUI
728x90
반응형

프로그레스바는 일반적으로 긴 실행 프로그레스에서 현재 상태를 표시하는데 사용된다.

 

 

전체 코드

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import scrolledtext
from tkinter import Menu
from tkinter import messagebox as msg
from tkinter import Spinbox
from tkinter import SCROLL
from time import sleep


win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("파이썬 GUI")   # 제목을 설정하기 위한 인스턴스 변수 사용
win.iconbitmap('pyc.ico')
tabControl = ttk.Notebook(win)
tab1 = ttk.Frame(tabControl)
tabControl.add(tab1, text='Tab 1')
tab2 = ttk.Frame(tabControl)
tabControl.add(tab2, text='Tab 2')
tabControl.pack(expand=1, fill="both")

# tab1을 부모로 사용한 라벨프레임
mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
mighty.grid(column=0, row=0, padx=8, pady=4)

# mighty를 부모로 사용한 라벨
a_label = ttk.Label(mighty, text="Enter a name:")
a_label.grid(column=0, row=0, sticky='W')

name = tk.StringVar()  # StringVar 변수를 생성하고 tkinter의 별칭으로 tk를 사용
name_entered = ttk.Entry(mighty, width=12, textvariable=name) # ttk.Entry 위젯을 생성하고 다른 변수에 할당
name_entered.grid(column=0, row=1) # 위젯의 위치 지정
name_entered.focus()

# 다른 라벨 추가하기
ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)

number = tk.StringVar()
number_chosen = ttk.Combobox(mighty, width=12, textvariable=number)  # ttk.Combobox 위젯 생성
number_chosen['values'] = (1, 2, 4, 10, 100) # 콤보박스 위젯 값 할당
number_chosen.grid(column=1, row=1) # 콤보박스 위젯 위치 지정
number_chosen.current(0)

def click_me():  # click_me() 함수 정의 
    action.configure(text='Hello ' + name.get())
    a_label.configure(foreground='red')
    

action = ttk.Button(mighty, text="Click Me!", command=click_me) # ttkfmf 사용해 버튼을 생성하고 text 속성을 전잘 
action.grid(column=2, row=1)
action.configure(state='enable')

# Spinbox 콜백
def _spin():
    value = spin.get()
    print(value)
#    scrol.insert(tk.INSERT, value + 'n')

# Spinbox2 콜백
def _spin2():
    value = spin2.get()
    print(value)
 #   scrol.insert(tk.INSERT, value + '\n')

# Spinbox 위젯 추가하기
spin = Spinbox(mighty, from_=0, to=10, width=10, bd=8, command=_spin)
spin.grid(column=0, row=2)
spin2 = Spinbox(mighty, values=('0 50 100'), width=10, bd=8, command=_spin2, relief=tk.RIDGE)
spin2.grid(column=1, row=2)
spin3 = Spinbox(mighty, values=('0 50 100'), width=10, bd=8, command=_spin2, relief=tk.FLAT)
spin3.grid(column=2, row=2)


# 스크롤되는 텍스트 위젯
scrol_w = 50  # 높이와 넓이를 위한 변수 정의 
scrol_h = 5

# ScrolledText 위젯 생성
scr = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scr.grid(column=0, row=5, sticky='WE', columnspan=3) # 스크롤 위젯의 위치 지정

mighty2 = ttk.LabelFrame(tab2, text= 'The Snake ')
mighty2.grid(column=0, row=0, padx=8, pady=4)

chVarDis = tk.IntVar()
check1 = tk.Checkbutton(mighty2, text="Disabled", variable=chVarDis, state='disabled')
check1.select()  # 상태를 select로 설정
check1.grid(column=0, row=4, sticky=tk.W, padx= 20, pady=10)  # 체크박스 위치 지정

chVarUn = tk.IntVar()  
check2 = tk.Checkbutton(mighty2, text="UnChecked", variable=chVarUn)
check2.deselect()  # 상태를 deselect로 설정
check2.grid(column=1, row=4, sticky=tk.W, padx= 20, pady=10)

chVarEn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check3 = tk.Checkbutton(mighty2, text="Enabled", variable=chVarEn)
check3.select()  # 상태를 select로 설정
check3.grid(column=2, row=4, sticky=tk.W, padx= 20, pady=10)

# 생상 이름을 저장하는 모듈 레벨의 전역변수 생성
COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

# 라디오 버튼을 위한 콜백함수 생성
def radCall():
    radSel=radVar.get()
    if   radSel == 1: mighty2.configure(tex=COLOR1)
    elif radSel == 2: mighty2.configure(text=COLOR2)
    elif radSel == 3: mighty2.configure(text=COLOR3)

# 1개의 변수를 사용하여 3개의 라디오버튼 생성
radVar = tk.IntVar()
 
# 3개의 tk 라디오 버튼 생성
for col in range(3):
    curRad = tk.Radiobutton(mighty2, variable=radVar, value=col, command=radCall)
    curRad.grid(column=col, row=6, sticky=tk.W)

# Tab2에 프로그레스바 추가
    progress_bar = ttk.Progressbar(tab2, orient='horizontal', length=286, mode='determinate')
    progress_bar.grid(column=0, row=3, pady=2)

# 콜백 함수에서 상태바 업데이트 하기
def run_progressbar():
    progress_bar["maximum"] = 100
    for i in range(101):
        sleep(0.05)
        progress_bar["value"] = i # 프로그레스바 증가시키기
        progress_bar.update()     # 순환문에서 update() 호출
        progress_bar["value"] = 0 # 프로그레스바 리셋 및 정리

# start 프로그레스바
def start_progressbar():
    progress_bar.start()

# stop 프로그레스바
def stop_progressbar():
    progress_bar.stop()

# 0.1초 후 프로그레스바 stop 
def progressbar_stop_after(wait_ms=1000):
    win.after(wait_ms, progress_bar.stop)

#라벨 프레임
buttons_frame = ttk.LabelFrame(mighty2, text=' ProgressBar ')
buttons_frame.grid(column=0, row=7, sticky='W', columnspan=2, padx=20, pady=40)

# Progressbar 명령 버튼을 추가
ttk.Button(buttons_frame, text=" Run Progressbar ", command=run_progressbar).grid(column=0, row=0, sticky='W')
ttk.Button(buttons_frame, text=" Start Progressbar ", command=start_progressbar).grid(column=0, row=1, sticky='W')
ttk.Button(buttons_frame, text=" Stop immediately ", command=stop_progressbar).grid(column=0, row=2, sticky='W')
ttk.Button(buttons_frame, text=" Stop after second ", command=progressbar_stop_after).grid(column=0, row=3, sticky='W')

# 순환문에 buttons_frame의 자식인 추가적인 패딩 추가
for child in buttons_frame.winfo_children():
    child.grid_configure(padx=2, pady=2)

# Tab2의 자식으로 추가적인 패딩 추가
for child in mighty2.winfo_children():
    child.grid_configure(padx=8, pady=2)


# 각 라벨 주변에 공간 추가하기
for child in mighty.winfo_children():
    child.grid_configure(padx=8)

for child in mighty2.winfo_children():
    child.grid_configure(padx=8)

# 메뉴바 생성하기
menu_bar = Menu(win)
win.config(menu=menu_bar)

def _quit():
    win.quit()
    win.destroy()
    exit()

# 메뉴를 생성하고 메뉴 아이템 추가하기
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

def _msgBox():
    msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter' 'This year is 2024.')
    msg.showwarning('Python Message Warning Box', 'A Python GUI created using tkinter' '\nWarning: There might be a bug in this code.')
    msg.showerror('Python Message Error Box', 'A Python GUI created using tkinter:' '\nError : Houston ~ we Do have a serious PROBLEM!')
    answer = msg.askyesnocancel("Python Message Multi Choice Box", "Are you sure you really wish to do this?")


help_menu = Menu(menu_bar, tearoff=0)
help_menu.add_command(label="About", command=_msgBox)
menu_bar.add_cascade(label="Help", menu=help_menu)


win.mainloop()

 

프로그레스바를 생성하고 시작 및 중지하는 새 버튼을 만드는 단계는 다음과 같다.

모듈의 상단에 sleep을 임포트해 추가한다.

from time import sleep

 

3개의 라디오 버튼 위젯 생성한다.

# 3개의 tk 라디오 버튼 생성
for col in range(3):
    curRad = tk.Radiobutton(mighty2, variable=radVar, value=col, command=radCall)
    curRad.grid(column=col, row=6, sticky=tk.W)

 

다음 Tab2에 프로그레스바를 추가한다.

# Tab2에 프로그레스바 추가
    progress_bar = ttk.Progressbar(tab2, orient='horizontal', length=286, mode='determinate')
    progress_bar.grid(column=0, row=3, pady=2)

 

다음으로 프로그레스바를 업데이트하는 콜백함수를 작성한다.

# 콜백 함수에서 상태바 업데이트 하기
def run_progressbar():
    progress_bar["maximum"] = 100
    for i in range(101):
        sleep(0.05)
        progress_bar["value"] = i # 프로그레스바 증가시키기
        progress_bar.update()     # 순환문에서 update() 호출
        progress_bar["value"] = 0 # 프로그레스바 리셋 및 정리

# start 프로그레스바
def start_progressbar():
    progress_bar.start()

# stop 프로그레스바
def stop_progressbar():
    progress_bar.stop()

# 0.1초 후 프로그레스바 stop 
def progressbar_stop_after(wait_ms=1000):
    win.after(wait_ms, progress_bar.stop)

 

프로그레스바를 담기 위한 컨테이너를 생성한다.

# 프로그레스바를 담기 위한 컨테이너 생성
buttons_frame = ttk.LabelFrame(mighty2, text=' ProgressBar ')
buttons_frame.grid(column=0, row=7, sticky='W', columnspan=2, padx=20, pady=40)

 

다음 4개의 새로운 버튼을 생성한다.

# Progressbar 명령 버튼을 추가
ttk.Button(buttons_frame, text=" Run Progressbar ", command=run_progressbar).grid(column=0, row=0, sticky='W')
ttk.Button(buttons_frame, text=" Start Progressbar ", command=start_progressbar).grid(column=0, row=1, sticky='W')
ttk.Button(buttons_frame, text=" Stop immediately ", command=stop_progressbar).grid(column=0, row=2, sticky='W')
ttk.Button(buttons_frame, text=" Stop after second ", command=progressbar_stop_after).grid(column=0, row=3, sticky='W')

 

순환문에 버튼프레임의 자식인 추가적인 패딩을 추가하고, Tab2의 자식으로 추가적인 패딩을 추가한다.

# 순환문에 buttons_frame의 자식인 추가적인 패딩 추가
for child in buttons_frame.winfo_children():
    child.grid_configure(padx=2, pady=2)

# Tab2의 자식으로 추가적인 패딩 추가
for child in mighty2.winfo_children():
    child.grid_configure(padx=8, pady=2)

 

코드를 실행하고 프로그레스바 버튼을 클릭하면 위 그림과 같은 GUI를 볼 수 있다. 

728x90
반응형
posted by 조이키트 블로그
2024. 1. 3. 20:05 파이썬 GUI
728x90
반응형

메시지 박스는 사용자에게 피드백을 제공하는 팝업창이며, 잠재적 문제와 치명적인 오류를 암시하는 정보가 될 수 있다.

먼저 Help>About 메뉴를 만들고 About 메뉴를 클릭시 정보, 경고, 에러 메시지를 출력하는 프로그램을 만든다.

 

출력된 메시지 박스

 

 

전체코드

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import Menu
from tkinter import messagebox as msg

win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("GUI Message_Box")   # 제목을 설정하기 위한 인스턴스 변수 사용

# 메뉴바 생성하기
menu_bar = Menu(win)
win.config(menu=menu_bar)

def _quit():
    win.quit()
    win.destroy()
    exit()

# 메뉴를 생성하고 메뉴 아이템 추가하기
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

def _msgBox():
    msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter' 'This year is 2024.')
    msg.showwarning('Python Message Warning Box', 'A Python GUI created using tkinter' '\nWarning: There might be a bug in this code.')
    msg.showerror('Python Message Error Box', 'A Python GUI created using tkinter:' '\nError : Houston ~ we Do have a serious PROBLEM!')
    answer = msg.askyesnocancel("Python Message Multi Choice Box", "Are you sure you really wish to do this?")


help_menu = Menu(menu_bar, tearoff=0)
help_menu.add_command(label="About", command=_msgBox)
menu_bar.add_cascade(label="Help", menu=help_menu)


win.mainloop()

 

코드 설명

 

import문이 있는 모듈의 맨 위에 다음 코드를 추가한다.

from tkinter import messagebox as msg

 

다음 메시지박스를 표시하는 4개의 콜백함수를 만든다.

def _msgBox():
    msg.showinfo('Python Message Info Box', 'A Python GUI created using tkinter' 'This year is 2024.')
    msg.showwarning('Python Message Warning Box', 'A Python GUI created using tkinter' '\nWarning: There might be a bug in this code.')
    msg.showerror('Python Message Error Box', 'A Python GUI created using tkinter:' '\nError : Houston ~ we Do have a serious PROBLEM!')
    answer = msg.askyesnocancel("Python Message Multi Choice Box", "Are you sure you really wish to do this?")

 

콜백함수를 추가하고 클릭 이벤트를 처리하기 위해 Helf 메뉴 명령 속성에 추가했다.

help_menu = Menu(menu_bar, tearoff=0)
help_menu.add_command(label="About", command=_msgBox)
menu_bar.add_cascade(label="Help", menu=help_menu)

 

askyesnocancel 메시지 박스는 사용자가 클릭한 버튼에 따라 다른 값을 반환한다. 답을 변수에 캡처해 어떤 답을 선택했는지에 따라 다른 코드를 쓸 수 있다. 

728x90
반응형
posted by 조이키트 블로그
2024. 1. 2. 20:07 파이썬 GUI
728x90
반응형

여기서는 간단한 GUI를 만든 다음 이전 레시피의 위젯을 추가하고 이를 새로운 탭 레이아웃에 배치한다.

 

Tab1과 Tab2를 추가하여 만들어진 완성된 GUI의 모습이다.

 

 

전체코드

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import scrolledtext
from tkinter import Menu

win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("파이썬 GUI")   # 제목을 설정하기 위한 인스턴스 변수 사용
tabControl = ttk.Notebook(win)
tab1 = ttk.Frame(tabControl)
tabControl.add(tab1, text='Tab 1')
tab2 = ttk.Frame(tabControl)
tabControl.add(tab2, text='Tab 2')
tabControl.pack(expand=1, fill="both")

# tab1을 부모로 사용한 라벨프레임
mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
mighty.grid(column=0, row=0, padx=8, pady=4)

# mighty를 부모로 사용한 라벨
a_label = ttk.Label(mighty, text="Enter a name:")
a_label.grid(column=0, row=0, sticky='W')

name = tk.StringVar()  # StringVar 변수를 생성하고 tkinter의 별칭으로 tk를 사용
name_entered = ttk.Entry(mighty, width=12, textvariable=name) # ttk.Entry 위젯을 생성하고 다른 변수에 할당
name_entered.grid(column=0, row=1) # 위젯의 위치 지정
name_entered.focus()

# 다른 라벨 추가하기
ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)

number = tk.StringVar()
number_chosen = ttk.Combobox(mighty, width=12, textvariable=number)  # ttk.Combobox 위젯 생성
number_chosen['values'] = (1, 2, 4, 10, 100) # 콤보박스 위젯 값 할당
number_chosen.grid(column=1, row=1) # 콤보박스 위젯 위치 지정
number_chosen.current(0)

def click_me():  # click_me() 함수 정의 
    action.configure(text='Hello ' + name.get())
    a_label.configure(foreground='red')
    

action = ttk.Button(mighty, text="Click Me!", command=click_me) # ttkfmf 사용해 버튼을 생성하고 text 속성을 전잘 
action.grid(column=2, row=1)
action.configure(state='enable')

# 스크롤되는 텍스트 위젯
scrol_w = 50  # 높이와 넓이를 위한 변수 정의 
scrol_h = 5

# ScrolledText 위젯 생성
scr = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scr.grid(column=0, row=5, columnspan=3) # 스크롤 위젯의 위치 지정

mighty2 = ttk.LabelFrame(tab2, text= 'The Snake ')
mighty2.grid(column=0, row=0, padx=8, pady=4)

chVarDis = tk.IntVar()
check1 = tk.Checkbutton(mighty2, text="Disabled", variable=chVarDis, state='disabled')
check1.select()  # 상태를 select로 설정
check1.grid(column=0, row=4, sticky=tk.W, padx= 20, pady=10)  # 체크박스 위치 지정

chVarUn = tk.IntVar()  
check2 = tk.Checkbutton(mighty2, text="UnChecked", variable=chVarUn)
check2.deselect()  # 상태를 deselect로 설정
check2.grid(column=1, row=4, sticky=tk.W, padx= 20, pady=10)

chVarEn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check3 = tk.Checkbutton(mighty2, text="Enabled", variable=chVarEn)
check3.select()  # 상태를 select로 설정
check3.grid(column=2, row=4, sticky=tk.W, padx= 20, pady=10)

# 생상 이름을 저장하는 모듈 레벨의 전역변수 생성
COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

# 라디오 버튼을 위한 콜백함수 생성
def radCall():
    radSel=radVar.get()
    if   radSel == 1: mighty2.configure(tex=COLOR1)
    elif radSel == 2: mighty2.configure(text=COLOR2)
    elif radSel == 3: mighty2.configure(text=COLOR3)

# 1개의 변수를 사용하여 3개의 라디오버튼 생성
radVar = tk.IntVar()
 
# 3개의 tk 라디오 버튼 생성
rad1 = tk.Radiobutton(mighty2, text=COLOR1, variable=radVar, value=1, command=radCall)
rad1.grid(column=0, row=6, sticky=tk.W, columnspan=3, padx= 20, pady=10)  # 그리드 레이아웃을 사용해 위치 지정

rad2 = tk.Radiobutton(mighty2, text=COLOR2, variable=radVar, value=2, command=radCall)
rad2.grid(column=1, row=6, sticky=tk.W, columnspan=3, padx= 20, pady=10)

rad3 = tk.Radiobutton(mighty2, text=COLOR3, variable=radVar, value=3, command=radCall)
rad3.grid(column=2, row=6, sticky=tk.W, columnspan=3, padx= 20, pady=10)


# 각 라벨 주변에 공간 추가하기
for child in mighty.winfo_children():
    child.grid_configure(padx=8)

for child in mighty2.winfo_children():
    child.grid_configure(padx=8)

# 메뉴바 생성하기
menu_bar = Menu(win)
win.config(menu=menu_bar)

def _quit():
    win.quit()
    win.destroy()
    exit()

# 메뉴를 생성하고 메뉴 아이템 추가하기
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

help_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Help", menu=help_menu)
help_menu.add_command(label="About")

#라벨 프레임
buttons_frame = ttk.LabelFrame(mighty2, text=' Labels in a Frame ')
buttons_frame.grid(column=0, row=7, padx=20, pady=40)

ttk.Label(buttons_frame, text="Label1").grid(column=0, row=0, sticky=tk.W, padx= 20, pady=10)
ttk.Label(buttons_frame, text="Label2").grid(column=1, row=0, sticky=tk.W, padx= 20, pady=10)
ttk.Label(buttons_frame, text="Label3").grid(column=2, row=0, sticky=tk.W, padx= 20, pady=10)


win.mainloop()

 

코드 설명

모듈의 최상단에 tkinter를 임포트한다.

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함

 

Tk 클래스의 인스턴스를 생성한다.

win = tk.Tk()  # Tk 클래스의 인스턴스 생성

 

ttk 노트북을 사용해 탭컨트롤을 생성한다.

tabControl = ttk.Notebook(win)

 

탭컨트롤에 Tab1과 Tab2를 추가한다.

tab1 = ttk.Frame(tabControl)
tabControl.add(tab1, text='Tab 1')
tab2 = ttk.Frame(tabControl)
tabControl.add(tab2, text='Tab 2')

 

 

pack을 사용해 GUI 내부에 컨트롤을 가시화한다.

tabControl.pack(expand=1, fill="both")

 

라벨을 라벨프레임에 추가한다.

mighty = ttk.LabelFrame(tab1, text=' Mighty Python ')
mighty.grid(column=0, row=0, padx=8, pady=4)

 

# mighty를 부모로 사용한 라벨
a_label = ttk.Label(mighty, text="Enter a name:")
a_label.grid(column=0, row=0, sticky='W')

 

Tab1에는 위의 화면상에 Enter a name, Choose a number, Click Me!, 스크롤 위젯 기능이 들어간 부분을  mighty라는 변수를 사용해 적용시켰다. 

# mighty를 부모로 사용한 라벨
a_label = ttk.Label(mighty, text="Enter a name:")
a_label.grid(column=0, row=0, sticky='W')

name = tk.StringVar()  # StringVar 변수를 생성하고 tkinter의 별칭으로 tk를 사용
name_entered = ttk.Entry(mighty, width=12, textvariable=name) # ttk.Entry 위젯을 생성하고 다른 변수에 할당
name_entered.grid(column=0, row=1) # 위젯의 위치 지정
name_entered.focus()

# 다른 라벨 추가하기
ttk.Label(mighty, text="Choose a number:").grid(column=1, row=0)

number = tk.StringVar()
number_chosen = ttk.Combobox(mighty, width=12, textvariable=number)  # ttk.Combobox 위젯 생성
number_chosen['values'] = (1, 2, 4, 10, 100) # 콤보박스 위젯 값 할당
number_chosen.grid(column=1, row=1) # 콤보박스 위젯 위치 지정
number_chosen.current(0)

def click_me():  # click_me() 함수 정의 
    action.configure(text='Hello ' + name.get())
    a_label.configure(foreground='red')
    

action = ttk.Button(mighty, text="Click Me!", command=click_me) # ttkfmf 사용해 버튼을 생성하고 text 속성을 전잘 
action.grid(column=2, row=1)
action.configure(state='enable')

# 스크롤되는 텍스트 위젯
scrol_w = 50  # 높이와 넓이를 위한 변수 정의 
scrol_h = 5

# ScrolledText 위젯 생성
scr = scrolledtext.ScrolledText(mighty, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scr.grid(column=0, row=5, columnspan=3) # 스크롤 위젯의 위치 지정

 

Tab2에는 체크박스, 라디오 버튼, Labels in a Frame  기능이 들어간 부분을 mighty2라는 변수를 사용해 적용시켰다.

mighty2 = ttk.LabelFrame(tab2, text= 'The Snake ')
mighty2.grid(column=0, row=0, padx=8, pady=4)

chVarDis = tk.IntVar()
check1 = tk.Checkbutton(mighty2, text="Disabled", variable=chVarDis, state='disabled')
check1.select()  # 상태를 select로 설정
check1.grid(column=0, row=4, sticky=tk.W, padx= 20, pady=10)  # 체크박스 위치 지정

chVarUn = tk.IntVar()  
check2 = tk.Checkbutton(mighty2, text="UnChecked", variable=chVarUn)
check2.deselect()  # 상태를 deselect로 설정
check2.grid(column=1, row=4, sticky=tk.W, padx= 20, pady=10)

chVarEn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check3 = tk.Checkbutton(mighty2, text="Enabled", variable=chVarEn)
check3.select()  # 상태를 select로 설정
check3.grid(column=2, row=4, sticky=tk.W, padx= 20, pady=10)

# 생상 이름을 저장하는 모듈 레벨의 전역변수 생성
COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

# 라디오 버튼을 위한 콜백함수 생성
def radCall():
    radSel=radVar.get()
    if   radSel == 1: mighty2.configure(tex=COLOR1)
    elif radSel == 2: mighty2.configure(text=COLOR2)
    elif radSel == 3: mighty2.configure(text=COLOR3)

# 1개의 변수를 사용하여 3개의 라디오버튼 생성
radVar = tk.IntVar()
 
# 3개의 tk 라디오 버튼 생성
rad1 = tk.Radiobutton(mighty2, text=COLOR1, variable=radVar, value=1, command=radCall)
rad1.grid(column=0, row=6, sticky=tk.W, columnspan=3, padx= 20, pady=10)  # 그리드 레이아웃을 사용해 위치 지정

rad2 = tk.Radiobutton(mighty2, text=COLOR2, variable=radVar, value=2, command=radCall)
rad2.grid(column=1, row=6, sticky=tk.W, columnspan=3, padx= 20, pady=10)

rad3 = tk.Radiobutton(mighty2, text=COLOR3, variable=radVar, value=3, command=radCall)
rad3.grid(column=2, row=6, sticky=tk.W, columnspan=3, padx= 20, pady=10)

#라벨 프레임
buttons_frame = ttk.LabelFrame(mighty2, text=' Labels in a Frame ')
buttons_frame.grid(column=0, row=7, padx=20, pady=40)

ttk.Label(buttons_frame, text="Label1").grid(column=0, row=0, sticky=tk.W, padx= 20, pady=10)
ttk.Label(buttons_frame, text="Label2").grid(column=1, row=0, sticky=tk.W, padx= 20, pady=10)
ttk.Label(buttons_frame, text="Label3").grid(column=2, row=0, sticky=tk.W, padx= 20, pady=10)

 

위의 코드들을 보면 각 부분들의 구체적인 설명은 하지 않았다. 다만 Tab1과 Tab2를 mighty와 mighty2라는 변수로 부모 컨테이너를 지정해 일부 기능들을 분류하여 적용하는데 중점적으로 설명하였다.

728x90
반응형
posted by 조이키트 블로그
2024. 1. 2. 19:52 파이썬 GUI
728x90
반응형

여기서는 메인 윈도우에 메뉴바를 추가하고 메뉴 막대에 메뉴항목을 추가한다.

 

맥북에서 메뉴바가 만들어진 모습

 

전체코드

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import scrolledtext
from tkinter import Menu

win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("메뉴바 만들기")   # 제목을 설정하기 위한 인스턴스 변수 사용

# 메뉴바 생성하기
menu_bar = Menu(win)
win.config(menu=menu_bar)

def _quit():
    win.quit()
    win.destroy()
    exit()

# 메뉴를 생성하고 메뉴 아이템 추가하기
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

help_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Help", menu=help_menu)
help_menu.add_command(label="About")

win.mainloop()

 

동작원리 

먼저 tkinter에서 Menu 클래스를 임포트해야 한다.

from tkinter import Menu

 

다음 메뉴바를 만든다. 

menu_bar = Menu(win)

Menu 모듈 클래스의 생성자를 호출하고 메인 GUI 인스턴스인 win을 전달한다. Menu 객체의 인스턴스를 menu_bar 변수에 저장한다.

win.config(menu=menu_bar)

다음 메뉴바에 메뉴 항목들을 배치한다. 여기서는 File에는 New, Exit를 나열하였고, Help메뉴에는 About항목을 나열하였다.

file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label="New")
file_menu.add_separator()
file_menu.add_command(label="Exit", command=_quit)
menu_bar.add_cascade(label="File", menu=file_menu)

help_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="Help", menu=help_menu)
help_menu.add_command(label="About")

 

Exit 항목에 _quit 함수를 사용해 클릭시 창이 닫기게 한다.

def _quit():
    win.quit()
    win.destroy()
    exit()

 

728x90
반응형
posted by 조이키트 블로그
2023. 12. 31. 14:31 파이썬 GUI
728x90
반응형

파이썬은 매우 강력한 언어다. 내장된 tkinter 모듈이 함께 제공되므로 단 몇 줄의 코드로 파이썬 GUI를 만들 수 있다.

 

아래 그림은 완성된 파이썬 GUI 폼이다. 

파이썬 GUI가 실행된 모습

 

전체코드

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import scrolledtext

win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("파이썬 GUI")   # 제목을 설정하기 위한 인스턴스 변수 사용

a_label = ttk.Label(win)  # ttk를 사용한 라벨 추가
a_label.grid(column=0, row=0)  # 라벨의 위치 지정

def click_me():  # click_me() 함수 정의 
    action.configure(text='Hello ' + name.get())

    a_label.configure(foreground='red')
    #a_label.configure(text='A Red Label')

ttk.Label(win, text="이름 입력").grid(column=0, row=0) 
name = tk.StringVar()  # StringVar 변수를 생성하고 tkinter의 별칭으로 tk를 사용
name_entered = ttk.Entry(win, width=12, textvariable=name) # ttk.Entry 위젯을 생성하고 다른 변수에 할당
name_entered.grid(column=0, row=1) # 위젯의 위치 지정
name_entered.focus()

action = ttk.Button(win, text="Click Me!", command=click_me) # ttkfmf 사용해 버튼을 생성하고 text 속성을 전잘 
action.grid(column=2, row=1)
action.configure(state='enable')

ttk.Label(win, text="번호 선택").grid(column=1, row=0) # ttk.Label 위젯 생성
number = tk.StringVar()
number_chosen = ttk.Combobox(win, width=12, textvariable=number)  # ttk.Combobox 위젯 생성
number_chosen['values'] = (1, 2, 4, 42, 1000) # 콤보박스 위젯 값 할당
number_chosen.grid(column=1, row=1) # 콤보박스 위젯 위치 지정
number_chosen.current(0)

# 3개의 체크박스 생성 
chVarDis = tk.IntVar()  # tk.IntVar 인스턴스 생성
check1 = tk.Checkbutton(win, text="Disabled", variable=chVarDis, state='disabled')
check1.select()  # 상태를 select로 설정
check1.grid(column=0, row=4, sticky=tk.W)  # 체크박스 위치 지정

chVarUn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check2 = tk.Checkbutton(win, text="UnChecked", variable=chVarUn)
check2.deselect()  # 상태를 deselect로 설정
check2.grid(column=1, row=4, sticky=tk.W)

chVarEn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check3 = tk.Checkbutton(win, text="Enabled", variable=chVarEn)
check3.select()  # 상태를 select로 설정
check3.grid(column=2, row=4, sticky=tk.W)

# 생상 이름을 저장하는 모듈 레벨의 전역변수 생성
COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

# 라디오 버튼을 위한 콜백함수 생성
def radCall():
    radSel=radVar.get()
    if   radSel == 1: win.configure(background=COLOR1)
    elif radSel == 2: win.configure(background=COLOR2)
    elif radSel == 3: win.configure(background=COLOR3)

# 1개의 변수를 사용하여 3개의 라디오버튼 생성
radVar = tk.IntVar()
 
# 3개의 tk 라디오 버튼 생성
# 그리드 레이아웃을 사용해 배치
rad1 = tk.Radiobutton(win, text=COLOR1, variable=radVar, value=1, command=radCall)
rad1.grid(column=0, row=5, sticky=tk.W, columnspan=3)  # 그리드 레이아웃을 사용해 위치 지정

rad2 = tk.Radiobutton(win, text=COLOR2, variable=radVar, value=2, command=radCall)
rad2.grid(column=1, row=5, sticky=tk.W, columnspan=3)

rad3 = tk.Radiobutton(win, text=COLOR3, variable=radVar, value=3, command=radCall)
rad3.grid(column=2, row=5, sticky=tk.W, columnspan=3)

# 스크롤되는 텍스트 위젯
scrol_w = 50  # 높이와 넓이를 위한 변수 정의 
scrol_h = 5

# ScrolledText 위젯 생성
scr = scrolledtext.ScrolledText(win, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scr.grid(column=0, columnspan=3) # 스크롤 위젯의 위치 지정

win.resizable(True, False)  # Tk 인스턴스 변수 win의 resizable 메소드 호출
win.mainloop()  # 윈도우 메인 이벤트 순환문 시작

 

 

그럼 이제부터 위 전체코드에 대한 동작원리를 차례대로 살펴본다.

 

1. GUI 폼에 라벨 추가하기 

라벨은 GUI에 값을 추가하는 매우 간단한 위젯이다. 이는 사용자에게 엔트리 위젯의 의미를 안내하며 사용자가 데이터를 입력할 필요없이 위젯이 표시하는 데이터를 설명할 수도 있다. 

import tkinter as tk      
from tkinter import ttk  # ttk를 임포트 함
from tkinter import scrolledtext

win = tk.Tk()  # Tk 클래스의 인스턴스 생성
win.title("파이썬 GUI")   # 제목을 설정하기 위한 인스턴스 변수 사용

a_label = ttk.Label(win)  # ttk를 사용한 라벨 추가
a_label.grid(column=0, row=0)  # 라벨의 위치 지정

ttk.Label(win, text="이름 입력").grid(column=0, row=0)

 

위 코드에서는 tkinter 패키지에서 별도의 모듈을 가져온다. ttk 모듈에는 GUI를 멋지게 보이게 하는 노트북, 프로그레스바, 라벨과 색다른 버튼과 같은 고급 위젯이 있다. ttk는 tkinter 패키지 내의 확장이다.

ttk.Label(win, text="이름 입력").grid(column=0, row=0)

은 mainloop를 호출하기 직전에 라벨을 GUI에 추가한다. window 인스턴스를 ttk.Label 생성자에 전달하고 text 속성을 설정한다.

 

2. 버튼 생성 및 텍스트박스 위젯 생성하기

아래 그림은 이름 입력칸에 문자를 입력하고 Click me! 버튼을 클릭하였을 때 모습이다. 

이름입력칸에 문자를 입력하고 click me!를 누른 모습

 

a_label = ttk.Label(win)  # ttk를 사용한 라벨 추가
a_label.grid(column=0, row=0)  # 라벨의 위치 지정

def click_me():  # click_me() 함수 정의 
    action.configure(text='Hello ' + name.get())

    a_label.configure(foreground='red')
    #a_label.configure(text='A Red Label')

ttk.Label(win, text="이름 입력").grid(column=0, row=0) 
name = tk.StringVar()  # StringVar 변수를 생성하고 tkinter의 별칭으로 tk를 사용
name_entered = ttk.Entry(win, width=12, textvariable=name) # ttk.Entry 위젯을 생성하고 다른 변수에 할당
name_entered.grid(column=0, row=1) # 위젯의 위치 지정
name_entered.focus()

action = ttk.Button(win, text="Click Me!", command=click_me) # ttkfmf 사용해 버튼을 생성하고 text 속성을 전잘 
action.grid(column=2, row=1)
action.configure(state='enable')

 

1단계에서 새로운 파이썬 모듈을 만들고 2단계에서 tkinter의 stringVar 타입을 추가하고 name 변수에 저장한다. 엔트리 위젯을 생성할 때 이 변수를 사용하고 엔트리 위젯의 textvariable 속성에 할당한다. 엔트리 위젯에서 텍스트를 입력할 때마다 이 텍스트는 name 변수에 저장된다. 

action.configure(text='Hello ' + name.get())

name.get()을 사용해 엔트리 위젯의 값을 가져온다. 버튼을 생성할 때 action 변수에 참조를 저장한다. action 변수를 사용해 버튼의 configure 메소드를 호출하고 버튼의 텍스트를 업데이트 한다.

name = tk.StringVar()

이는 변수 name을 생성한다. 이 변수는 엔트리 위젯에 바인딩돼 있으며 click_me() 함수에서 이 변수에 대해 get()을 호출해 엔트리 위젯의 값을 검색할 수 있다. 

 

3. 콤보박스 위젯 생성하기

여기서는 초기 기본값을 가질 수 있는 드롭다운 콤보박스를 추가해 GUI를 개선한다. 사용자의 선택을 제한할 수 있지만 사용자가 원하는 대로 입력하도록 허용할 수도 있다.

 

ttk.Label(win, text="번호 선택").grid(column=1, row=0) # ttk.Label 위젯 생성
number = tk.StringVar()
number_chosen = ttk.Combobox(win, width=12, textvariable=number)  # ttk.Combobox 위젯 생성
number_chosen['values'] = (1, 2, 4, 42, 1000) # 콤보박스 위젯 값 할당
number_chosen.grid(column=1, row=1) # 콤보박스 위젯 위치 지정
number_chosen.current(0)

 

ttk.Label(win, text="번호 선택").grid(column=1, row=0)

여기서는 새로 작성된 콤보박스와 일치하는 두 번째 라벨을 추가한다. 

number = tk.StringVar() 

이는 특별한 tkinter 유형 StringVar의 변수에 상자의 값을 지정한다.

number_chosen['values'] = (1, 2, 4, 42, 1000)

정수 튜플을 따음표로 묶지 않았지만 tk.StringVar 유형으로 선언했기 때문에 문자열에 캐스팅됐다.

콤보박스에서 1000을 선택하면 number 변수의 값이 1000이 된다.

number_chosen = ttk.Combobox(win, width=12, textvariable=number)

이는 콤보박스에서 선택한 값을 textvariable 속성을 통해 number 변수에 바인딩한다.

 

4. 초기 상태가 다른 체크 버튼 만들기

이번에는 세 개의 체크 버튼 위젯을 추가하고 각각 다른 초기 상태를 가진다. 

- 첫 번째 항목은 비활성화돼 있으며 체크 표시가 되어있다. 위젯이 비활성화 되어 있어 사용자는 이 체크 표시를 제거할 수 었다.

- 두 번째 항목은 체크 번튼이 활성화 되어 있으며 기본적으로 체크 표시가 없지만 사용자가 클릭해 체크 표시를 추가할 수 있다.

- 세 번째 체크 버튼은 기본적으로 활성화 되어 있고 선택되어 있다. 사용자는 원하는 만큼 위젯을  선택 최소하고 다시 체크할 수 있다.

코드는 다음과 같다. 

# 3개의 체크박스 생성 
chVarDis = tk.IntVar()  # tk.IntVar 인스턴스 생성
check1 = tk.Checkbutton(win, text="Disabled", variable=chVarDis, state='disabled')
check1.select()  # 상태를 select로 설정
check1.grid(column=0, row=4, sticky=tk.W)  # 체크박스 위치 지정

chVarUn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check2 = tk.Checkbutton(win, text="UnChecked", variable=chVarUn)
check2.deselect()  # 상태를 deselect로 설정
check2.grid(column=1, row=4, sticky=tk.W)

chVarEn = tk.IntVar()   # tk.IntVar 인스턴스 생성
check3 = tk.Checkbutton(win, text="Enabled", variable=chVarEn)
check3.select()  # 상태를 select로 설정
check3.grid(column=2, row=4, sticky=tk.W)

 

chVarDis = tk.IntVar()

chVarUn = tk.IntVar()

chVarEn = tk.IntVar()

IntVar 유형의 세 변수를 만들고 각각의 변수 다음 줄에서 이러한 변수를 전달하는 Checkbutton 위젯을 생성한다.

 

5. 라디오 버튼 위젯 만들기

 

여기서는 3개의 라디오 버튼 위젯을 생성하고 어떤 라디오 버튼이 선택되었는지에 따라 기본 폼의 색상이 변경된다.

COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

# 라디오 버튼을 위한 콜백함수 생성
def radCall():
    radSel=radVar.get()
    if   radSel == 1: win.configure(background=COLOR1)
    elif radSel == 2: win.configure(background=COLOR2)
    elif radSel == 3: win.configure(background=COLOR3)

# 1개의 변수를 사용하여 3개의 라디오버튼 생성
radVar = tk.IntVar()
 
# 3개의 tk 라디오 버튼 생성
# 그리드 레이아웃을 사용해 배치
rad1 = tk.Radiobutton(win, text=COLOR1, variable=radVar, value=1, command=radCall)
rad1.grid(column=0, row=5, sticky=tk.W, columnspan=3)  # 그리드 레이아웃을 사용해 위치 지정

rad2 = tk.Radiobutton(win, text=COLOR2, variable=radVar, value=2, command=radCall)
rad2.grid(column=1, row=5, sticky=tk.W, columnspan=3)

rad3 = tk.Radiobutton(win, text=COLOR3, variable=radVar, value=3, command=radCall)
rad3.grid(column=2, row=5, sticky=tk.W, columnspan=3)

 

COLOR1 = "Blue"
COLOR2 = "Gold"
COLOR3 = "Red"

각 라디오 버튼을 생성할 때 사용하는 모듈 수준의 전역변수와 기본폼의 배경색을 변경하는 액션을 생성하는 콜백함수를 생성한다.

 

def radCall():
radSel=radVar.get()
if radSel == 1: win.configure(background=COLOR1)
elif radSel == 2: win.configure(background=COLOR2)
elif radSel == 3: win.configure(background=COLOR3)

사용자의 선택에 따라 메인폼의 백그라운드를 변경하는 콜백함수이다.

radVar = tk.IntVar()

tk.IntVar 변수를 만들고 3개의 라디오 버튼 모두에서 사용할 변수를 하나만 만들면 된다. 여기서 어떤 라디오 버튼을 선택하든 다른 모든 라디오 버튼은 자동으로 선택 해제된다.

rad1 = tk.Radiobutton(win, text=COLOR1, variable=radVar, value=1, command=radCall)
rad1.grid(column=0, row=5, sticky=tk.W, columnspan=3) # 그리드 레이아웃을 사용해 위치 지정

rad2 = tk.Radiobutton(win, text=COLOR2, variable=radVar, value=2, command=radCall)
rad2.grid(column=1, row=5, sticky=tk.W, columnspan=3)

rad3 = tk.Radiobutton(win, text=COLOR3, variable=radVar, value=3, command=radCall)
rad3.grid(column=2, row=5, sticky=tk.W, columnspan=3)

여기서는 3개의 라디오 버튼을 만들어 메인폼에 할당하고 콜백함수에서 사용할 변수를 전달해 메인 윈도우의 배경을 변경하는 액션을 생성한다.

Gold 라디오 버튼을 눌렀을 때 모습

 

6. 스크롤 되는 텍스트 위젯 만들기

메모장 같은 위젯으로 줄 바꿈과 텍스트가 ScrolledText 위젯의 높이보다 커지면 자동으로 세로 스크롤 막대가 활성화된다.

scrol_w = 50  # 높이와 넓이를 위한 변수 정의 
scrol_h = 5

# ScrolledText 위젯 생성
scr = scrolledtext.ScrolledText(win, width=scrol_w, height=scrol_h, wrap=tk.WORD)
scr.grid(column=0, columnspan=3) # 스크롤 위젯의 위치 지정

# win.resizable(True, False)  # Tk 인스턴스 변수 win의 resizable 메소드 호출
win.mainloop()  # 윈도우 메인 이벤트 순환문 시작

 

from tkinter import scrolledtext

먼저 ScrolledText 위젯 클래스가 포함된 모듈을 가져온다. 

 

scrol_w = 50 # 높이와 넓이를 위한 변수 정의
scrol_h = 5

만들고자 하는 ScrolledText 위젯의 너비와 높이를 정의한다. 이 값은 ScrolledText 위젯 생성자에 전달되는 하드코딩된 값이다.

scr = scrolledtext.ScrolledText(win, width=scrol_w, height=scrol_h, wrap=tk.WORD)

wrap=tk.WORD를 전달해 위젯에 대한 속성을 설정한다. wrap 속성을 tk.WORD로 설정하면 ScrolledText 위젯에 단어별로 줄 바꿈을 표시해 단어내에서 줄 바꿈하지 않도록 한다.

728x90
반응형
posted by 조이키트 블로그
2023. 10. 21. 20:55 C언어 기초
728x90
반응형

논리 연산자란 AND(논리곱), OR(논리합), NOT(논리부정)을 표현하는 연산자이다.

연산자 연산자의 기능
&& A&&B : A와 B 모두 참이면 연산결과로 참을 반환(논리 AND)
|| A||B : A와 B 둘 중 하나라도 참이면 연산결과로 참을 반환(논리 OR)
! !A : A가 참이면 거짓, A가 거짓이면 참을 반환(논리 NOT)
#include<stdio.h>
int main(void)
{
	int num1 = 10;
	int num2 = 12;
	int result1, result2, result3;

	result1 = (num1 == 10 && num2 == 12); // num1이 10이고 num2가 12이면 참
	result2 = (num1 < 12 || num2>12); // num1이 12보다 작거나 num2가 12보다 크면 참
	result3 = (!num1==10); // num1이 10가 같으면 거짓

	printf("result1: %d \n", result1);
	printf("result2: %d \n", result2);
	printf("result3: %d \n", result3);
	return 0;
}

출력결과

 

728x90
반응형
posted by 조이키트 블로그
2023. 10. 16. 19:40 C언어 기초
728x90
반응형

관계 연산자는 대소와 동등의 관계를 따지는 연산자이다. 예를 들어서 a와 b라는 숫자 또는 변수가 있다면 둘이 같은지, 누가 더 크고 작은지를 따지는 연산자이다. 조건을 만족하면 참을, 만족하지 않으면 거짓을 반환한다. 

 

#include<stdio.h>
int main(void)
{
	int num1 = 10;
	int num2 = 12;
	int result1, result2, result3;

	result1 = (num1 == num2);
	result2 = (num1 <= num2);
	result3 = (num1 > num2);

	printf("result1: % d \n", result1);
	printf("result2: % d \n", result2);
	printf("result3: % d \n", result3);
	return 0;
}

출력결과

출력결과를  보면 0이 출력되었다는 것은 관계연산의 결과가 거짓이었다는 뜻이고 1이 출력되었다는 것은 관계연산의 결과가 참이었다는 뜻이다. 

728x90
반응형
posted by 조이키트 블로그
2023. 10. 16. 19:27 C언어 기초
728x90
반응형

연산자는 변수에 저장된 값을 1 증가 및 감소시키는 경우에 사용되는 연산자이다. 

 

1. 증가 연산자

#include<stdio.h>
int main(void)
{
	int num1 = 12;
	int num2 = 12;

	printf("num1: %d \n", num1);
	printf("num1++: %d \n", num1++);  // 후위 증가
	printf("num1: %d \n", num1);

	printf("num2: %d \n", num2);
	printf("++num2: %d \n", ++num2);  // 전위 증가
	printf("num2: %d \n", num2);
	return 0;
}

++num : 값을 1 증가 후, 속한 문장의 나머지를 진행한다. (선 증가, 후 연산)

num++ : 속한 문장을 먼저 진행한 후 값을 1 증가한다. (선 연산, 후 증가)

--num : 값을 1감소 후, 속한 문장의 나머지를 진행한다. (선 감소, 후 연산)

num-- : 속한 문장을 먼저 진행한 후, 값을 1 감소한다. (선 연산, 후 감소)

 

++ 연산자와 -- 연산자는 이름 그대로 값을 1 증가 및 감소시키는 연산자이다. 그런데 이 두 연산자는 삽입된 위치에 따라서 그 의미가 달라진다. 피연산자의 왼편에 붙는 경우에는 먼저 변수에 저장된 값을 증가 및 감소시키고 나서 문장의 나머지 부분을 실행하게 된다. 반면 피연산자의 오른쪽에 붙는 경우에는 문장 전체를 실행한 다음에 값을 증가 및 감소시키게 된다. 

 

출력결과

 

2. 감소 연산자

#include<stdio.h>
int main(void)
{
	int num1 = 10;
	int num2 = (num1--)+2;

	printf("num1: %d \n", num1);
	printf("num2: %d \n", num2);  // 후위 증가
	return 0;
}

출력결과

6행에서는 변수 num1에 대해서 선 연산 후 감소를 진행하고 있다. 그런데 이 연산의 앞과 뒤에 소괄호가 채워져 있다. C언어세는 소괄호도 연산자이다. 이는 수학의 소괄호와 의미가 같다. 즉 먼저 연산하라는 뜻이다. 

728x90
반응형
posted by 조이키트 블로그
2023. 10. 16. 18:32 C언어 기초
728x90
반응형

+연산자와 -연산자는 이항 연산자로서 덧셈과 뺄셈을 의미하지만 피연산자가 하나인 단항 연산자로서 부호를 뜻하기도 한다. 

#include<stdio.h>
int main(void)
{
	int num1 = +2;
	int num2 = -4;

	num1 = -num1;
	printf("num1: %d \n", num1);
	num2 = -num2;
	printf("num2: %d \n", num2);
	return 0;
}

출력결과

- 4행 : 숫자 2의 앞에 +를 붙여서 양의 정수 2를 표현하고 있다 

- 5행 : 음의 정수 4를 표현하기 위해서 -연산자를 사용하였다.

- 7행 : 변수 num1 값의 부호를 바꾸기 위해서 - 연산자가 사용되었다. 그리고 연산의 결과를 다시 변수 num1에 저장하였다.

- 9행 : 7행과 마찬가지로 변수 num2 값의 부호를 바꾸기 위해서 - 연산자가 사용되었다. 그리고 연산의 결과를 다시 변수 num2에 저장하였다.

728x90
반응형
posted by 조이키트 블로그
2023. 10. 6. 14:24 C언어 기초
728x90
반응형

문제1

"+" 더하기 연산자

#include<stdio.h>
int main()
{
	int num1 = 3;
	int num2 = 4;
	int result = num1 + num2;

	printf("덧셈 결과 : %d \n", result);
	printf("%d+%d=%d \n", num1, num2, result);
	printf("%d와(과) %d의 합은 %d입니다. \n", num1, num2, result);
	return 0;
}

출력결과

문제2

다양한 연산자(+, -, *, /, %)

#include<stdio.h>
int main()
{
	int num1 = 9, num2 = 4;
	printf("%d+%d=%d \n", num1, num2, num1 + num2);
	printf("%d-%d=%d \n", num1, num2, num1 - num2);
	printf("%dx%d=%d \n", num1, num2, num1 * num2);
	printf("%d/%d의 몫=%d \n", num1, num2, num1 / num2);
	printf("%d/%d의 나머지=%d \n", num1, num2, num1 % num2);
	return 0;
}

출력결과

문제3

복합 대입 연산자(*=, /=, %=, +=, -=)

#include<stdio.h>
int main()
{
	int num1 = 2, num2 = 4, num3 = 6, num4 = 8, num5 = 10;
	num1 += 3;
	num2 *= 4;
	num3 %= 5;
	num4 -= 6;
	num5 /= 7;
	printf("결과 : %d, %d, %d, %d, %d \n", num1, num2, num3, num4, num5);
	return 0;
}

출력결과

728x90
반응형
posted by 조이키트 블로그
2023. 10. 6. 13:51 C언어 기초
728x90
반응형

문제 1 : 다음의 출력결과를 보이도록 작성

제 이름은 홍길동입니다.

제 나이는 20살이고요.

제가 사는 곳의 번지수는 123-456입니다.

#include<stdio.h>
int main()
{
	printf("제 이름은 홍길동입니다. \n");
	printf("제 나이는 %d 살이고요. \n", 20);
	printf("제가 사는 곳의 번지수는 %d-%d 입니다. \n", 123, 456);
	return 0;
}

출력결과 

문제 2

4X5=20

7X9=63

#include<stdio.h>
int main()
{
	printf("%dX%d=%d \n",4,5,20);
	printf("%dX%d=%d \n",7,9,7*9);
	return 0;
}

 출력결과

728x90
반응형
posted by 조이키트 블로그
2023. 8. 29. 01:58 PHP
728x90
반응형

웹에서 파일을 업로드하려면 <form> 태그의 enctype 속성을 multipart/form-data로 설정해야 한다. 그리고 <input> 태그의 type 속성을 file로 설정해야 업로드할 파일을 선택하는 양식을 생성할 수 있다. name 속성을 upload로 설정하면 업로드한 파일이 $_POST["upload"] 배열에 저장된다.

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <form name="form1" method="post" action="view8.php" enctype="multipart/form-data">
            <ul>
                <li>이미지 업로드 : <input type="file" name="upload"></li>
                <li>설명 : <textarea name="comment" rows="3" cols="60"></textarea></li>
                <li><input type="submit" value="확인"></li>
            </ul>
        </form>
    </body>
</html>

업로드된 이미지에 대한 설명을 입력할 수 있는 텍스트 영역을 생성하기 위해 <textarea>태그를 사용하고 name 속성은 comment로 설정한다. <확인>을 클릭하면 view8.php 파일로 이동한다.

파일 선택을 하고 텍스트 영역에 이미지에 대한 설명을 입력한 다음 확인을 클릭하면 

다음과 같이 나타난다.

view8.php 파일의 소스 코드는 다음과 같다.

<html>
<head>
<meta charset="utf-8">
<link href="style.css" rel="stylesheet">
</head>
<body>
<?php
	$file_dir = "C:/xampp/htdocs/07/img/";
	$file_path = $file_dir.$_FILES["upload"]["name"];
	if(move_uploaded_file($_FILES["upload"]["tmp_name"], $file_path)) {
		$img_path = "img/".$_FILES["upload"]["name"];
?>
	<ul>
		<li><img src="<?= $img_path?>"></li>
		<li><?= $_POST["comment"]?></li>
	</ul>
<?php
	}
	else {
		echo "파일 업로드 오류가 발생했습니다!!!";
	}
?>
</body>
</html>

업로드된 이미지 파일을 저장할 경로가 $file_dir에 설정되어 있다.

$_FILES["upload"]["name"]은 업로드된 파일명을 나타낸다. 따라서 $file_path에는 저장할 폴더와 파일명을 포함한 경로가 저장된다.

move_uploaded_file($_FILES["upload"]["tmp_name"], $file_path)는 업로드된 파일을 설정한 파일 경로에 저장한다는 의미이다. 여기서 $_FILES["upload"]["tmp_name"]은 서버에 임시로 저장된 업로드된 파일명이고 $file_path는 업로드된 파일을 저장할 경로를 의미한다.

$img_path는 <img> 태그의 src 속성으로 설정한 폴더와 이미지 파일명을 포함한 경로를 의미한다.

$_POST["comment"]는 사용자가 텍스트 영역에 입력한 내용을 의미한다.

move_uploaded_file() 함수는 HTTP POST를 이용하여 업로드된 파일을 지정된 경로에 저장할 때 사용한다. 만약 해당 경로에 동일한 파일이 있으면 덮어쓰기를 한다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 28. 17:49 PHP
728x90
반응형

선택 박스는 회원가입 양식, 게시판, 쇼핑몰 등에서 주로 사용된다.

<html>
    <head>
        <meta charset="utf-8">
        <link href="style.css" rel="stylesheet">
    </head>
    <body>
        <form name="form1" method="post" action="view6.php">
            <ul>
                <li>이메일 : <input type="text" name="email1">
                <select name="email2">
                    <option value="" selected>선택하세요!</option>
                    <option value="naver.com">naver.com</option>
                    <option value="google.com">gmail.com</option>
                    <option value="hanmail.com">hanmail.net</option>
                </select>
                </li>
                <li><input type="submit" value="확인"></li>
            </ul>
        </form>
    </body>
</html>

위 코드를 실행하면 다음과 같다.

<확인>을 클릭하면 action 속성에 설정된 view6.php 파일로 이동한다.

<html>
    <head>
        <meta charset="utf-8">
        <link href="style.css" rel="stylesheet">
    </head>
    <body>
    <?php
                $email1 = $_POST["email1"];
                $email2 = $_POST["email2"];
                ?>
        <ul>
            <li>이메일 : <?php echo $email1."@".$email2; ?></li>
        </ul>
    </body>
</html>

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 28. 17:21 PHP
728x90
반응형

라디오 버튼과 달리 체크박스는 여러 항목 중에서 동시에 여러개를 선택하도록 할 때 사용한다. 

<html>
    <head>
        <meta charset="utf-8">
        <link href="style.css" rel="stylesheet">
    </head>
    <body>
        <form name="form1" method="post" action="view5.php">
            <h3>당신의 취미는?</h3>
            <ul>
                <li>영화감상 <input type="checkbox" name="hobby[]" value="영화감상"></li>
                <li>맛집탐방 <input type="checkbox" name="hobby[]" value="맛집탐방" checked></li>
                <li>독서 <input type="checkbox" name="hobby[]" value="독서"></li>
                <li>요가 <input type="checkbox" name="hobby[]" value="요가"></li>
                <li>축구 <input type="checkbox" name="hobby[]" value="축구"></li>
                <li><input type="submit" value="확인"></li>
            </ul>
        </form>
    </body>
</html>

출력 결과

체크박스를 생성하려면 <input> 태그의 type 속성을 checkbox로 설정해야 한다. 그리고 중복 선택이 가능하도록 name 속성은 배열(hobby[]) 로 설정하고, value 속성에는 화면에 출력할 각 항목을 설정한다. 체크박스에서 선택된 항목의 value 속성값은 $_POST["hobby"]로 전달된다. checked 속성은 초깃값을 의미하며 실행 결과를 보면 맛집탐방이 초깃값이다.

체크박스의 항목을 선택하고 <확인>을 클릭하면 action속성에 설정한 view5.php 파일로 이동한다.

<html>
    <head>
        <meta charset="utf-8">
        <link href="style.css" rel="stylesheet">
    </head>
    <body>
        <ul>
            <li>
                <?php
                $num = count($_POST["hobby"]);
                for($i = 0; $i < $num; $i++)
                {
                    echo $_POST["hobby"][$i];
                    if($i != $num - 1)
                    echo ", ";
                }
                ?>
            </li>
        </ul>
    </body>
</html>

$_POST["hobby"]에는 체크박스의 name 속성으로 설정한 hobby[]의 value 속성 값이 배열 형태로 저장된다. 즉 체크박스 항목의 value 속성값이 $_POST["hobby"][0], $_POST["hobby"][1]...에 차례대로 전달된다. count() 함수는 배열의 개수를 세는데 사용하고 변수 $num에는 선택된 체크박스 항목의 개수가 저장된다.

for문은 배열의 개수만큼 반복 수행한다.

체크박스에서 선택된 항목의 value 속성값을 화면에 출력한다.

항목 사이에 쉼표(,)를 넣어 출력하기 위해 if 구문을 이용한다. 항목의 마지막이 아니라면 항목 사이에 쉼표를 출력하라는 의미이다.

 

영화감상, 맛집탐방, 독서
728x90
반응형
posted by 조이키트 블로그
2023. 8. 28. 15:52 파이썬
728x90
반응형

다음 코드는 간단한 해시 함수를 사용하여 정수가 키인 딕셔너리를 구현하고 있다. 여기에서 기본적인 아이디어는 intDict 클래스의 인스턴스를 해시 버킷 리스트로 나타내는 것이며, 각 버킷은 키/값의 쌍들로 이루어진 리스트이다. 각 버킷을 리스트로 구현함으로 버킷에 해시되는 값들을 리스트에 저장하여 충돌을 해결할 수 있다. 인스턴스 변수 buckets는 numBuckets의 개수만큼의 빈 리스트로 초기화한다. dictkey키로 엔트리를 검색하거나 저장하려고 할 때 해시함수 %를 사용하여 dictkey를 정수로 반환하고 그 정수를 사용하여 buckets를 인덱스하여 해당하는 dictkey와 연관된 해시 버킷을 찾아낸다. 그 다음엔 그 버킷을 선형적으로 검색하여 dictkey키로 된 엔트리가 있는지 확인한다. 검색을 하는 경우에는 그 키로 된 엔트리가 없다면 None을 반환한다. 저장을 하려고 하는 경우에는 이미 들어가 있는 엔트리가 있다면 그 엔트리의 값을 대체하거나 엔트리가 없다면 새로운 엔트리를 추가한다.

# 해싱을 사용하여 딕셔너리 구현하기
class intDict(object):
    def __init__(self, numBuckets):
        self.buckets = []
        self.numBuckets = numBuckets
        for i in range(numBuckets):
            self.buckets.append([])

    def addEntry(self, dictKey, dictVal):
        hashBucket = self.buckets[dictKey%self.numBuckets]
        for i in range(len(hashBucket)):
            if hashBucket[i][0] == dictKey:
                hashBucket[i] = (dictKey, dictVal)
                return
        hashBucket.append((dictKey, dictVal))

    def getValue(self, dicKey):
        hashBucket = self.buckets[dicKey%self.numBuckets]
        for e in hashBucket:
            if e[0] == dicKey:
                return e[1]
            return None
        
    def __str__(self):
        result = '{'
        for b in self.buckets:
            for e in b:
                result = result + str(e[0]) + ':' + str(e[1]) + ', '
                return result[:-1] + '}'
            
import random
D = intDict(29)
for i in range(20):
    key = random.randint(0, 10**5)
    D.addEntry(key, i)

print('The value of the intDict is:')
print(D)
print('\n', 'The buckets are:')
for hashBucket in D.buckets:
    print(' ', hashBucket)

__str__ 메소드에서 보면 요소들이 추가된 순서에 관계없이 키가 해시하려는 값의 순서로 딕셔너리를 만들고 있다는 것을  알 수가 있다. 이것이 dict 자료형의 키의 순서를 왜 예측할 수 없는지를 설명해준다. 위의 코드는 먼저 20개의 엔트리로 intDict를 만든다. 엔트리의 값은 정수 0에서 19이다. 키는 0과 10^5 -1 사이의 정수 중 하나를 임의로 선택한다. 그 다음에는 클래스에 정의된 __str__ 메소드를 사용하여 intDict를 출력한다. 마직막으로 D.bucket을 반복하여서 각 해시 버킷을 출력한다.

 

출력 결과

The value of the intDict is:
{957:7,}

 The buckets are:
  [(957, 7)]
  [(96745, 4), (19373, 5), (1567, 19)]
  [(86799, 12)]
  []
  []
  [(79726, 1)]
  []
  [(43101, 10), (36112, 18)]
  [(74886, 16)]
  []
  []
  [(62042, 13)]
  []
  [(68018, 6)]
  []
  []
  []
  [(83508, 17)]
  [(192, 2)]
  []
  []
  [(10722, 3), (99839, 14)]
  []
  [(34620, 0)]
  [(18381, 9), (33490, 11)]
  []
  []
  [(22792, 15)]
  [(79952, 8)]

만약 추상화 장벽을 무시하고 intDict을 직접 살펴보면 많은 해시 버킷이 비어있는 것을 확인할 수 있다. 비어있지 않은 버킷은 충돌 횟수에 따라 하나에서 세 개의 튜플을 갖고 있다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 28. 14:35 파이썬
728x90
반응형

합병 정렬은 전형적인 분할정복 알고리즘으로 볼 수 있으며 1945년에 존 폰 노이만이 개발하였고 아직까지도 많이 사용되고 있다. 분할 정복 알고리즘처럼 재귀적으로 가장 쉽게 설명할 수 있다.

1. 리스트의 길이가 0이나 1일 때 리스트는 이미 정렬된 상태이다.

2. 리스트에 한 개 이상의 요소가 들어있으면 리스트를  두 개의 리스트로 나눈 후에 합병정렬을  사용하여 나뉘어진 리스트를 정렬한다.

3. 결과를 합병한다.

우선 각 리스트의 첫 번째 요소를 보고 둘 중 작은 요소를 결과 리스트의 끝으로 옮기는 것이다. 만약 둘 중 하나의 리스트가 비게 되면, 남아있는 리스트의 요소들을 모두 결과 리스트에 옮기면 된다.

 

다음 코드는 두 개의 배치 함수를 정의하고 있으며 이 두 함수를 이용하여 두 가지 방법으로 리스트를 정렬하고 있다. 각 함수는 표준 파이썬 모듈 string을 가져와서 그 모듈의 split 함수를 사용한다. split의 인자는 두개의 문자열들이고 두번 째 인자는 문자열을 부분열로 나눌 때 사용하는 구분자를 나타낸다. 

# 이름 리스트 정렬하기
def merge(left, right, compare):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if compare(left[i], right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    while (i < len(left)):
        result.append(left[i])
        i += 1
    while (j < len(right)):
        result.append(right[j])
        j += 1
    return result

import operator

def mergeSort(L, compare = operator.lt):
    if len(L) < 2:
        return L[:]
    else:
        middle = len(L)//2
        left = mergeSort(L[:middle], compare)
        right = mergeSort(L[middle:], compare)
        return merge(left, right, compare)
    
from string import *
def lastNameFirstName(name1, name2):
    name1 = name1.split(' ')
    name2 = name2.split(' ')
    if name1[1] != name2[1]:
        return name1[1] < name2[1]
    else : 
        return name1[0] < name2[0]
    
def firstNameLastName(name1, name2):
    name1 = name1.split(' ')
    name2 = name2.split(' ')
    if name1[0] != name2[0]:
        return name1[0] < name2[0]
    else:
        return name1[1] < name2[1]
    
L = ['Chris Terman', 'Tom Brady', 'Eric Grimson', 'Gisels Bundchen']
newL = mergeSort(L, lastNameFirstName)
print('Sorted by last name =', newL)
newL = mergeSort(L, firstNameLastName)
print('Sorted by first name =', newL)

L = [3, 5, 2]
D = {'a' : 12, 'c' : 5, 'b' : 'dog'}
print(sorted(L))
L.sort()
print(L)
print(sorted(D))

파이썬 함수 sorted은 리스트나 딕셔너리처럼 반복 가능한 객체를 첫 번째 인자로 받아서 정렬된 새로운 리스트를 반환한다.

 

출력 결과

Sorted by last name = ['Tom Brady', 'Gisels Bundchen', 'Eric Grimson', 'Chris Terman']
Sorted by first name = ['Chris Terman', 'Eric Grimson', 'Gisels Bundchen', 'Tom Brady']
[2, 3, 5]
[2, 3, 5]
['a', 'b', 'c']

sorted 함수를 딕셔너리에 실행하면 딕셔너리의 키 값으로 정렬한 리스트를 반환한다. list.sort 메소드와 sorted 함수 모두 두 개의 추가 매개변수를 사용할 수가 있다. key 매개변수는 합병정렬에서 compare와 같은 역할을 하는 것으로 비교 함수를 제공하기 위한 것이다. reverse 매개변수는 리스트가 오름차순인지 내림차순인지를 지정해준다. 다음 코드는 L의 요소들을 내림차순으로 정렬하여 출력한다.

L = [[1,2,3], (3,2,1,0), 'abc']
print(sorted(L, key = len, reverse=True))

출력 결과

[(3, 2, 1, 0), [1, 2, 3], 'abc']

list.sort 메소드와 sorted 함수는 안전 정렬 함수이다. 즉 비교할 때 두 개의 요소가 같다면 원래 리스트의 순서가 상대적으로 적용되어 최종 리스트에도 원래 순서로 유지가 된다.

728x90
반응형
posted by 조이키트 블로그
prev 1 2 3 4 5 next