반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

<Python-docx 관련 글>

 

2021.12.27 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 1편. 문서 생성, 저장, 불러오기, 글자 입력

2021.12.28 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 2편. 이미지 삽입, 표 삽입

 


 

지난 두 시간에 걸쳐서 python-docx 라이브러리로 워드 파일에 글자, 그림, 표를 삽입하는 방법을 배워봤습니다.

 

새로운 문서를 만들 때에도 필요하겠지만, 기존 문서의 내용에 무언가 추가하고 변경하기 위해서는 인덱싱(indexing)이 필요합니다.

 

엑셀에 행(row)과 열(column)의 개념이 있어, 원하는 셀(cell)의 내용을 인덱싱해서 가져올 수 있듯이 워드 파일도 이러한 개념을 잘 파악하고 있어야만이 마음대로 문서를 주무를 수 있답니다.

 

우선 오늘의 수업을 위해서 아래의 코드를 실행하셔서 '예제 문서.docx'를 만들어주세요.

 

from docx import Document

document = Document()

document.add_heading('코딩유치원 python-docx 강의', level = 0)

p = document.add_paragraph('안녕하세요, 코린이 여러분!')
p.add_run(' 코딩유치원에 오신 것을 환영합니다.').bold = True

document.add_paragraph('문장 추가 1')
document.add_paragraph('문장 추가 2')
document.add_paragraph('문장 추가 3')
document.add_paragraph('문장 추가 4')

records = (
    (1, '하나', 'one'),
    (2, '둘', 'two'),
    (3, '셋', 'three')
)

table = document.add_table(rows=1, cols=3)

# 만든 표의 스타일을 가장 기본 스타일인 'Table Grid'로 설정
table.style = document.styles['Table Grid']

hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'No'
hdr_cells[1].text = '한국어'
hdr_cells[2].text = '영어'
for qty, id, desc in records:
    row_cells = table.add_row().cells
    row_cells[0].text = str(qty)
    row_cells[1].text = id
    row_cells[2].text = desc

document.save('예제 문서.docx')

 

<실행 결과>

 

1. paragraph 인덱싱

 

먼저 문단(paragraph)을 인덱싱 하는 방법부터 시작해보겠습니다. 아래의 코드를 실행해보세요.

 

doc = Document('예제 문서.docx')

for i, paragraph in enumerate(doc.paragraphs):
    print(str(i+1) + ": " + paragraph.text)

 

그럼 아래와 같이 문단의 번호와 내용들이 출력됩니다.

 

여기서 잠깐

워드 문서에서 '레이아웃-줄 번호-페이지마다 다시 매기기'를 클릭하시면 문단 옆에 문단 번호가 표시된답니다.

문단 좌측에 인덱스가 추가된 모습

 

만약 특정 문단에 글을 추가하고 싶으시면 지난 시간에 배웠던 add_run( ) 함수를 이용해 주시면 됩니다.

양식에 내용을 추가할 때 사용하면 되겠죠?

# 추가하고 싶은 문단 (*실제 인덱스는 0부터 시작하므로 원하는 문단번호보다 +1 해주어야함에 주의)
p = doc.paragraphs[4]

p.add_run('문단에 굵은 글자 추가').

 

그리고 이런 경우가 자주 있을지는 모르겠지만 문단 중간에 새로운 문단을 추가하고 싶으면 아래의 코드를 이용하시면 됩니다.

# 3번째 문장 다음에 삽입 (*paragraphs[3]은 4번째 문장을 의미)
dco.paragraphs[3].insert_paragraph_before("문장을 삽입한다.")

 

 

2. table 인덱싱

 

위에서 문단을 인덱싱하고 내용을 가져왔을 때, 표(table)은 포함되지 않은 것을 보셨나요?

 

python-docx에서 표는 따로 분류되어 관리되며, 인덱싱 하는 방법도 조금 다릅니다.

 

 

1) 표의 특정 셀의 값 읽는 방법

 

엑셀과 매우 비슷하면서도 조금 다릅니다. 엑셀로 치면 sheet와 같은 것이 table입니다. 첫번째 시트, 두번째 시트가 있듯이 첫번째 표와 두번째 표를 table[인덱스]로 접근합니다.

 

rows[0]과 cells[0]은 행과 열로 셀 하나를 인덱싱하는 것이며, paragraphs[0]은 해당 셀의 내용(정확히는 문단)을 인덱싱 하는 것입니다. 만약 한 셀에 엔터를 치고 글자를 입력되어 있다면 paragraphs[1]로 인덱싱 해주어야겠죠?

 

# 문서 안의 모든 표를 가져옴
tables = doc.tables

# 가장 처음 표의 첫행, 첫열의 첫문단 내용 가져오기
tables[0].rows[0].cells[0].paragraphs[0].text

 

당연히 'No' 출력되겠죠? (No.라고 했어야했는데 잘 못한걸 이제 발견했네요)

 

 

2) 표의 모든 값에 접근하는 방법

 

표의 모든 값을 출력할 일이 있을지 모르겠지만 아래와 같이 가능합니다.

 

table = doc.tables[0]

for row in table.rows:
    for cell in row.cells:
        for para in cell.paragraphs:
            print(para.text)

 

이걸 응용해서 표의 모든 내용 중, '하나'를 찾아볼까요? 만약 그게 가능하면 글자를 추가해주거나 수정할 수도 있답니다.

 

# 첫번째 표 인덱싱
table = doc.tables[0]

for row in table.rows:
    for cell in row.cells:
        for para in cell.paragraphs:
            if(para.text == "하나"):
                para.add_run(' <-- 찾았다 하나')
                
# 확인을 위해서 저장하기
doc.save('예제 문서.docx')

 

실행해보니 하나를 잘 찾아서 글자도 잘 추가했네요.

 

이번 시간은 여기까지입니다.

 

오늘 공부한 내용을 가지고 얼른 회사에서 지루하게 반복해야 하는 문서업무를 자동화 해버리고 싶네요.


<참고 자료>

 

1. python-docx 공식 문서

https://python-docx.readthedocs.io/en/latest/index.html

 

2. 파이썬 DOCX 모듈의 사용방법_anakt님의 네이버 블로그

https://m.blog.naver.com/anakt/221842622079

 

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

<Python-docx 관련 글>

 

2021.12.27 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 1편. 문서 생성, 저장, 불러오기, 글자 입력

2021.12.28 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 2편. 이미지 삽입, 표 삽입

2021.12.30 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 3편. 기존 양식의 내용 읽는 법 (ft. 문단, 표 인덱싱)


오늘은 지난 시간에 이어서 python-docx 라이브러리로 워드 파일에 이미지와 표를 삽입하는 방법을 공부해보겠습니다.

 

이번 시간 역시 VScode에서 쥬피터 노트북 파일(.ipynb)을 생성하여 코드를 실행해보겠습니다.

 

우선 가장 기본이 되는 Document 클래스를 import 해주세요.

from docx import Document

 

1. 이미지 삽입

 

우선 이미지를 삽입하려면 삽입할 이미지가 있어야겠죠?

 

이미지 파일을 하나 준비해주세요.

 

뭘 준비해야 할지 모르겠다면 그냥 화면을 캡쳐해서 jpg 혹은 png 파일로 저장해주세요.

 

cat.jpg

 

저는 귀여운 고양이 사진을 워드 문서에 삽입해보겠습니다.

 

코드 설명은 아래에 주석으로 달아두었으며, 주석을 달지 않은 부분이 잘 이해가 안가신다면 지난 글을 참고해주세요.

 

<이미지 삽입 코드>

# Cm와 Inch 단위를 사용하기 위한 모듈
from docx.shared import Cm, Inches
 
doc = Document()

# 사진의 크기를 Cm 단위로 설정하여 삽입
doc.add_picture('cat.jpg',width= Cm(16), height= Cm(9))

# 사진의 크기를 Inch 단위로 설정하여 삽입
doc.add_picture('cat.jpg',width= Inches(4), height= Inches(3))

doc.save('이미지 삽입.docx')

 

<실행 결과>

 

워드 파일을 직접 열어주어야 함.

 

 

2. 표 삽입

 

1) 행과 열 설정 및 표 만들기

 

우리가 워드를 사용할 때 표를 삽입하려면 가장 먼저 행과 열의 갯수를 설정해주어야 하죠?

Word 사용 시, 일반적인 표 삽입 과정

 

python-docx를 사용할 때에도 마찬가지로 가장 먼저 행(rows)와 열(cols)의 갯수를 설정해줍니다.

 

이전 시간에 배우셨던 add_paragraph의 개념과 동일하게 변수에 대입해줌으로써 객체화가 가능합니다.

 

<표 삽입 코드>

# 새로운 문서 만들기
doc = Document()

# 2행 3열의 표 만들기
table = doc.add_table(rows = 2, cols = 3)

# 만든 표의 스타일을 가장 기본 스타일인 'Table Grid'로 설정
table.style = doc.styles['Table Grid']

# 저장
doc.save('표 삽입.docx')

 

<실행 결과>

 

 

참고로 위에서  표 스타일을 Table Grid로 해주었는데, 이 스타일은 가장 기본적인 스타일입니다.

추후에 문단과 표를 정렬하고 스타일을 변경하는 방법에 대해서 다루어 보겠습니다.

 

2) 각 셀에 내용 입력

 

각 셀에는 아래와 같은 인덱싱 방법으로 표에 접근하여, 텍스트를 입력할 수 있습니다.

 

<표에 텍스트 삽입 코드>

# 표의 첫 행을 리스트로 가져오기
first_row = table.rows[0].cells

# 첫 행의 각 열들에 접근해서 값 입력 
first_row[0].text = 'a'
first_row[1].text = 'b'
first_row[2].text = 'c'

# 표의 두번째 행을 리스트로 가져온 후, 각 셀에 값 입력
second_row = table.rows[1].cells
second_row[0].text = 'd'
second_row[1].text = 'e'
second_row[2].text = 'f'

# 저장
doc.save('표 삽입.docx')

 

<실행 결과>

 

3) 행과 열 추가하기

 

행 추가

row_cells = table.add_row().cells

 

위에서 굳이 변수에 대입해준 이유는 나중에 새로 만든 셀들에 값을 입력할 때, row_cells[0]과 같이 인덱싱하여 텍스트 입력이 가능하기 때문입니다.

 

 

열 추가

 

열을 추가할 때에는 행을 추가할 때와 다르게 반드시 width 값을 꼭 입력해주어야 합니다.

 

col_cells = table.add_column(width=Cm(2)).cells

 

오늘 준비한 내용은 여기까지입니다.

 

다음 시간에는 위에서 잠시 언급했던 paragraph에 스타일을 주거나, 정렬하는 방법, 그리고 표에 스타일을 주거나 간격을 조정하는 방법을 공부해보겠습니다.


<참고자료>

 

1. python-docx 공식 문서

https://python-docx.readthedocs.io/en/latest/index.html

 

 

 

 

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

<Python-docx 관련 글>

 

2021.12.27 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 1편. 문서 생성, 저장, 불러오기, 글자 입력

2021.12.28 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 2편. 이미지 삽입, 표 삽입

2021.12.30 - [파이썬 패키지/Word] - [Python-docx] 파이썬으로 MS워드 문서 다루기 3편. 기존 양식의 내용 읽는 법 (ft. 문단, 표 인덱싱)


 

오늘은 지난 시간에 배웠던 Pywin32 패키지의 win32com 모듈이 아닌, python-docx 라이브러리를 이용해서 word 파일을 다루어 보겠습니다.

 

 

1. 패키지 설치

 

아래의 코드를 터미널 창 혹은 주피터 노트북의 셀(cell)에 입력하고 실행시켜주세요. 참고로 해당 패키지는 Windows OS 뿐만 아니라 Mac OS에서도 잘 작동합니다.

pip install python-docx

 

2. 패키지 불러오기

 

python-docx 라이브러리에는 다양한 클래스들이 존재하며, 원하는 기능(스타일, 정렬, 표 등등)에 따라서 import 해주는 것이 조금씩 다릅니다.

 

아래는 몇가지 예로 든 것 외에도 많은 것들이 있으며, 오늘은 Document 클래스를 이용한 기능들만 알아보겠습니다.

# 가장 기본적인 기능(문서 열기, 저장, 글자 쓰기 등등)
from docx import Document

# 문단 정렬
from docx.enum.text import WD_ALIGN_PARAGRAPH

# 문자 스타일 변경
from docx.enum.style import WD_STYLE_TYPE

 

3. 새 워드문서 만들기

 

위에서 import를 했다면 문서 객체(Object)를 만들어 줄 차례입니다. 참고로 객체란 클래스(Class)를 변수로 선언해줌으로써 만들 수 있습니다.

 

doc = Document()

 

 

4. 워드문서 저장하기

 

현재는 그냥 새 워드문서가 파이썬 상에서만 존재하는 상태입니다. 이것을 우리가 사용하는 실제 워드 파일로 만들어주고 싶으면 아래의 코드로 객체를 저장해주어야합니다.

 

# 현재 작업경로에 저장
doc.save('저장하고 싶은 파일명.docx')

 

저장하실 때 특정 위치에 저장하고 싶으시면, 절대경로를 입력해주시면 됩니다.

 

저장된 docx 파일

 

5. 저장된 워드문서 불러오기

 

만약 기존의 워드파일을 불러오고 싶으시다면 아래와 같이 코딩해주시면 됩니다.

여기서 '저장하고 싶은 파일명'은 위에서 저장했던 파일명을 그대로 사용한 것입니다.

# 절대경로를 이용하는 방법
doc = Document(r'C:\Users\SANGWOO\Desktop\VSCODE\저장하고 싶은 파일명.docx')

# 현재작업 경로에 '파일명.docx'가 위치할 때
doc = Document('저장하고 싶은 파일명.docx')

불러온 파일 (실제 출력되지는 않음)

 

6. 워드문서에 글자 입력하기

 

워드의 가장 기본적인 기능인 글자를 입력하는 방법을 알아보겠습니다.

 

1) 제목 넣기

위와 같이 제목을 넣는 방법은 아래의 코드를 사용합니다. 코드와 이미지를 보면서 비교해보세요.

 

# 제목
doc.add_heading('가장 큰 제목 (아래에 밑줄)', level=0)
doc.add_heading('제목 크기, H1', level=1)
doc.add_heading('제목 크기, H2', level=2)
doc.add_heading('제목 크기, H3', level=3)
doc.add_heading('제목 크기, H4', level=4)
doc.add_heading('제목 크기, H5', level=5)
doc.add_heading('제목 크기, H6', level=6)

 

level이 어디까지 가능한지 확인은 해보지 않았으며, 레벨 3 밑으로는 글자 크기가 더 작아지지 않는 것으로 보입니다.

 

2) 문단(paragraph) 넣기

 

여기서 말하는 문단이란 그냥 한줄로 쭉 이어지는 글을 말합니다. 즉, 엔터를 치지 않은 상태의 글을 의미합니다.

참고로 제목도 하나의 문단이라고 할 수 있습니다.

 

doc.add_paragraph('여기에 원하는 텍스트를 마음껏 입력하면 됩니다.')

 

 

3) 문단에 문자 추가하기

 

문단에 글자를 쭉 이어서 쓸 수도 있지만 특정한 문자를 강조하고 싶거나 다른 스타일을 주고 싶을 때는 add_run( ) 함수를 사용합니다.

 

우선 위에서와 같이 add_paragraph( ) 함수를 사용하되 변수에 담아줍니다.

p = doc.add_paragraph('두번째 문단: 여기에 원하는 텍스트를 마음껏 입력하면 됩니다.')

 

변수 p에 .add_run( ) 함수로 글자를 추가해줍니다. 스타일 적용 방법은 아래의 코드를 참고하세요.

# 굵은 글씨(Bold) 적용
p.add_run('문단에 굵은 글자 추가').bold = True

# 기울임꼴(Italic) 적용
p.add_run('문단에 기울인 글자 추가').italic = True

# 밑줄(Underline) 적용
p.add_run('문단에 밑줄 글자 추가').underline = True

 

여기서 강조하고 싶은 것은 add_run( )은 반드시 paragraph 객체를 기반으로 사용할 수 있다는 점입니다.
 
오늘 준비한 내용은 여기까지입니다. 다음 시간에는 문서에 그림과 표를 넣는 방법을 자세히 다루어보겠습니다.
 

 

<참고 문서>

 

1. python-docx 공식 문서

https://python-docx.readthedocs.io/en/latest/index.html

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 


 

오늘은 지난 시간에 배웠던 Pywin32 패키지의 win32com 모듈을 이용해서 word 파일을 다루어 보겠습니다.

 

참고로 오늘의 내용을 함께 따라하시기 위해서는 Pywin32 패키지가 설치되어 있어야 합니다.

 

 

 

1. 새로운 워드 파일 열기 

# 관련 패키지 import
import win32com.client

# Word 어플리케이션 열기
word = win32com.client.gencache.EnsureDispatch("Word.application")

# 자동으로 실행되는 것을 확인하고 싶을 때 코드 추가
word.Visible = True

 # 새로운 워드 문서 열기
doc = word.Documents.Add()

 

만약 새로운 문서가 아닌 기존의 문서를 다루고 싶으시면, 아래의 코드를 실행해주세요.

 

# 절대 경로를 이용하여 기존 워드 파일 열기
doc = word.Documents.Open(r'C:\Users\SANGWOO\Desktop\VSCODE\test.docx')

 

 

2. 문자 입력

 

# 커서 앞에 문자 삽입
word.Selection.InsertBefore("안녕하세요 ")

# 커서 뒤에 문자 삽입
word.Selection.InsertAfter("코딩유치원입니다.")

 

 

3. 커서 이동

 

커서를 이동하는 방법은 아래와 같이 왼쪽, 혹은 오른쪽으로 가능하며 다양한 단위로 이동 가능합니다.

(아직 상하 이동은 파악하지 못하여서, 추후에 알게되면 업데이트 하겠습니다.)

 

# 왼쪽으로 커서 이동
Selection.MoveLeft(Unit=문자/단어/문장/표의 셀 하나,Count=숫자)

# 오른쪽으로 커서 이동
Selection.MoveRight(Unit=문자/단어/문장/표의 셀 하나,Count=숫자)

 

자세한 예시는 아래와 같습니다. 하나씩 따라하시면서 어떻게 움직이는지 관찰해보세요.

 

# 글자 단위로 이동
word.Selection.MoveLeft(Unit=win32.constants.wdCharacter, Count=3)

# 단어 하나씩 이동 (특수기호는 단어 하나로 취급함 ex. ?, !, 쉼표 등등)
word.Selection.MoveLeft(Unit=win32.constants.wdWord, Count=1)

# 문장 하나를 이동 (문장은 .으로 구분함)
word.Selection.MoveRight(Unit=win32.constants.wdSentence, Count=1)

# 표에서 한 칸 이동 (표가 없으면 에러)
word.Selection.MoveLeft(Unit=win32.constants.wdCell, Count=1)

 

 

4. 글자 스타일 변경

 

스타일을 변경하는 방법은 아직 완전히 파악하지 못하여서, 글자의 크기 변경하는 법만 일단 알려드릴게요.

 

# 한번에 모든 글자를 변경하고 싶을 때
doc.Content.Font.Size = 20

# 커서의 위치를 기준으로 몇 개의 글자만 변경하고 싶을 때

word.Selection.Start = 2 # 커서가 있는 행에서 2번째 글자의 다음 글자부터
word.Selection.End = 4 # 커서가 있는 행에서 4번째 글자까지
word.Selection.Font.Size = 20 # 선택된 부분의 폰트 크기를 20으로 조정

 

 

5. 페이지 가로/세로 설정

 

페이지를 세로로 사용할지, 가로로 사용할지를 설정해 줄 수도 있습니다.

 

# 페이지 방향 세로
doc.PageSetup.Orientation = 0

# 페이지 방향 가로
doc.PageSetup.Orientation = 1

 

 

6. 페이지 상하좌우 여백 설정

# 페이지 상하좌우 여백 설정 

doc.PageSetup.TopMargin = 100
doc.PageSetup.BottomMargin = 100
doc.PageSetup.LeftMargin = 100
doc.PageSetup.RightMargin = 100

 

7. 문서 저장

 

파일을 닫기 전에 문서를 저장해주어야 합니다. 저장해주지 않으면 아래에서 문서를 닫거나 어플리케이션을 닫는 단계에서 저장 경로를 설정하는 창이 뜨게 됩니다.

 

# 내PC - 문서에 저장
# doc.SaveAs("test.docx")

# 지정된 절대 경로에 test라는 이름으로 워드 문서 저장
doc.SaveAs(r"C:\Users\SANGWOO\Desktop\VSCODE\test.docx")

 

8. 워드 문서 닫기 / 어플리케이션 닫기

 

문서를 닫는 것과 어플리케이션(워드 프로그램)을 닫는 것의 차이를 코드를 하나씩 실행하면서 관찰해 보세요.

 

# 워드 파일 닫기
doc.Close()

# 워드 프로그램 종료
word.Quit()

워드 문서만 닫은 상태

 

 

엑셀을 다룰 때 써보았던 win32com 모듈을 이용해서 Word 문서를 다루어 보려고 공부해보았으나, 자료가 부족하여서 원하는 기능을 모두 사용하기는 힘들어 보입니다.

 

그래서 다음 시간에는 python-docx 패키지를 이용해서 MS워드 문서를 다루는 방법을 공부해보겠습니다.

 

https://python-docx.readthedocs.io/en/latest/

 

python-docx — python-docx 0.8.11 documentation

from docx import Document from docx.shared import Inches document = Document() document.add_heading('Document Title', 0) p = document.add_paragraph('A plain paragraph having some ') p.add_run('bold').bold = True p.add_run(' and some ') p.add_run('italic.')

python-docx.readthedocs.io

 


<참고 자료>

 

1. 파이썬 win32com을 이용한 Word 자동화_네이버 블로그

https://m.blog.naver.com/anakt/221874907407

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 


 

오늘은 파일과 폴더를 이동하거나 복사하고 싶을 때 사용하는 shutil 모듈에 대해서 공부해 보겠습니다.

 

1. 모듈 불러오기

 

우선 shutil 모듈은 따로 설치할 필요가 없이 바로 import 해주시면 됩니다. 지난 시간에 배웠던 os 모듈과 같이 파이썬 내장 라이브러리에 포함되어 있는 모듈이기 때문입니다.

 

import shutil

 

2. 파일을 특정 폴더로 이동하기_move( )

1) 상대경로 방식

# 방법 1 - 파일과 폴더가 현재 작업경로에 있는 경우만 가능
shutil.move('이동시킬 파일명.확장자', '파일을 이동시킬 폴더명')

# 예시
shutil.move('Test.xlsx', '테스트 폴더')

 

2) 절대경로 방식

# 방법 2 - 현재 작업경로와 상관없이 절대경로를 입력
shutil.move('이동시킬 파일 경로', '파일을 이동시킬 폴더의 경로')

# 예시
shutil.move('/Users/sangwoo/Desktop/PYTHON BASIC/Shutil Basic/Test.xlsx',
            '/Users/sangwoo/Desktop/PYTHON BASIC/Shutil Basic/테스트 폴더')

 

아래부터는 간결한 글을 위해서 상대 경로 방식으로만 코드를 작성하였으나, 위와 동일하게 절대경로 방식또한 가능한 점 참고해주세요.

 

 

3. 폴더 특정 폴더로 이동하기_move( )

 

파일과 마찬가지로 폴더도 이동시킬 수 있습니다. 이때 폴더 안의 모든 내용물이 함께 이동됩니다.

 

1) 폴더가 존재하는 경우

# 방법 1 - 파일과 폴더가 현재 작업경로에 있는 경우만 가능
shutil.move('이동시킬 폴더명', '이동할 폴더를 담을 폴더명')

# 예시
shutil.move('테스트 폴더', '테스트 폴더2')

 

2) 폴더가 존재하지 않는 경우

 

코드는 동일하지만 그 결과가 다릅니다. 만약 '테스트 폴더2'가 없는 경우, 기존의 '테스트 폴더'의 이름에 2가 추가되면서 안에는 'Test.xlsx' 파일이 위치하게 됩니다.

 

4. 파일을 특정 폴더로 복사하기_copy( )

# 방법 1 - 파일과 폴더가 현재 작업경로에 있는 경우만 가능
shutil.copy('복사할 파일명.확장자', '복사한 파일을 담을 폴더명')

# 예시
shutil.copy('Test.xlsx', '테스트 폴더')

 

 

5. 폴더를 특정 폴더로 복사하기_copytree( )

# 방법 1 - 파일과 폴더가 현재 작업경로에 있는 경우만 가능
shutil.copytree('복사할 폴더명', '복사될 새로운 폴더명')

# 예시
shutil.copytree('테스트 폴더', '테스트 폴더2')

 

폴더를 복사할  때 주의할 점은 '복사될 새로운 폴더명'과 동일한 폴더명이 존재하면 아래와 같은 에러 메시지를 띄운다는 것입니다.

 

FileExistsError: [Errno 17] File exists: '테스트 폴더2'

 

간단히 말해서, '테스트 폴더2'는 코드가 실행될 때 존재해서는 안됩니다.

 

만약 원하시는 기능이 기존 존재하는 폴더 안에 특정 폴더를 복사해야 하는 것이라면 아래와 같이 하셔야 합니다.

 

shutil.copytree('테스트 폴더', '테스트 폴더2/새로운 폴더명')

실행 결과


<참고 자료>

 

1. 파이썬을 이용한 파일 및 디렉터리 작업 - Code

https://code.tutsplus.com/ko/tutorials/file-and-directory-operations-using-python--cms-25817

 

2. shutil — 고수준 파일 연산 — Python 3.10.1 문서

https://docs.python.org/ko/3/library/shutil.html

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 


오늘은 아주 유명한 마이크로 컨트롤러 중의 하나인 아두이노를 파이썬으로 제어하는 법에 대해 알아보겠습니다.

 

저의 경우엔 컴퓨터의 GUI 프로그램으로 모터를 제어하기 위해서 파이썬과 아두이노를 결합하는 방법을 공부했습니다.

 

이 글을 보시는 대부분의 분들께서는 이미 아두이노를 아신다는 가정하에 글을 썼으니, 이 점 참고 부탁드립니다.

 

1. 개념도

 

파이썬이 어떻게 아두이노를 제어할 수 있는지 한 눈에 이해하기 쉽도록 개념도를 그려보았습니다.

 

 

기본적으로 아두이노는 UART 방식의 Serial 통신을 지원하며, 이 통신 방식으로 컴퓨터와 통신이 가능합니다.

 

여기서 말씀드리고 싶은 것은 아두이노를 파이썬이 직접 제어하는 것이 아니라, 아두이노는 컴퓨터와 통신을 하고, 파이썬은 pyserial 모듈을 이용해서 컴퓨터(정확히는 컴퓨터의 시리얼 통신 기능)를 제어 한다는 것입니다.

 

즉, 아두이노 IDE로 코딩을 해서 아두이노 보드에 시리얼 통신 기능이 포함된 코드를 컴파일 해주고, 별도로 파이썬으로 코딩을 해줘야 한다는 말입니다. 

 

 

 

2. pySerial 사용법

 

우선 pySerial을 설치해보겠습니다. 무난하게 pip 명령어를 이용해서 설치해주세요.

 

# 터미널 창에서 pip로 설치
pip install pyserial

# conda로도 설치 가능
conda install pyserial

 

설치가 완료되었으면 오늘은 간단하게 아두이노-파이썬 시리얼 통신의 개념에 대해 이해할 수 있는 예제를 함께 살펴보겠습니다.

 

 

<아두이노 코드>

 

먼저 아두이노 코드는 아래와 같이 작성하고, 아두이노에 '업로드' 해주시면 됩니다.

 

시리얼 통신을 통해 아두이노로 명령이 전달될 때마다, 명령어를 파악해서 명령어의 종류에 따라 시리얼 통신으로 특정 메시지를 전송하는 코드입니다.

 

char cmd;

void setup() {
  
  // 시리얼 통신 시작 (boadrate: 9600)
  Serial.begin(9600);
}

void loop() {

  // 컴퓨터로부터 시리얼 통신이 전송되면, 한줄씩 읽어와서 cmd 변수에 입력
  if(Serial.available()){
    cmd = Serial.read(); 

    if(cmd=='a'){
      Serial.println("아두이노: a");
      delay(100);
    }
    else if(cmd=='b'){
      Serial.println("아두이노: b");
      delay(100);
    }
  }
}

시리얼 모니터에서 아두이노 코드 작동 확인

 

 

<파이썬 코드>

 

파이썬 코드는 아래와 같이 작성해서 파이썬 파일(.py)로 실행시켜주시면 됩니다.

 

여기서 주의하실 점은 꼭 아두이노의 시리얼 모니터를 종료하고 실행시켜주셔야 한다는 것입니다.

 

이를 지키지 않을 시, 아래와 같은 에러를 출력합니다.

 

raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM3': PermissionError(13, '액세스가 거부되었습니다.', None, 5)

 

import serial
import time

py_serial = serial.Serial(
    
    # Window
    port='COM3',
    
    # 보드 레이트 (통신 속도)
    baudrate=9600,
)

while True:
      
    commend = input('아두이노에게 내릴 명령:')
    
    py_serial.write(commend.encode())
    
    time.sleep(0.1)
    
    if py_serial.readable():
        
        # 들어온 값이 있으면 값을 한 줄 읽음 (BYTE 단위로 받은 상태)
        # BYTE 단위로 받은 response 모습 : b'\xec\x97\x86\xec\x9d\x8c\r\n'
        response = py_serial.readline()
        
        # 디코딩 후, 출력 (가장 끝의 \n을 없애주기위해 슬라이싱 사용)
        print(response[:len(response)-1].decode())

 

코드를 나누어서 설명드리자면,

 

1) 먼저 아까 설치한 pyserial 모듈과 파이썬 내장 라이브러리에 있는 time 모듈을 불러와줍니다.

 

import serial
import time

 

2) serial 모듈의 Serial 함수를 이용해서 port와 baudrate를 설정해줍니다.

py_serial = serial.Serial(
    
    # Window
    port='COM3',
    
    # 보드 레이트 (통신 속도)
    baudrate=9600,
)

 

3) 아두이노에게 내릴 명령을 input 함수를 이용해서 입력해주고, 그 명령어를 시리얼 통신을 이용해서 보내주는 부분입니다.

 

아두이노와 같이 무한 루프(loop)를 돌기 위해서 while문을 사용한다는 점 꼭 기억해 주세요. 아니면 한 번 실행되고 그냥 프로그램이 종료됩니다.

 

while True:
      
    commend = input('아두이노에게 내릴 명령:')
    
    py_serial.write(commend.encode())
    
    time.sleep(0.1)

 

여기서 encode( )와 decode( )에 대해서 아셔야 하는데요.

 

encode란 우리가 사용하는 한글이나 영어를 시리얼 통신에 최적화된 상태로 변형시켜 주는 것을 말하며,

decode란 시리얼 통신에 최적화된 형태의 문자열을 다시 원래의 형태로 원상복구 시켜주는 것을 말합니다.

 

그 형태는 아래의 코드에서 주석으로 설명해 두었으니 주의깊게 봐주세요.

 

 

4) 아두이노에서 보낸 시리얼 통신(명령에 대한 반응 메시지)을 받는 부분입니다.

 

아두이노와 마찬가지로 메시지가 들어오면, 해당 메시지를 한 줄 읽고, 디코딩해줍니다.

 

    if py_serial.readable():
        
        # 들어온 값이 있으면 값을 한 줄 읽음 (BYTE 단위로 받은 상태)
        # BYTE 단위로 받은 response 모습 : b'\xec\x95\x84\xeb\x91\x90\xec\x9d\xb4\xeb\x85\xb8: a\r\n'
        response = py_serial.readline()
        
        # 디코딩 후, 출력 (가장 끝의 \n을 없애주기위해 슬라이싱 사용)
        print(response[:len(response)-1].decode())

 

위에서 설명드린 파이썬 코드를 실행하면 아래와 같이 터미널 창을 마치 아두이노 시리얼 모니터 처럼 사용할 수 있습니다.

 

 

오늘 준비한 내용은 여기까지입니다.

 

다음에 기회가 된다면 GUI 프로그램으로 아두이노 모터 제어를 해보는 프로젝트를 포스팅 해보겠습니다.

 

2022.09.28 - [파이썬 패키지/아두이노] - [Python/Serial] 파이썬과 아두이노로 스텝모터 제어하기

 

[Python/Serial] 파이썬과 아두이노로 스텝모터 제어하기

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다. 코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도

coding-kindergarten.tistory.com

 

감사합니다.

 

 


<참고 자료>

 

https://pyserial.readthedocs.io/en/latest/pyserial.html

 

pySerial — pySerial 3.4 documentation

 

pyserial.readthedocs.io

 

https://kamang-it.tistory.com/entry/Arduino-Python%EC%9C%BC%EB%A1%9C-UARTSerial%ED%86%B5%EC%8B%A0%ED%95%98%EA%B8%B0

 

Arduino Python으로 UART(Serial)통신하기

이 때까지 여러분은 UART통신을 사용해서 모니터에 값을 출력하고 값을 쓰는 행동을 하였다. 만약 이걸 프로그래밍으로 코딩하기 위해서는 어떻게 해야할까? 그걸 하기위해서는 여러가지 방법과

kamang-it.tistory.com

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

오늘은 제가 윈도우 환경에서 pyinstaller로 패키징한 exe파일의 용량을 줄이기 위해서 새로운 가상환경을 만들고, pywin32를 설치 및 사용하면서 겪었던 문제들을 정리해보려 합니다.

 

개인적으로 너무 고생을 해서 다른 분들은 이 글을 보시고 문제들을 쉽게 해결하시길 바랍니다.

 


1. powershell 권한 설정 문제

 

1) 문제 현상

 

VScode의 터미널창(windows의 경우 기본적으로 Powershell)을 켰을 때 발생하는 오류 메시지

 

+ CategoryInfo : 보안 오류: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess

 

2) 해결 방법

 

구글링을 하다보면 VScode의 기본 터미널을 Powershell을 cmd로 바꾸라고 하는 경우가 많은데, 참고로 cmd보다 업그레이드 된 터미널이 Powershell이라고 합니다. (실제로 cmd로 터미널을 켜면 해당 오류는 출력되지 않음)

 

실제 사용할 때는 큰 차이는 못느꼈지만 저는 그냥 아래의 방법을 이용해서 powershell을 기본 터미널로 이용하기로 하였습니다.

 

a) 우선 윈도우(windows10 기준)화면 좌측하단의 검색창을 클릭해서 "powershell"을 입력 후, 그림에 표시된 Windows PowerShell을 우클릭하여, 관리자권한으로 실행시켜줍니다.

 

 

b) 다음 명령어들을 차례대로 입력하고 엔터를 눌러줍니다. 해당 과정은 허용되지 않은 스크립트를 사용하겠다고 설정해주는 과정입니다. 

 

- Set-ExecutionPolicy Unrestricted

- Y

 

 

2. 가상환경 신규생성 후, win32com 설치 및 스크립트 실행 시 문제

 

1) 문제 현상

 

ImportError: DLL load failed while importing win32api: 지정된 프로시저를 찾을 수 없습니다.

 

 

2) 해결 방법

2021년 12월 16일 기준, pywin32를 설치하면 302 버전이 설치됩니다. 하지만 최신 버전의 안정성 문제 때문인지 위와 같은 에러를 출력하면서 파이썬 스크립트가 정상적으로 실행되지 않습니다.

 

따라서 해결방법은 버전을 다운그레이드 해주는 것입니다.

 

pip install --upgrade pywin32==225

225 버전으로 다운그레이드 완료

 

 

3. pyinstaller 패키징 후, win32com(win32api) 못찾는 현상

 

1) 문제 현상

 

가장 저를 괴롭혔던 문제이며, 구글링을 해보아도 원인을 알 수 없었던 문제였습니다.

 

멀쩡히 잘 돌아가던 파이썬 스크립트가 pyinstaller로 exe파일을 만들어서 실행시키니깐, 위에서 발생했던 2번 문제가 또 발생했습니다.

 

exe파일 실행 시, 출력되는 에러 팝업창

 

새로 생성한 가상환경을 '환경 변수'에 추가해주지 않아서 그런가해서 path에 추가해주고 컴퓨터를 재부팅 해보아도 문제는 해결되지 않았습니다.

 

2) 해결 방법

 

정말 운이 좋게도 겨우겨우 해결한 방법은 VScode의 터미널창이 아닌, Windows Powershell를 직접 열어서 pyinstaller 패키징하는 것이었습니다. Windows Powershell을 여는 방법은 아까 1번 문제에서 배우셨으니 따로 설명드리지 않을게요.

 

# " "사이에 패키징할 파이썬 파일의 절대경로를 입력
pyinstaller -w -F "C:\Python_Coding\EXCEL_PYTHON\Excel_sum.py"

 

VScode에서 실행하는 터미널에서 pyinstaller 패키징 시, 알수 없는 이유로 win32api를 import하지 않고 패키징 하는 것으로 보입니다.

파일 용량 비교: 오작동 vs 정상 작동

 


<참고 자료>

 

1. 1번 문제 해결

https://samsons.tistory.com/16

 

[PowerShell] 스크립트 실행 시 오류(UnauthorizedAccess), (PSSecurityException)

+ CategoryInfo : 보안 오류: (:) [], PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess ----------------------------------------------------------- ※관리자권한으로 PowerShell 실행해야..

samsons.tistory.com

 

2. 2번 문제 해결

https://stackoverflow.com/questions/58612306/how-to-fix-importerror-dll-load-failed-while-importing-win32api

 

How to fix "ImportError: DLL load failed" while importing win32api

I'm setting up an autoclicker in Python 3.8 and I need win32api for GetAsyncKeyState but it always gives me this error: >>> import win32api Traceback (most recent call last): File "...

stackoverflow.com

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 


오늘은 지난 시간의 엑셀 시트 취합 프로젝트의 업그레이드 버전을 가져와봤습니다.

 

이번 프로그램의 컨셉은 아래와 같습니다. 참고로 해당 프로젝트는 제품 모델당 자동으로 생성되는 Report들을 한번에 취합해서 프린팅 하기 위한 프로그램입니다.

 

수 십, 수 백개의 엑셀 파일을 하나씩 열어가며 인쇄 버튼을 누르는 것보다 훨씬 시간을 절약할 수 있겠죠?

 

1. 전체 코드

 

코드에 대한 설명은 주석으로 대체하도록 하겠습니다. 최대한 자세히 달아두었으나 이해가지 않으시는 부분은 댓글로 질문해주세요!

 

# step1.관련 모듈 및 패키지 import
import glob
import win32com.client
import tkinter
from tkinter import filedialog
import os

# step2.폴더 선택 (Tkinter)
root = tkinter.Tk()
root.withdraw()
path = filedialog.askdirectory(parent=root, initialdir="./", title="폴더를 선택 해 주세요")

# step3.glob 모듈로 원하는 폴더 내의 모든 xlsx 파일의 경로를 리스트로 반환
list_filepath = glob.glob(path + '/**/*.xlsx', recursive=True)

# step4.역슬레시로 출력되는 부분 슬레시로 변환
list_filepath_slash = [i.replace("\\", "/", 5) for i in list_filepath]

# step5.복사한 시트의 이름을 각 Report가 존재하는 폴더 이름으로 변경해주기 위한 폴더명 리스트
list_folder_name = os.listdir(path)

# step6.win32com(pywin32)를 이용해서 엑셀 어플리케이션 열기
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True #실제 작동하는 것을 보고 싶을 때 사용

# step7.엑셀 어플리케이션에 새로운 Workbook 추가
wb_new = excel.Workbooks.Add()

# step8.엑셀 시트를 추출하고 새로운 엑셀에 붙여넣는 반복문
for i, filepath in enumerate(list_filepath_slash):

    # 받아온 엑셀 파일의 경로를 이용해 엑셀 파일 열기
    wb = excel.Workbooks.Open(filepath)

    # 새로 만든 엑셀 파일에 추가
    # 추출할wb.Worksheets("추출할 시트명").Copy(Before=붙여넣을 wb.Worksheets("기준 시트명")
    wb.Worksheets("1번 문서").Copy(Before=wb_new.Worksheets("Sheet1"))
    
    # 시트명을 원래 Report 파일이 존재하던 폴더명으로 변경 
    ws = wb_new.Worksheets('1번 문서')
    ws.Name = list_folder_name[i]
    
    # copy 작업이 끝난 Workbook 종료
    wb.Close()

# 처음 새로운 엑셀파일이 생성될 때 존재하는 "Sheet1" 시트 삭제
wb_new.Worksheets("Sheet1").Delete()

# step6. 취합한 엑셀 파일을 "통합 문서"라는 이름으로 저장
wb_new.SaveAs(r"C:\Users\SANGWOO\Desktop\VSCODE\통합 문서.xlsx")

# step7. 켜져있는 엑셀 및 어플리케이션 모두 종료
excel.Quit()

 

2. 새롭게 알게 된 점

 

1)  윈도우의 기준, 파일 혹은 폴더 경로에 /(슬레시)와, \(역슬레시)가 섞여서 들어가면 에러가 난다

 

아래의 코드와 같이 Tkinter로 폴더 경로를 선택한 후, glob 모듈로 하위 폴더 내의 모든 xlsx파일의 경로를 리스트로 받아서 출력해보니 다음과 같이 출력되었습니다. 

 

해당 문제는 전체 코드에서는 개선하여 반영하였습니다.

 

import glob
import tkinter
from tkinter import filedialog

root = tkinter.Tk()
root.withdraw()
path = filedialog.askdirectory(parent=root, initialdir="./", title="폴더를 선택 해 주세요")
print("path : ", path)

list_filepath = glob.glob(path + '/**/*.xlsx', recursive=True)

for i in list_filepath:
    print(i)

 

<출력 결과>

path :  C:/Users/SANGWOO/Desktop/VSCODE/엑셀 시트 취합
C:/Users/SANGWOO/Desktop/VSCODE/엑셀 시트 취합\1번 제품\Report.xlsx
C:/Users/SANGWOO/Desktop/VSCODE/엑셀 시트 취합\2번 제품\Report.xlsx
C:/Users/SANGWOO/Desktop/VSCODE/엑셀 시트 취합\3번 제품\Report.xlsx
C:/Users/SANGWOO/Desktop/VSCODE/엑셀 시트 취합\4번 제품\Report.xlsx
C:/Users/SANGWOO/Desktop/VSCODE/엑셀 시트 취합\5번 제품\Report.xlsx

 

 

2) win32com으로 엑셀을 다룰 때, 같은 이름의 엑셀 파일이 열리면 아래와 같은 오류가 발생한다

 

아래와 같은 에러를 띄우면서 시트를 복사하는 부분에서 걸리는 문제가 발생해서 원인을 찾다보니, Report라는 엑셀 파일을 열고 닫지 않고 그다음 폴더의 Report 파일을 열어서 문제가 발생하는 것을 파악하였습니다.

 

이를 해결하기 위해서는 wb.Close( ) 명령을 사용해야합니다.

 

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-42-3f47d6541631> in <module>
     39     # 새로 만든 엑셀 파일에 추가
     40     # 추출할wb.Worksheets("추출할 시트명").Copy(Before=붙여넣을 wb.Worksheets("기준 시트명")
---> 41     wb.Worksheets("1번 문서").Copy(Before=wb_new.Worksheets("Sheet1"))
     42 
     43 # 처음 새로운 엑셀파일이 생성될 때 존재하는 "Sheet1" 시트 삭제

AttributeError: 'NoneType' object has no attribute 'Worksheets'

 

직접 동일명 엑셀 파일을 열었을 때 출력되는 메시지

 

 

3) win32com으로 엑셀 시트 이름을 바꾸는 방법

 

ws = wb.Worksheets('변경 전 시트 이름')

ws.Name = '변경 후 시트명'

 

 


 

<참고 자료>

 

https://url.kr/jqxl4b

 

파이썬 Replace, 폴더 디렉토리 경로 "\"→"/" 자동 변경 방법 (Python)

파이썬을 활용해서 머신러닝, 이미지 프로세스 관련 개발을 하면서 폴더 혹은 디렉토리 경로를 입력하는 일이 많습니다. 하지만, 컴퓨터에서 사용되는 경로에는 역슬래쉬인 "\"가 사용되며, 파

muzukphysics.tistory.com

 

https://stackoverflow.com/questions/31330941/python-win32-excel-copy-worksheet-and-change-name-of-copied-worksheet

 

python win32 excel copy worksheet and change name of copied worksheet

I'm trying to use python win32 excel application in order to: 1) copy a worksheet 2) change the name of the copied worksheet Using the following code: from win32com.client import Dispatch xl =

stackoverflow.com

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

Win32com 모듈을 사용하려면 pywin32라는 패키지를 설치하셔야 합니다.

 

설치 방법은 지난 글을 참고해주세요.

 

2021.12.12 - [파이썬 패키지/엑셀] - [파이썬 엑셀/PyWin32 ] 개별 엑셀 파일의 특정 시트들을 새로운 엑셀 파일에 모두 합치기 (ft. Openpyxl로는 못함)


오늘은 하나의 엑셀 파일에 있는 엑셀 시트를 각각 분리해서 엑셀 파일로 저장해보는 프로젝트를 해보겠습니다.

 

대략적인 컨셉은 다음과 같습니다. 

 


 

1. 전체 코드

 

코드에 대한 설명은 주석으로 대체하도록 하겠습니다. 최대한 자세히 달아두었으나 이해가지 않으시는 부분은 댓글로 질문해주세요!

 

# step1.관련 모듈 및 패키지 import
import win32com.client

# step2.win32com(pywin32)를 이용해서 엑셀 어플리케이션 열기
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True #실제 작동하는 것을 보고 싶을 때 사용

# step3. 분리할 엑셀 파일이 있는 폴더 경로
path = r"C:\Users\SANGWOO\Desktop\VSCODE\엑셀 시트 분리"+"/"

# step4.분리하고자 하는 엑셀 통합문서 가져오기
wb = excel.Workbooks.Open(path + "통합 문서.xlsx")

# step5.통합문서의 엑셀 시트들의 이름을 리스트로 받기
Sheet_list = [sheet.Name for sheet in wb.Sheets]

# step6. 엑셀 시트 분리 및 저장 반복문
for sheet in Sheet_list:
    
    # 시트를 분리 저장할 새로운 엑셀 파일 open
    wb_new = excel.Workbooks.Add()

    # 통합문서의 시트 하나를 새로운 엑셀 문서에 copy
    wb.Worksheets(sheet).Copy(Before=wb_new.Worksheets("Sheet1"))
    
    # 처음 새로운 엑셀파일이 생성될 때 존재하는 "Sheet1" 시트 삭제
    wb_new.Worksheets("Sheet1").Delete()
    
    # 기존 경로에 시트명을 파일명으로 엑셀 파일 저장
    wb_new.SaveAs(path + sheet + ".xlsx")

# step7. 켜져있는 엑셀 및 어플리케이션 모두 종료
excel.Quit()

 

 

2. 새롭게 알게 된 점

 

1) win32com 모듈로 엑셀 시트 이름 얻는 법 & 리스트로 저장

 

# step5.통합문서의 엑셀 시트들의 이름을 리스트로 받기
Sheet_list = [sheet.Name for sheet in wb.Sheets]

 

<참고 링크>

 

2) win32com 모듈로 엑셀 시트 삭제하는 법

 

    # 삭제할 시트가 있는 wb.Worksheets("삭제할 시트명").Delete()
    
    wb.Worksheets("Sheet1").Delete()

 

 


오늘 준비한 내용은 여기까지입니다.

 

이 글이 도움이 되셨다면, 좋아요나 댓글을 남겨주세요. 블로그를 운영하는데에 큰 힘이 됩니다.

 

감사합니다.

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 


오늘은 제목과 같이 개별 엑셀 파일의 특정 시트들을 새로운 엑셀 파일에 모두 합치는 파이썬 프로그램을 만들어 보겠습니다.

 

대략적인 컨셉은 다음과 같습니다. 보시다시피 이번 시간에는 openpyxl 대신에 Windows OS에서 Office 프로그램을 제어해 줄 수 있는 Pywin32 패키지를 사용하였습니다.

 

 

자세한 개념에 대한 설명은 아래의 링크를 참고해주시고, 저는 코드 설명만 드리도록 하겠습니다.

 

https://wikidocs.net/153820

 

2) win32com 통해 엑셀 다루기 - 1편

win32com에 속한 client라는 모듈을 활용하여 엑셀을 제어할 수 있습니다. 이번 편에서는 win32com.client를 이용해서 엑셀을 제어하는 기본적인 방법에 ...

wikidocs.net

 


 

1. 전체 코드

 

코드에 대한 설명은 주석으로 대체하도록 하겠습니다. 최대한 자세히 달아두었으나 이해가지 않으시는 부분은 댓글로 질문해주세요!

 

# step1.관련 모듈 및 패키지 import
import glob
import win32com.client

# step2.win32com(pywin32)를 이용해서 엑셀 어플리케이션 열기
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = True #실제 작동하는 것을 보고 싶을 때 사용

# step3.엑셀 어플리케이션에 새로운 Workbook 추가
wb_new = excel.Workbooks.Add() 

# step4.glob 모듈로 원하는 폴더 내의 모든 xlsx 파일의 경로를 리스트로 반환
list_filepath = glob.glob(r'C:\Users\SANGWOO\Desktop\VSCODE\엑셀 샘플\*.xlsx', recursive=True)

# step5.엑셀 시트를 추출하고 새로운 엑셀에 붙여넣는 반복문
for filepath in list_filepath:

    # 받아온 엑셀 파일의 경로를 이용해 엑셀 파일 열기
    wb = excel.Workbooks.Open(filepath)
    
    # 새로 만든 엑셀 파일에 추가
    # 추출할wb.Worksheets("추출할 시트명").Copy(Before=붙여넣을 wb.Worksheets("기준 시트명")
    wb.Worksheets("코딩유치원").Copy(Before=wb_new.Worksheets("Sheet1"))

# step6. 취합한 엑셀 파일을 "통합 문서"라는 이름으로 저장
wb_new.SaveAs(r"C:\Users\SANGWOO\Desktop\VSCODE\엑셀 샘플\통합 문서.xlsx")

# step7. 켜져있는 엑셀 및 어플리케이션 모두 종료
excel.Quit()

 

 

2. 새롭게 알게 된 점

 

1) openpyxl은 Workbook끼리 Sheet이동이 되지 않는다.

 

for filepath in list_filepath:
    
    wb = op.load_workbook(filepath)
    
    ws = wb["코딩유치원"]
    
    wb_new.copy_worksheet(ws)
    
    wb_new.save("통합 문서.xlsx")

 

위의 코드로 시트 이동을 시도해보았으나 아래와 같은 에러를 출력했습니다.

 

ValueError: Cannot copy between worksheets from different workbooks

 

 

2) Pywin32 패키지는 Windows OS 전용이다. (Mac OS에 MS 프로그램이 있어도 안됨)

 

아래의 사진은 Mac OS에서 pywin32를 설치하려 했을 때 출력되는 에러입니다.

제가 잘 못해서 그럴 가능성도 있지만, 애초에 pywin32가 윈도우 전용 패키지가 아닐까 생각됩니다.

 

 

3) Pywin32 패키지 설치방법

 

Windows에서 주피터 노트북을 이용해서 pywin32를 설치하니 커널이 먹통이 되는 문제가 발생했습니다.

 

해결책은 Anaconda 인터프리터를 사용할 때에는 pip가 아닌 conda로 install 해주어야 하는 것이었습니다.

 

conda install -c anaconda pywin32

 

<참고한 블로그>

https://gentlesark.tistory.com/112

 

 


오늘 준비한 내용은 여기까지입니다.

 

이 글이 도움이 되셨다면, 좋아요나 댓글을 남겨주세요. 블로그를 운영하는데에 큰 힘이 됩니다.

 

감사합니다.

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 


오늘은 예전에도 겪었던 openpyxl 문제가 다시 발생하여 기록 및 공유 겸 짧게 글을 써보려 합니다.

 

파이썬으로 엑셀을 다루게 해주는 openpyxl 패키지는,

 

시트(sheet)에 존재하는 값이 입력된 가장 마지막 열을 파악해야 할 때, ws.max_row를,

마지막 열이 정확히 어디인지 모르지만 전체 열을 범위로 넣고 싶을 때ws.rows를 사용합니다.

 

그런데 이때 가끔씩 빈 공간을 마치 값이 입력된 것처럼 인식할 때가 있습니다. 없는데 있는 그런 모순된 상황입니다.

 

결론부터 말씀드리면 무엇인가 썼다가 지웠거나, 셀 서식이 들어가 있으면 해당 셀 공간이 빈공간이 아닌 것 처럼 인식합니다.

 

해결 방법은 아래에서 설명드리겠습니다.

 

1. 문제 현상

 

자, 아래에서 예시를 통해서 좀 더 자세히 보여드리겠습니다.

 

아래의 그림을 보시면, 6번행까지 값이 입력되어 있습니다. 단, 7,8,9번행까지 제가 다른 것을 썼다가 지운 상태입니다.

 

테스트용 출석부.xlsx

 

간단한 코드로 ws.rows가 어떻게 사용되고 작동하는지 살펴보겠습니다. 의도한 출력결과는 값이 입력된 마지막 행을 파악하고 그 전의 행들을 모두 출력하는 것입니다. 참고로 여기서 출력하는 것은 값이 아니라 Cell 객체입니다.

 

import  openpyxl

# "출석부.xlsx"라는 이름의 엑셀파일 불러오기
wb = openpyxl.load_workbook("출석부.xlsx")

# 불러운 엑셀파일에서 "1반"이라는 이름을 가진 sheet 가져오기
ws = wb["1반"]

# ws.rows로 가장 마지막 행을 파악, 행을 한줄씩 출력
for  row  in  ws.rows:
    print(row)

 

<정상적인 실행 결과>

 

<잘못된 실행 결과>

 

분명히 아무것도 존재하지 않는데 9번 행을 시트의 마지막 행으로 잡았습니다.

 

 

2. 해결 방법

 

해결 방법은 간단합니다.

 

주변의 진짜 순수한(?) 떼뭍지 않은(?) 셀을 잘라내기해서 문제가 되는 영역에 붙여넣는 것입니다.

 

 


누군가에게 도움이 되었길 기대하며 글을 마칩니다.

 

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

 

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

 

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

<Pyinstaller 관련 지난 글>

 

2021.06.08 - [파이썬 패키지/실행파일 배포] - [Python / PyInstaller] 파이썬 프로그램 실행 파일로 만들어서 배포하는 방법 (ft. exe 파일 용량 줄이는 팁)

 

오늘은 지난 시간에 알아보았던 파이썬 용량 줄이는 방법을 제가 직접 수행하면서 새롭게 알게 된 내용을 공유드리겠습니다.

 

1. exe 파일의 과용량 원인

 

예전에 제가 만든 간단한 크롤링 GUI 프로그램의 용량이 200~300MB로 되는 문제가 있어서 여기저기 많이 찾아보니, 

그 원인은 잘 이해는 가지 않지만 'conda와 pyinstaller가 잘 맞지 않아서' 였습니다.

 

저의 경우엔 아나콘다 패키지로 파이썬을 설치했었고, 아나콘다 패키지의 파이썬 인터프리터와 conda 기반의 패키지 관리 환경에 설치된 numpy와 pandas 같은 패키지들이 큰 용량으로 포함되었습니다. numpy와 pandas를 사용하지 않은 코드였는데도요!!

 

2. 임시 해결방안

 

그 당시 저는 가상환경 셋팅법이 너무 어려워서 아래와 같은 방법을 사용했었습니다.

 

Anaconda의 가상환경(제가 주로 사용하는 'base': conda)를 그대로 사용하면서 '--exclude 패키지명' 옵션으로 특정 패키지 제외

 

# 가장 큰 패키지인 pandas와 numpy 제외
pyinstaller -F -w --exclude pandas, --exclude numpy 파이썬 파일명.py

 

 

실제로 이 방법으로 330MB였던 프로그램을 45MB로 용량으로 줄였습니다.

 

하지만 pandas와 numpy를 사용했었다면 이 방법을 사용하지 못 했을거예요. 그래서 이 방법은 반쪽짜리 임시 해결책이라고 볼 수 있습니다.

 

3. 제대로 된 해결방안

 

위의 문제를 제대로 해결하기 위한 방법은 새로운 가상환경을 만들어서, 그 환경에서 pip install로 필요한 패키지를 설치한 다음, pyinstaller를 실행하는 것입니다.

 

가상환경을 만드는 방법은 아래에 정리해 두었으니 참고해주세요.

 

2021.12.07 - [파이썬 기초/개발환경 구축(VScode)] - [Python/VScode] 파이썬 가상환경 만들고 사용하는 법 상세정리

 

2021년 12월 10일 기준으로 예전과 조금 달라진 점이 있어서 공유드립니다.

 

2021년 5월 22일에 exe 파일을 만들었을 땐 190MB였던 파이썬 파일이 현재으로 다시 exe 파일로 만들어보니 87.3MB로 출력됩니다.

 

Anaconda (base) 가상환경

 

짧은 지식으로 추측해보건데, 현재 pyinstaller 버전(4.7)에서 그 동안 발생했던 용량 문제를 조금이나마 해결한 듯 합니다.

 

어쩌면 아래의 코드가 가장 가성비 좋은 해결방법일 수도 있겠다는 생각이 듭니다.

pip install --upgrade pyinstaller

 

위에서 조금이나마 해결했다고 하는 이유는 아래의 신규 생성한 가상환경에서 만든 exe 용량 때문입니다. 잘 보시면 약 70% 수준으로 감소한 것을 확인할 수 있습니다. 조금이라도 더 용량을 줄이고 싶으시다면 가상환경을 새로 만드시는 방법을 추천드립니다.

신규로 셋팅한 가상환경

 


오늘 준비한 내용은 여기까지입니다.

 

다음 시간에는 pyinstaller로 exe 파일 패키징 시, pyqt 혹은 selenium를 사용한 파이썬 파일이 ui 파일과 chromedriver의 경로를 못 찾는 문제와 이러한 리소스 파일을 함께 포함하여 패키징 하는 방법에 대해서 다루어 보겠습니다.

 

감사합니다.

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

오늘은 제가 번번히 도전하다가 실패했던, 코딩 초보에겐 너무나도 어려운 파이썬 가상환경을 셋팅하는 방법에 대해서 자세히 알아보겠습니다.

 

이 글이 많은 코린이 여러분에게 도움이 되길 바라면서 오늘 포스팅 시작하겠습니다.

 

참고로 제목에서도  보셨 듯이 개발환경은 VScode를 사용한 점 참고 바랍니다.


 

1. 인터프리터 선택의 의미 (Select Interpreter) 

 

우리는 처음에 파이썬을 설치하고 실행을 하면 인터프리터를 설정해줍니다.

 

쉽게 말해서 어떤 경로의 파이썬을 실행시켜줄지 선택하는 것입니다.

 

Anaconda 패키지로 파이썬을 설치하셨다면 아마 ~/opt/anaconda3/bin/python이라는 인터프리터를 기본적으로 사용하실거예요.

 

Anaconda와 순정 python의 environment

 

VScode에서 단축키 'Ctrl(or CMD) + Shift + P'를 입력하거나 좌측 하단의 빨간 상자 부분을 클릭하면 선택할 수 있답니다.

 

이 인터프리터를 선택한다는 것은 pip 혹은 conda 명령어로 설치한 모듈과 라이브러리들(bin과 lib에 위치)을 사용할 수 있다는 것을 의미합니다.

 

예를 들어, 아래에서 배울 가상환경을 새로 만들고 거기에 있는 python 인터프리터를 선택하면 원래 문제없던 import 부분의 코드들에 빨간줄이 쳐지는 것을 보실 수 있을거예요.

 

anaconda3 폴더 안의 폴더들

 

 

2. 가상환경 만들기

 

우리는 간단한 코드 한 줄로 위에서 본 anconda3 폴더 같은 가상환경을 생성해 줄 수 있습니다.

 

참고로, 잘쓰던 기본 개발환경을 놔두고 가상환경을 만드는 이유는 진행하는 프로젝트마다 패키지들의 버전에 따라 발생할 수 있는 호환성 문제를 방지해주기 위함입니다.

 

또한 anaconda 개발 환경과 pyinstaller 궁합이 맞지 않아서 용량이 엄청 커지는 문제를 피하기 위해서도 사용할 수 있답니다.

 

자 그럼 서론은 이쯤하고, 본론으로 들어가볼까요?

 

 

1) VScode로 프로젝트 폴더열기 & 터미널 창 열기

 

가상환경을 만드는 것은 아무 폴더에나 가능하지만 저는 VENV_BASIC이라고 폴더를 하나 만들고 VScode로 폴더를 열었습니다.

 

그리고는 화면 상단의 메뉴에서 터미널 - 새 터미널을 클릭해줍니다.

 

 

2) 터미널 창에 코드 입력

 

# 작업공간에 새로운 가상환경 만듦
python -m venv newvenv

 

터미널 창이 열렸으면 위의 코드를 아래와 같이 터미널 창에 입력해주세요. 참고로 newvenv는 제가 마음대로 지은 이름이므로 여러분들도 마음에 드시는 이름으로 지어주시면 됩니다.

 

 

가상환경을 설치하시면 newvenv라는 폴더가 생기고 하위 폴더로 bin, include, lib/python3.8/site-packages 폴더 3개가 생기는 것을 확인 하실 수 있습니다. (참고로 windows 환경에서는 bin 대신 Scripts로 폴더가 만들어집니다)

 

 

3) 가상환경의 인터프리터 선택

 

만들어진 가상환경을 사용하려면 처음에 설명드렸 듯이 인터프리터를 다시 선택해주어야 합니다.

 

 

새로 만든 가상환경을 선택했음에도 터미널 창을 보면 처음 그대로의 인터프리터를 사용하고 있습니다.

(여기서 pip install로 라이브러리들을 설치해봤자 이미 설치돼 있다는 말만 나옵니다.)

 

 

당황하지 마시고 오른쪽의 + 버튼을 눌러서 새로운 터미널 창을 열어주세요.

 

아래를 보시면 (newvenv)라고 표시되어 정상적으로 가상환경에 접속했음을 알 수 있습니다.

 

 

4) 새로운 가상환경에 라이브러리 설치하기

 

신나게 pip install 명령어를 이용해 필요한 라이브러리를 설치해주었습니다.

 

그런데 뭔가 설치는 됐다고 하는데 노란색 글씨로 경고를 해줍니다. 

 

 

자세히 읽어보면 pip 버전이 최신이 아니라서 업그레이드를 해주라고 합니다. 친절하게 어떻게 업그레이드 하는지도 알려주네요.

 

# pip install --upgrade pip만 입력해도 되는 것으로 확인

python -m pip install --upgrade pip

 

 

성공적으로 업그레이드 되었다고 합니다. 이젠 다른 라이브러리를 설치할 때에 경고를 띄우지 않습니다.

 

 


오늘 준비한 내용은 여기까지입니다.

 

다음 시간에는 예전에 애를 먹었던 pyinstaller 용량줄이기를 가상환경을 통해서 해결하는 것에 대해 다루어 보겠습니다.

 

오늘도 공부하시느라 고생 많으셨습니다!

 

이 글이 도움이 되셨다면, 아래의 광고를 한 번씩만 눌러주시면 너무너무 감사하겠습니다!

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 


 

오늘은 Pyqt5를 다루면서 항상 의문이었던 부분을 정리해보려 합니다.

 

바로 파이썬 Pyqt5 패키지로 GUI 창을 만들 때 사용되는 QWidget, QDialog, QMainWindow 클래스 3형제들입니다.

 

class MyWindow(QWidget):

    def __init__(self):
        super().__init__()

 

구글링하면 Pyqt5 관련 패키지의 코드들을 보면 QWidget이 들어간 자리에 이 3형제들이 골고루 들어가 있어서 혼란스러웠기에 저같은 분들이 있으실 듯 하여 정리해보는 시간을 갖기로 하였습니다.

 

참고로 제가 즐겨 사용하는 qt designer을 켜면 아래와 같이 3가지 클래스(Dialog, Main Window, Widget)를 선택하는 창이 가장 처음 출력됩니다.

 

 

1. QWidget

 

QWidget을 딱 한마디로 설명하면 버튼, input 위젯 같은 다양한 위젯들을 올려놓을 수 있는 사각형의 영역입니다.

 

즉, 그림을 그릴 수 있는 도화지 같은 것이죠.

 

특징으로는 Main Window와 다르게 상단의 메뉴창과 하단의 상태창을 추가할 수 없습니다.

 

qt designer에서의 창 형태

qt designer에서의 객체 및 클래스 분류

 

2. QMainWindow

 

위에서 잠시 보았던 QWidget과 비슷하지만 조금 다릅니다.

 

QMainWindow는 최상위 위젯으로 메뉴바, 도구 모음, 상태바등이 포함된 미리 정의된 레이아웃을 가지고 있습니다.

 

가장 기본적인 QMainWindow의 형태

 

qt designer의 객체 탐색기를 살펴보면 QMainWindow라는 상위 클래스에 QWidget이 속해 있는 것을 알 수 있죠.

 

즉, MainWindow를 도화지와 도화지를 담고 있는 프레임이라고 생각하시면 됩니다.

 

qt designer에서의 객체 및 클래스 분류

 

 

3. QDialog

 

항상 별도의 창에 표시되는 대화상자로, 주로 우리가 흔히 보는 팝업창이나 경고창 역할을 주로 합니다.

 

아래의 그림에서 보시면 기본 템플릿에서 버튼을 제공하는 것이 있는데, 주로 사용자가 간단히 확인, 취소 버튼을 누를 때 사용하기 때문입니다. 아직 테스트는 해보지 않았지만 버튼을 최대로 넣을 수 있는 제한 같은게 있다고 하네요.

 

 

겉보기에는 Qwidget과 별 다를 것이 없죠?

 

qt designer에서의 객체 및 클래스 분류

 

4. Modal, Modeless 개념 (참고)

 

위에서 배운 기본적인 GUI 창 3형제를 더 깊이 이해하려면 Modal 및 Modaless의 개념에 대해서 알아야 합니다.

 

두 개념은은 MainWindow를 제외한 Widget과 Dialog에서 사용하는 실행 형식입니다.

 

참고로 Dialog 창은 Modal 속성을 주로 사용한답니다.

 

 

1) Modal

 

- 새롭게 Modal 속성을 가진 창이 열렸을 경우 기존에 있던 창을 사용하지 못하는 '제어권 독점' 방식입니다.

  (이 특성을 이용해서 중요한 메세지를 표시하는 Dialog는 거의 Modal 창을 이용합니다.)

 

- exec()의 실행 형식으로 독립적입니다. (이 부분은 좀 더 공부 필요)

 

2) Modeless

 

- 어느 하나의 Dialog 창이 있어도 프로그램 제어권을 독점하지 않으므로 다른 작업이 가능합니다. (즉, 다른창을 선택 가능)

 

- show()의 실행 형식으로 독립적이지 않습니다. (이 부분은 좀 더 공부 필요)

 


<참고자료>

 

1. 개발자 라면_QWidget과 QDialog의 차이 - Modal/Modeless

https://flower0.tistory.com/457

 

 

2. 타스의 개발 블로그_[MFC] Modal&Modeless Dialog: 설명

https://tars-c.github.io/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/mfc/dialog/Dialog-Modal-and-Modeless-%EC%84%A4%EB%AA%85/

 

 

반응형
반응형

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.

코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.

업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.

 

 

<Telegram 패키지 관련 지난 글>

 

2021.04.03 - [파이썬 패키지/텔레그램(Telegram)] - [Python / Telegram] 파이썬으로 Telegram bot 사용하는 법 (feat. 공시정보알림 탤레그램 봇 소개)

2021.12.05 - [파이썬 패키지/텔레그램(Telegram)] - [Python/Telegram] 파이썬으로 텔레그램 채널 관리 봇(bot) 사용하는 법_1편.채널 추가 및 관리자로 봇 추가(코딩 ㄴㄴ)


 

오늘은 지난 시간 생성한 채널에 봇을 이용해서 메시지를 보내는 방법을 포스팅 해보겠습니다.

 

 

1. 대화방의 chat_id 파악하기

 

지난 시간 텔레그램 봇을 생성하고, 채널도 생성하셨다면 이제 코딩을 할 시간입니다.

 

시작 전에 살포시 import를 해주겠습니다.

 

# 만약 설치가 안되어 있으면 터미널 창에 pip install python-telegram-bot 입력
import telegram

 

봇이 채팅을 할 수 있도록 하려면 2가지 정보가 필요합니다.

 

 

1) 봇의 토큰 정보

 

가장 기본적으로 필요한 봇 토큰과 토큰을 이용해서 봇을 불러오는 코드입니다.

#토큰을 변수에 저장 (대략 이렇게 생겼음: '0123456789:AABBCCDDGdv1mI8zOcd9d7d7q87q9qQ')
bot_token = '각자 생성한 봇의 고유 토큰 입렵(타인에게 노출하지 말 것)'

#telegram 패키지의 Bot 함수를 사용하여 내가 만든 bot 객체화
bot = telegram.Bot(token = bot_token)

 

만약 봇의 토큰 정보를 모르시는 분들은 텔래그램 관련 지난 글 중, 첫번째 글을 참고해주세요.

 

 

2) chat_id

 

오늘의 핵심은 chat_id의 개념입니다.

 

텔레그램의 대화방은 각각 고유한 chat_id를 가지고 있습니다.

우리가 봇을 이용해서 메시지를 보내기 위해서는 대화방의 chat_id를 알아야만 하죠.

 

chat_id를 알기 위해서는 일단 대화방에서 우리가 아무말이나 입력해서 전송해야합니다.

 

우선 여러분들이 만드신 봇(저의 경우엔 DART)의 대화방에 들어가셔서 아무말이나 입력해보세요.

 

그런 후에 아래의 코드를 실행합니다. (물론 위의 코드들이 선행되어야 합니다)

 

# bot과의 채팅 정보 및 메세지 업데이트
updates = bot.getUpdates()

# updates에 들어있는 내용 하나씩 꺼내어 출력
for i in updates :
    print(i)
    print('\n')

 

출력 결과는 이렇게 생겼습니다. 아주 길다란 딕셔너리 형태입니다. 

{'message': {'photo': [], 'chat': {'first_name': 'Sangwoo', 'type': 'private', 'id': 1516137537}, 'entities': [], 'channel_chat_created': False, 'new_chat_members': [], 'caption_entities': [], 'message_id': 255, 'new_chat_photo': [], 'delete_chat_photo': False, 'text': '여기는 봇과의 대화방', 'date': 1638625002, 'group_chat_created': False, 'supergroup_chat_created': False, 'from': {'first_name': 'Sangwoo', 'is_bot': False, 'language_code': 'ko', 'id': 1516137537}}, 'update_id': 899725563}

 

이걸 정리해서 보면 아래와 같은 구조를 갖고 있어요. 중요하게 볼 부분은 바로 chat 안의 id입니다.

저기 보이는 숫자가 제 봇 채팅방의 고유한 id인 것입니다. (단, 봇 토큰이 없으면 저 아이디를 알아도 채팅을 보낼 권한이 없답니다.)

 

참고로 type은 private, 즉 개인톡방입니다. 다음에 배울 채널 대화방은 channel이라고 나와요.

봇 채팅방의 chat_id

 

동일하게 여러분들이 지난 시간 만드신 채널에도 아무 채팅이나 전송한 후에 같은 코드를 실행하시면 아래와 같은 결과를 얻으실 수 있습니다.

채널 채팅방의 chat_id

 

2. 봇으로 메시지 보내기

 

여기까지 하셨으면 메시지를 보내는 방법은 너무나도 간단합니다.

 

# 위에서 파악한 코딩유치원 채널 id
chat_id = '-1001415675502'

#위에서 얻은 chat id로 bot이 메세지를 보냄.
bot.sendMessage(chat_id = chat_id, text="봇으로 보내는 메시지")

 

첫 메시지가 제가 직접 입력한 것이고, 두 번째 메시지가 위의 코드로 전송한 메시지 입니다. 

 

이렇게 봇으로 메시지를 보내는 방법을 이용하면 아래와 같은 프로젝트도 가능하답니다.

 

2021.04.05 - [파이썬 패키지/텔레그램(Telegram)] - [Python/Telegram] 원하는 주제의 네이버 뉴스 텔레그램으로 5분마다 전송 받기

 

[Python/Telegram] 원하는 주제의 네이버 뉴스 텔레그램으로 5분마다 전송 받기

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다. 코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석, 머신러닝 등의 다양한 패키지까지 초보자도

coding-kindergarten.tistory.com

 

 

반응형

+ Recent posts