넓이와 파일명을 입력하도록 창을 띄워서 유도해 보자
넓이와 파일명 둘 중 하나라도 입력하지 않으면 작동하지 않는다.
사용자가 입력하도록 오류 창을 띄워서 입력하도록 유도하자.
아직 리스트 위젯에 배경을 적용하지 않았다면 아래글 참고
Python 이미지 세로로 합치기 - 14 (Drag&Drop에 배경 이미지 적용)
사용자 편의를 위해서 리스트 위젯에 배경이미지를 적용해 보자 빈 화면만 덩그러니 있으면 뭘 어떻게 해야 하는지 모른다. 친절하게 파일을 Drag&Drop 하라고 해주자. 아직 버튼이 작동되지 않는
udangco-coding-record.tistory.com
1. class Ui_Form(object) 변경
이전에 Qtdesign에서 가져온 것이 Ui_Form으로 작성되어졌다.
완료 또는 오류 창을 적용하려면 QMessageBox를 사용해야 하는데 Ui_Form으로는 사용되지 않는다.
Ui_Dialog(QMainWindow)로 변경하자.
class Ui_Dialog(QMainWindow):
2. Form을 Dialog로 변경
ctrl+f 를 눌러서 Form을 전부 Dialog로 변경하자.
3. QWidget을 QDialog()로 변경
아래 함수를 찾아서 QWidget()을 QDialog()로 변경하자.
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QWidget()
아래 코드로 변경
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
4. 완료 창
이미지 합치기가 완료되면 완료창을 띄워야 한다.
try를 이용해서 merge_img 함수에 적용하자.
# 이미지 합치기 버튼
def merge_img(self):
count1 = self.listWidget.count()
new_width = int(self.lineEdit.text()) # 변경 이미지 넓이
file_name = self.lineEdit_2.text() # 파일 이름
try:
if count1 > 0:
new_height = 0
# 빈 이미지 만들기
for i in range(0, count1):
img = self.listWidget.item(i)
image = Image.open(img.text()) # 이미지 열기
image_width = image.size[0] # 원본 이미지 넓이
image_height = image.size[1] # 원본 이미지 높이
new_image = image.resize((new_width, int((image_height * new_width) / image_width))) # 이미지 비율 변경
new_height += new_image.size[1] # 이미지 높이 구하기
empty_img = Image.new('RGB', (new_width, new_height), '#FFFFFF')
# 이미지 합치기
merge_height = 0
for i in range(0, count1):
img = self.listWidget.item(i)
image = Image.open(img.text()) # 이미지 열기
# 하단 부터 동일
image_width = image.size[0] # 원본 이미지 넓이
image_height = image.size[1] # 원본 이미지 높이
new_image = image.resize((new_width, int((image_height * new_width) / image_width))) # 이미지 비율 변경
empty_img.paste(new_image, (0, merge_height)) # 이미지 합치기
merge_height += new_image.size[1] # 이미지 높이 구하기
empty_img.save(file_name + '.jpg')
QMessageBox.information(self, '완료', '완료되었습니다.') # 완료 창 띄우기
else:
pass
위 코드처럼 파일을 저장하고 완료 창을 띄우는 코드 한 줄을 입력하면 된다.
QMessageBox.information(self, '완료', '완료되었습니다.') # 완료 창 띄우기
5. 합치기 오류 창
합치기에 실패한다면 오류 창을 띄우도록 except를 사용해 보자.
except Exception as e:
QMessageBox.warning(self, 'Warning: 오류가 발생했습니다', e)
warning 메시지를 띄웠다.
6. 넓이를 미리 입력하기
넓이를 매번 입력하기 힘드니 미리 입력해 두고 사용자가 바꾸게 하자.
넓이 정보가 있는 줄 하단에 setText를 입력하자.
# 넓이 입력 칸
self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit.setGeometry(QtCore.QRect(10, 20, 151, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setText("1024")
7. 파일명 오류
파일명을 입력하지 않으면 오류창이 뜨도록 하자.
def merge_img(self):
count1 = self.listWidget.count()
new_width = int(self.lineEdit.text()) # 변경 이미지 넓이
file_name = self.lineEdit_2.text() # 파일 이름
if len(file_name) < 1:
QMessageBox.warning(self, 'Warning: 오류가 발생했습니다', '파일명을 입력하세요.')
else:
try:
if count1 > 0:
new_height = 0
# 빈 이미지 만들기
for i in range(0, count1):
img = self.listWidget.item(i)
image = Image.open(img.text()) # 이미지 열기
image_width = image.size[0] # 원본 이미지 넓이
image_height = image.size[1] # 원본 이미지 높이
new_image = image.resize((new_width, int((image_height * new_width) / image_width))) # 이미지 비율 변경
new_height += new_image.size[1] # 이미지 높이 구하기
empty_img = Image.new('RGB', (new_width, new_height), '#FFFFFF')
# 이미지 합치기
merge_height = 0
for i in range(0, count1):
img = self.listWidget.item(i)
image = Image.open(img.text()) # 이미지 열기
# 하단 부터 동일
image_width = image.size[0] # 원본 이미지 넓이
image_height = image.size[1] # 원본 이미지 높이
new_image = image.resize((new_width, int((image_height * new_width) / image_width))) # 이미지 비율 변경
empty_img.paste(new_image, (0, merge_height)) # 이미지 합치기
merge_height += new_image.size[1] # 이미지 높이 구하기
empty_img.save(file_name + '.jpg')
QMessageBox.information(self, '완료', '완료되었습니다.') # 완료 창 띄우기
else:
pass
except Exception as e:
QMessageBox.warning(self, 'Warning: 오류가 발생했습니다', e)
파일명이 몇 개의 문자로 되었는지 확인하고 1보다 작으면 if len(file_name) < 1:
오류 창을 띄운다. QMessageBox.warning(self, 'Warning: 오류가 발생했습니다', '파일명을 입력하세요.')
이제 모든 작업이 완료되었다.
전체코드
import os
import PyQt5
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize, Qt, QMimeDatabase
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QListWidget
import mimetypes
from PIL import Image
# 배경이미지
def resource_path(relative_path):
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
bg_img = resource_path('bg.jpg').replace('\\', '/')
# drag and drop event. 파일 위치 경로를 가져오기
class ListBoxWidget(QListWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setAcceptDrops(True)
self.setIconSize(QSize(50, 50))
self.setStyleSheet(''' border-image: url(''' + bg_img + '''); ''') # 배경 이미지 생성
def dragEnterEvent(self, event):
if event.mimeData().hasUrls:
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(Qt.CopyAction)
event.accept()
else:
event.ignore()
def dropEvent(self, event):
img_file = self.find_img(event.mimeData())
if img_file:
if event.mimeData().hasUrls():
event.setDropAction(Qt.CopyAction)
event.accept()
self.setStyleSheet('''border-image: url();''') # 배경 삭제
for file in img_file:
icon = QtGui.QIcon(str(file.toLocalFile())) # 아이콘 형태로 이미지 가져오기
show_file = QtWidgets.QListWidgetItem(icon, str(file.toLocalFile()))
self.addItem(show_file)
else:
event.ignore()
else:
event.ignore()
def find_img(self, mimedata):
file_list = list()
db = QMimeDatabase()
for file in mimedata.urls():
mimetype = db.mimeTypeForUrl(file) # pyqt mimetype 이용
mimetype_e = mimetypes.guess_type(file.toString())[0]
if (mimetype.name() == "image/bmp") or (mimetype.name() == "image/gif") or (mimetype.name() == "image/jpeg") or (mimetype.name() == "image/png"):
file_list.append(file)
elif (mimetype_e == "image/bmp") or (mimetype_e == "image/gif") or (mimetype_e == "image/jpeg") or (mimetype_e == "image/png"):
file_list.append(file)
else:
pass
return file_list
class Ui_Dialog(QMainWindow):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(690, 641)
# 넓이 그룹 박스
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setGeometry(QtCore.QRect(30, 30, 631, 51))
self.groupBox.setObjectName("groupBox")
# 넓이 입력 칸
self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit.setGeometry(QtCore.QRect(10, 20, 151, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setText("1024")
# 파일 이름 그룹 박스
self.groupBox_2 = QtWidgets.QGroupBox(Dialog)
self.groupBox_2.setGeometry(QtCore.QRect(30, 90, 631, 51))
self.groupBox_2.setObjectName("groupBox_2")
# 파일 이름 입력 칸
self.lineEdit_2 = QtWidgets.QLineEdit(self.groupBox_2)
self.lineEdit_2.setGeometry(QtCore.QRect(10, 20, 541, 20))
self.lineEdit_2.setObjectName("lineEdit_2")
# 이미지 그룹 박스
self.groupBox_3 = QtWidgets.QGroupBox(Dialog)
self.groupBox_3.setGeometry(QtCore.QRect(30, 150, 631, 411))
self.groupBox_3.setObjectName("groupBox_3")
# 이미지 리스트 위젯
self.listWidget = ListBoxWidget(self.groupBox_3)
self.listWidget.setGeometry(QtCore.QRect(10, 20, 511, 371))
self.listWidget.setObjectName("listWidget")
# 위로 버튼
self.pushButton = QtWidgets.QPushButton(self.groupBox_3)
self.pushButton.setGeometry(QtCore.QRect(540, 20, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.up_btn) # 위로 이동 버튼 연결
# 아래로 버튼
self.pushButton_2 = QtWidgets.QPushButton(self.groupBox_3)
self.pushButton_2.setGeometry(QtCore.QRect(540, 50, 75, 23))
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_2.clicked.connect(self.down_btn) # 아래로 이동 버튼 연결
# 제거 버튼
self.pushButton_3 = QtWidgets.QPushButton(self.groupBox_3)
self.pushButton_3.setGeometry(QtCore.QRect(540, 80, 75, 23))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_3.clicked.connect(self.del_btn) # 제거 버튼 연결
# 합치기 버튼
self.pushButton_4 = QtWidgets.QPushButton(Dialog)
self.pushButton_4.setGeometry(QtCore.QRect(40, 570, 511, 41))
self.pushButton_4.setObjectName("pushButton_4")
self.pushButton_4.clicked.connect(self.merge_img) # 합치기 버튼 연결
# 초기화 버튼
self.pushButton_5 = QtWidgets.QPushButton(Dialog)
self.pushButton_5.setGeometry(QtCore.QRect(570, 570, 71, 41))
self.pushButton_5.setObjectName("pushButton_5")
self.pushButton_5.clicked.connect(self.set_init) # 초기화 버튼 연결
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "이미지 합치기 v1.0"))
self.groupBox.setTitle(_translate("Dialog", "가로 사이즈 (px)"))
self.groupBox_2.setTitle(_translate("Dialog", "파일명"))
self.lineEdit_2.setPlaceholderText(_translate("Dialog", "확장자를 제외한 파일명을 입력해 주세요."))
self.groupBox_3.setTitle(_translate("Dialog", "이미지"))
self.pushButton.setText(_translate("Dialog", "위 이동"))
self.pushButton_2.setText(_translate("Dialog", "아래 이동"))
self.pushButton_3.setText(_translate("Dialog", "제거"))
self.pushButton_4.setText(_translate("Dialog", "합치기"))
self.pushButton_5.setText(_translate("Dialog", "초기화"))
# 버튼 함수
def up_btn(self): # 위로 이동
row = self.listWidget.currentRow()
if row > 0:
self.listWidget.insertItem(row - 1, self.listWidget.takeItem(row))
self.listWidget.setCurrentRow(row - 1)
def down_btn(self): # 아래로 이동
row = self.listWidget.currentRow()
if row < self.listWidget.count() - 1:
self.listWidget.insertItem(row + 1, self.listWidget.takeItem(row))
self.listWidget.setCurrentRow(row + 1)
def del_btn(self): # 삭제
self.listWidget.takeItem(self.listWidget.currentRow())
if self.listWidget.count() == 0:
self.listWidget.setStyleSheet(''' border-image: url(''' + bg_img + '''); ''') # 배경 이미지 생성
else:
pass
def set_init(self): # 초기화
self.listWidget.clear() # 리스트 위젯 리스트 삭제
self.lineEdit.clear() # 넓이 칸 텍스트 삭제
self.lineEdit_2.clear() # 파일명 칸 텍스트 삭제
self.listWidget.setStyleSheet(''' border-image: url(''' + bg_img + '''); ''') # 배경 이미지 생성
# 이미지 합치기 버튼
def merge_img(self):
count1 = self.listWidget.count()
new_width = int(self.lineEdit.text()) # 변경 이미지 넓이
file_name = self.lineEdit_2.text() # 파일 이름
if len(file_name) < 1:
QMessageBox.warning(self, 'Warning: 오류가 발생했습니다', '파일명을 입력하세요.')
else:
try:
if count1 > 0:
new_height = 0
# 빈 이미지 만들기
for i in range(0, count1):
img = self.listWidget.item(i)
image = Image.open(img.text()) # 이미지 열기
image_width = image.size[0] # 원본 이미지 넓이
image_height = image.size[1] # 원본 이미지 높이
new_image = image.resize((new_width, int((image_height * new_width) / image_width))) # 이미지 비율 변경
new_height += new_image.size[1] # 이미지 높이 구하기
empty_img = Image.new('RGB', (new_width, new_height), '#FFFFFF')
# 이미지 합치기
merge_height = 0
for i in range(0, count1):
img = self.listWidget.item(i)
image = Image.open(img.text()) # 이미지 열기
# 하단 부터 동일
image_width = image.size[0] # 원본 이미지 넓이
image_height = image.size[1] # 원본 이미지 높이
new_image = image.resize((new_width, int((image_height * new_width) / image_width))) # 이미지 비율 변경
empty_img.paste(new_image, (0, merge_height)) # 이미지 합치기
merge_height += new_image.size[1] # 이미지 높이 구하기
empty_img.save(file_name + '.jpg')
QMessageBox.information(self, '완료', '완료되었습니다.') # 완료 창 띄우기
else:
pass
except Exception as e:
QMessageBox.warning(self, 'Warning: 오류가 발생했습니다', e)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
마지막으로 실행파일을 만들자.
Python 이미지 세로로 합치기 - 16 (실행 파일 만들기)
실행 파일을 만들어서 쉽게 사용해 보자 완료 및 오류 창을 띄우는 작업까지 해 보았다. 이대로 사용해도 되지만 매번 파이참을 띄우기 번거로우니 실행 파일을 만들어 보자. 아직 완료 및 오류
udangco-coding-record.tistory.com
'파이썬' 카테고리의 다른 글
Python 이미지 url을 이용한 다운로드 (urllib.request.urlretrieve) (0) | 2024.03.15 |
---|---|
Python 이미지 세로로 합치기 - 16 (실행 파일 만들기) (0) | 2024.03.15 |
Python 이미지 세로로 합치기 - 14 (Drag&Drop에 배경 이미지 적용) (0) | 2024.03.14 |
Python 이미지 세로로 합치기 - 13 (버튼 연결) (0) | 2024.03.14 |
Python 이미지 세로로 합치기 - 12 (버튼 함수 만들기) (0) | 2024.03.14 |