© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🎆
005 생선가게 POS기 만들기 - 3 1. 기획 이제 본격적으로 POS기를 만들어 보도록 하겠습니다. 위에서 학습한 내용을 바탕으로 코드 작성을 하도록 하겠습니다.
2. 코드 구현 안된 기능
이전에 생성된 spinbox 값 변경 시 변경 내용 무시됨 → 아래 코드2-2확인
2-2 코드 '이전에 생성된 spinbox 값 변경 시 변경 내용 무시됨'
→ spinbox에 있는 값 받아와서 다른 메뉴를 클릭했을 경우 spinbox 위젯 삭제 후 label로 표기(이전값을 변경하지 못하도록 우회)
→ 정정버튼 추가
3. 상세 내용 전체 UI는
- 화면 상단에서 오늘의 날짜와 매출금액을 확인할 수 있는 '오늘'
- 화면 왼쪽에서 주문할 메뉴를 선택할 수 있는 '메뉴'
- 화면 오른쪽에서 선택된 메뉴들의 가격과 수량을 선택할 수 있는 '주문내역'
이렇게 세부분으로 구성되어 있습니다.
화면 왼쪽, 생선 이름으로 생성된 버튼을 클릭했을 때 실행되는 함수입니다. 화면 오른쪽에 생기는 주문내역을 표시해주기 위해 '생선_주문'인자값을 받아옵니다.
이 인자값에서 정규식을 이용하여 한글만 뽑아내면 '생선이름+원'을 추출할 수 있고, 숫자만 뽑아내면 생선가격 값을 추출할 수 있습니다.
(문자열 인덱싱을 통해 생선이름 마지막에 붙어있는 '원'을 제거해줍니다.)
같은 버튼이 여러번 클릭되었을 경우를 방지하기 위해 '중복확인'이라는 리스트를 초기화 시킬때 선언해줍니다. 중복확인 리스트 안에 생선이름이 없을 경우에만 QGridLayout으로 선언된 '주문 상품 목록'에 현재 선택된 생선 이름의 라벨과 SpinBox를 생성해줍니다. 중첩된 if문은 이전 spinbox를 제거하고 label로 생성해주는 코드입니다. 마리수_temp, 금액_temp은 새로운 메뉴 버튼이 눌렸을 경우 이전값을 가져오기 위한 임시 저장소라고 생각하시면 됩니다. 스핀박스의 값이 변화되었을 경우, 계산하기 함수를 호출하여 총수량과 총금액을 실시간으로 출력해줍니다.
'정정하기' 버튼을 클릭했을 경우에는 '정정하기_버튼클릭()' 메서드를 연결하고, '결제하기' 버튼을 클릭했을 경우에는 '결제하기_버튼클릭()' 메서드를 연결시켜줍니다. 정정하기 버튼을 클릭했을 때와 결제하기 버튼을 클릭했을 경우 동작원리는 비슷하여 결제하기 버튼에서 호출하도록 했습니다. 다만 결제하기 버튼에서 오늘 총금액을 계산해줘야 하므로 해당 코드를 추가했습니다.
우선 주문상품_목록의 갯수만큼 for문 동작시켜 주문상품_목록에서 item을 찾아 삭제할 위젯에 할당해주고, removeWidget을 이용하여 레이아웃 리스트에서 제거한 뒤 setParent를 이용해서 gui까지 삭제해주면 위젯이 삭제됩니다.
'스핀박스_만들기()' 메서드에서 생성된 '스핀박스'를 '스핀박스_리스트'에 저장해두고, 그 저장해둔 스핀박스를 꺼내서 지워줍니다. deleteLater()는 개체를 삭제하도록 예약합니다. 4. 실행 화면 import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QPixmap, QFont
from PyQt5.QtCore import QCoreApplication, Qt, QDate
import re
class 생선가게POS기(QWidget):
def __init__(self):
super().__init__()
self.UI초기화()
def UI초기화(self):
# 나중에 메서드에서 사용 될 변수들
self.i = 0
self.중복확인 = []
self.마리수 = 0
self.금액 = 0
self.몇마리_temp = 0
self.금액_temp = 0
self.오늘총금액 = 0
# UI 초기화
가로정렬 = QHBoxLayout()
가로정렬.addWidget(self.메뉴())
가로정렬.addWidget(self.주문내역())
세로정렬 = QVBoxLayout()
세로정렬.addWidget(self.오늘())
세로정렬.addLayout(가로정렬)
self.setLayout(세로정렬)
self.setWindowTitle('(주)캣네생선 POS기')
self.setWindowIcon(QIcon('img/캣네생선.png'))
self.setGeometry(700, 400, 650, 480)
self.show()
# 화면 상단부에 나오는 날짜와 오늘매출을 표시하는 메서드
def 오늘(self):
self.날짜 = QDate.currentDate()
self.오늘날짜 = QLabel(QDate.currentDate().toString('yyyy년 MM월 dd일'))
self.오늘매출 = QLabel('오늘 총 매출 : 0원')
self.그룹박스_오늘 = QGroupBox()
self.가로정렬_오늘 = QHBoxLayout()
self.가로정렬_오늘.addWidget(self.오늘날짜)
self.가로정렬_오늘.addWidget(self.오늘매출, alignment=Qt.AlignRight)
self.그룹박스_오늘.setLayout(self.가로정렬_오늘)
self.그룹박스_오늘.setFixedHeight(50)
return self.그룹박스_오늘
# 화면 왼쪽의 메뉴를 표시하는 메서드
def 메뉴(self):
self.삼치 = QPushButton('\n삼치\n3500원\n',self)
self.고등어 = QPushButton('\n고등어\n4500원\n',self)
self.꽁치 = QPushButton('\n꽁치\n5000원\n',self)
self.연어 = QPushButton('\n연어\n5500원\n',self)
self.광어 = QPushButton('\n광어\n6000원\n',self)
self.굴비 = QPushButton('\n굴비\n7000원\n',self)
self.넙치 = QPushButton('\n넙치\n8000원\n',self)
self.갈치 = QPushButton('\n갈치\n12000원\n',self)
self.참돔 = QPushButton('\n참돔\n20000원\n',self)
self.그룹박스_생선 = QGroupBox('메뉴')
self.생선들 = QGridLayout()
self.생선들.addWidget(self.삼치, 1,0)
self.생선들.addWidget(self.고등어, 1,1)
self.생선들.addWidget(self.꽁치, 1,2)
self.생선들.addWidget(self.연어, 2,0)
self.생선들.addWidget(self.광어, 2,1)
self.생선들.addWidget(self.굴비, 2,2)
self.생선들.addWidget(self.넙치, 3,0)
self.생선들.addWidget(self.갈치, 3,1)
self.생선들.addWidget(self.참돔, 3,2)
self.삼치.clicked.connect(lambda:self.생선선택하기(self.삼치_주문))
self.고등어.clicked.connect(lambda:self.생선선택하기(self.고등어_주문))
self.꽁치.clicked.connect(lambda:self.생선선택하기(self.꽁치_주문))
self.연어.clicked.connect(lambda:self.생선선택하기(self.연어_주문))
self.광어.clicked.connect(lambda:self.생선선택하기(self.광어_주문))
self.굴비.clicked.connect(lambda:self.생선선택하기(self.굴비_주문))
self.넙치.clicked.connect(lambda:self.생선선택하기(self.넙치_주문))
self.갈치.clicked.connect(lambda:self.생선선택하기(self.갈치_주문))
self.참돔.clicked.connect(lambda:self.생선선택하기(self.참돔_주문))
self.그룹박스_생선.setLayout(self.생선들)
return self.그룹박스_생선
# 메뉴를 클릭하면 나타나는 주문내역과 결제창을 보여주는 메서드
def 주문내역(self):
self.그룹박스_주문내역 = QGroupBox('주문 상품 목록')
self.세로정렬_주문내역 = QVBoxLayout()
self.세로정렬_주문내역.addWidget(self.주문내역_숨김())
self.세로정렬_주문내역.addWidget(self.결제박스())
self.그룹박스_주문내역.setLayout(self.세로정렬_주문내역)
self.그룹박스_주문내역.setFixedWidth(200)
return self.그룹박스_주문내역
# '주문내역' grid박스 내 아래쪽에 보여지는 결제박스
def 결제박스(self):
self.총수량_라벨 = QLabel('총 수량 :')
self.총수량 = QLabel('- 마리')
self.총금액_라벨 = QLabel('총 금액 :')
self.총금액 = QLabel(' - 원')
self.결제버튼 = QPushButton('결제하기',self)
# 인코딩문제로 인해서 lambda함수 사용함
# self.결제버튼.clicked.connect(self.결제하기_버튼클릭)
self.결제버튼.clicked.connect(lambda:self.결제하기_버튼클릭())
self.그룹박스_결제 = QGroupBox()
self.그룹박스_결제.setFlat(True)
self.결제값 = QGridLayout()
self.결제값.addWidget(self.총수량_라벨,0,0,1,3)
self.결제값.addWidget(self.총수량,0,5)
self.결제값.addWidget(self.총금액_라벨,1,0,1,3)
self.결제값.addWidget(self.총금액,1,5)
self.결제값.addWidget(self.결제버튼,2,0,1,6)
self.그룹박스_결제.setLayout(self.결제값)
self.그룹박스_결제.setFixedHeight(100)
return self.그룹박스_결제
# 메뉴를 클릭하면 오른쪽 주문내역에서 나타나는 라벨
def 주문내역_숨김(self):
self.삼치_주문 = QLabel('삼치 3500원')
self.고등어_주문 = QLabel('고등어 4500원')
self.꽁치_주문 = QLabel('꽁치 5000원')
self.연어_주문 = QLabel('연어 5500원')
self.광어_주문 = QLabel('광어 6000원')
self.굴비_주문 = QLabel('굴비 7000원')
self.넙치_주문 = QLabel('넙치 8000원')
self.갈치_주문 = QLabel('갈치 12000원')
self.참돔_주문 = QLabel('참돔 20000원')
self.그룹박스_선택 = QGroupBox()
self.선택하기 = QGridLayout()
self.그룹박스_선택.setLayout(self.선택하기)
return self.그룹박스_선택
def 스핀박스_만들기(self):
self.스핀박스 = QSpinBox()
self.스핀박스.setFixedWidth(45)
return self.스핀박스
# 결제하기 버튼 클릭했을 경우 실행되는 메서드
def 결제하기_버튼클릭(self):
# 오늘 총 매출 나타내기
if self.총금액.text() == ' - 원':
self.총금액.setText('0')
self.오늘총금액 += int(self.총금액.text())
self.오늘매출.setText(f'오늘 총 매출 : {self.오늘총금액}원')
# 마리수, 금액, 중복확인리스트 초기화
self.마리수 = 0
self.금액 = 0
self.몇마리_temp = 0
self.금액_temp = 0
self.중복확인 = []
# ui초기화
self.총수량.setText('- 마리')
self.총금액.setText(' - 원')
# ui초기화 - 선택하기 초기화
for i in reversed(range(self.선택하기.count())):
삭제할위젯 = self.선택하기.itemAt(i).widget()
self.선택하기.removeWidget(삭제할위젯)
삭제할위젯.setParent(None)
#생선을 선택했을 때 실행되는 메서드
def 생선선택하기(self, 생선주문):
생선이름 = 생선주문
생선가격 = int(re.sub('[^0-9]','',생선주문.text()))
# 같은 생선을 중복생성할 경우를 막기위한 if문
if 생선이름 in self.중복확인:
pass
else:
self.몇마리_temp += self.마리수
self.금액_temp += self.금액
self.i += 1
self.중복확인.append(생선이름)
self.선택하기.addWidget(생선주문, self.i, 0)
self.선택하기.addWidget(self.스핀박스_만들기(), self.i, 3)
self.선택하기.setAlignment(Qt.AlignTop)
self.스핀박스.valueChanged.connect(lambda:self.계산하기(생선가격))
# 총수량과 총금액을 계산하기 위한 메서드
def 계산하기(self, 생선가격):
self.마리수 = self.스핀박스.value()
self.금액 = self.마리수*생선가격
self.총수량.setText(str(self.마리수+self.몇마리_temp))
self.총금액.setText(str(self.금액+self.금액_temp))
프로그램무한반복 = QApplication(sys.argv)
실행인스턴스 = 생선가게POS기()
프로그램무한반복.exec_()
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon, QPixmap, QFont
from PyQt5.QtCore import QCoreApplication, Qt, QDate
import re
class 생선가게POS기(QWidget):
def __init__(self):
super().__init__()
self.UI초기화()
def UI초기화(self):
# 나중에 메서드에서 사용 될 변수들
self.j = 1
self.i = 0
self.중복확인 = []
self.마리수 = 0
self.금액 = 0
self.마리수_temp = 0
self.금액_temp = 0
self.오늘총금액 = 0
self.스핀박스_리스트 = []
# UI 초기화
가로정렬 = QHBoxLayout()
가로정렬.addWidget(self.메뉴())
가로정렬.addWidget(self.주문내역())
세로정렬 = QVBoxLayout()
세로정렬.addWidget(self.오늘())
세로정렬.addLayout(가로정렬)
self.setLayout(세로정렬)
self.setWindowTitle('(주)캣네생선 POS기')
self.setWindowIcon(QIcon('img/캣네생선.png'))
self.setGeometry(700, 400, 650, 430)
self.show()
# 화면 상단부에 나오는 날짜와 오늘매출을 표시하는 메서드
def 오늘(self):
self.날짜 = QDate.currentDate()
self.오늘날짜 = QLabel(QDate.currentDate().toString('yyyy년 MM월 dd일'))
self.오늘매출 = QLabel('오늘 총 매출 : 0원')
그룹박스_오늘 = QGroupBox()
가로정렬_오늘 = QHBoxLayout()
가로정렬_오늘.addWidget(self.오늘날짜)
가로정렬_오늘.addWidget(self.오늘매출, alignment=Qt.AlignRight)
그룹박스_오늘.setLayout(가로정렬_오늘)
그룹박스_오늘.setFixedHeight(50)
return 그룹박스_오늘
# 화면 왼쪽의 메뉴를 표시하는 메서드
def 메뉴(self):
삼치 = QPushButton('\n삼치\n3500원\n',self)
고등어 = QPushButton('\n고등어\n4500원\n',self)
꽁치 = QPushButton('\n꽁치\n5000원\n',self)
연어 = QPushButton('\n연어\n5500원\n',self)
광어 = QPushButton('\n광어\n6000원\n',self)
굴비 = QPushButton('\n굴비\n7000원\n',self)
넙치 = QPushButton('\n넙치\n8000원\n',self)
갈치 = QPushButton('\n갈치\n12000원\n',self)
참돔 = QPushButton('\n참돔\n20000원\n',self)
그룹박스_생선 = QGroupBox('메뉴')
생선들 = QGridLayout()
생선들.addWidget(삼치, 1,0)
생선들.addWidget(고등어, 1,1)
생선들.addWidget(꽁치, 1,2)
생선들.addWidget(연어, 2,0)
생선들.addWidget(광어, 2,1)
생선들.addWidget(굴비, 2,2)
생선들.addWidget(넙치, 3,0)
생선들.addWidget(갈치, 3,1)
생선들.addWidget(참돔, 3,2)
삼치.clicked.connect(lambda:self.생선선택하기(self.삼치_주문))
고등어.clicked.connect(lambda:self.생선선택하기(self.고등어_주문))
꽁치.clicked.connect(lambda:self.생선선택하기(self.꽁치_주문))
연어.clicked.connect(lambda:self.생선선택하기(self.연어_주문))
광어.clicked.connect(lambda:self.생선선택하기(self.광어_주문))
굴비.clicked.connect(lambda:self.생선선택하기(self.굴비_주문))
넙치.clicked.connect(lambda:self.생선선택하기(self.넙치_주문))
갈치.clicked.connect(lambda:self.생선선택하기(self.갈치_주문))
참돔.clicked.connect(lambda:self.생선선택하기(self.참돔_주문))
그룹박스_생선.setLayout(생선들)
return 그룹박스_생선
# 메뉴를 클릭하면 나타나는 주문내역과 결제창을 보여주는 메서드
def 주문내역(self):
그룹박스_주문내역 = QGroupBox('주문 상품 목록')
세로정렬_주문내역 = QVBoxLayout()
세로정렬_주문내역.addWidget(self.주문내역_숨김())
세로정렬_주문내역.addWidget(self.결제박스())
그룹박스_주문내역.setLayout(세로정렬_주문내역)
그룹박스_주문내역.setFixedWidth(200)
return 그룹박스_주문내역
# '주문내역' grid박스 내 아래쪽에 보여지는 결제박스
def 결제박스(self):
총수량_라벨 = QLabel('총 수량 :')
self.총수량 = QLabel('- 마리')
총금액_라벨 = QLabel('총 금액 :')
self.총금액 = QLabel(' - 원')
정정버튼 = QPushButton('정정하기',self)
결제버튼 = QPushButton('결제하기',self)
# 인코딩문제로 인해서 lambda함수 사용함
# self.결제버튼.clicked.connect(self.결제하기_버튼클릭)
정정버튼.clicked.connect(lambda:self.정정하기_버튼클릭())
결제버튼.clicked.connect(lambda:self.결제하기_버튼클릭())
그룹박스_결제 = QGroupBox()
그룹박스_결제.setFlat(True)
결제값 = QGridLayout()
결제값.addWidget(총수량_라벨,0,0,1,3)
결제값.addWidget(self.총수량,0,5)
결제값.addWidget(총금액_라벨,1,0,1,3)
결제값.addWidget(self.총금액,1,5)
결제값.addWidget(정정버튼,2,0,1,6)
결제값.addWidget(결제버튼,3,0,1,6)
그룹박스_결제.setLayout(결제값)
그룹박스_결제.setFixedHeight(130)
return 그룹박스_결제
# 메뉴를 클릭하면 오른쪽 주문내역에서 나타나는 라벨
def 주문내역_숨김(self):
self.삼치_주문 = QLabel('삼치 3500원')
self.고등어_주문 = QLabel('고등어 4500원')
self.꽁치_주문 = QLabel('꽁치 5000원')
self.연어_주문 = QLabel('연어 5500원')
self.광어_주문 = QLabel('광어 6000원')
self.굴비_주문 = QLabel('굴비 7000원')
self.넙치_주문 = QLabel('넙치 8000원')
self.갈치_주문 = QLabel('갈치 12000원')
self.참돔_주문 = QLabel('참돔 20000원')
그룹박스_숨김 = QGroupBox()
self.주문상품_목록 = QGridLayout()
그룹박스_숨김.setLayout(self.주문상품_목록)
return 그룹박스_숨김
def 스핀박스_만들기(self):
self.스핀박스 = QSpinBox()
self.스핀박스.setFixedWidth(45)
self.스핀박스_리스트.append(self.스핀박스)
return self.스핀박스
# 정정하기 버튼 클릭했을 경우 실행되는 메서드
def 정정하기_버튼클릭(self):
# 마리수, 금액, 중복확인리스트 초기화
self.마리수 = 0
self.금액 = 0
self.마리수_temp = 0
self.금액_temp = 0
self.중복확인 = []
self.스핀박스_리스트 = []
self.i = 0
# ui초기화
self.총수량.setText('- 마리')
self.총금액.setText(' - 원')
# ui초기화 - 주문상품_목록 초기화
self.위젯삭제하기()
# 결제하기 버튼 클릭했을 경우 실행되는 메서드
def 결제하기_버튼클릭(self):
if self.총금액.text() == ' - 원':
self.총금액.setText('0')
self.오늘총금액 += int(self.총금액.text())
self.오늘매출.setText(f'오늘 총 매출 : {self.오늘총금액}원')
self.정정하기_버튼클릭()
def 위젯삭제하기(self):
for i in reversed(range(self.주문상품_목록.count())):
삭제할위젯 = self.주문상품_목록.itemAt(i).widget()
self.주문상품_목록.removeWidget(삭제할위젯)
삭제할위젯.setParent(None)
def 스핀박스_삭제하기(self):
마지막위젯 = self.스핀박스_리스트.pop(-1)
self.주문상품_목록.removeWidget(마지막위젯)
마지막위젯.deleteLater()
# 생선(메뉴)을 선택했을 때 실행되는 메서드
def 생선선택하기(self, 생선_주문):
생선이름 = str(re.sub('[^ㄱ-힗]', '', 생선_주문.text()))[:-1]
생선가격 = int(re.sub('[^0-9]','',생선_주문.text()))
# 같은 생선을 중복생성할 경우를 막기위한 if문
if 생선이름 in self.중복확인:
pass
else:
# 이전에 생성된 스핀박스가 있다면 그 값을 가져와서 변경이 불가능한 라벨로 만들기
if self.스핀박스_리스트:
temp = self.스핀박스.value()
self.스핀박스_라벨 = QLabel(str(temp))
self.스핀박스_삭제하기()
self.주문상품_목록.addWidget(self.스핀박스_라벨, self.i,3)
self.마리수_temp += self.마리수
self.금액_temp += self.금액
self.마리수,self.금액 = 0,0
self.i += 1
self.중복확인.append(생선이름)
self.주문상품_목록.addWidget(생선_주문, self.i, 0)
self.주문상품_목록.addWidget(self.스핀박스_만들기(), self.i, 3)
self.주문상품_목록.setAlignment(Qt.AlignTop)
self.스핀박스.valueChanged.connect(lambda:self.계산하기(생선가격))
# 총수량과 총금액을 계산하기 위한 메서드
def 계산하기(self, 생선가격):
self.마리수 = self.스핀박스.value()
self.금액 = self.마리수 * 생선가격
self.총수량.setText(str(self.마리수 + self.마리수_temp))
self.총금액.setText(str(self.금액 + self.금액_temp))
프로그램무한반복 = QApplication(sys.argv)
실행인스턴스 = 생선가게POS기()
프로그램무한반복.exec_()
# 생선(메뉴)을 선택했을 때 실행되는 메서드
def 생선선택하기(self, 생선_주문):
생선이름 = str(re.sub('[^ㄱ-힗]', '', 생선_주문.text()))[:-1]
생선가격 = int(re.sub('[^0-9]','',생선_주문.text()))
# 같은 생선을 중복생성할 경우를 막기위한 if문
if 생선이름 in self.중복확인:
pass
else:
# 이전에 생성된 스핀박스가 있다면 그 값을 가져와서 변경이 불가능한 라벨로 만들기
if self.스핀박스_리스트:
temp = self.스핀박스.value()
self.스핀박스_라벨 = QLabel(str(temp))
self.스핀박스_삭제하기()
self.주문상품_목록.addWidget(self.스핀박스_라벨, self.i,3)
self.마리수_temp += self.마리수
self.금액_temp += self.금액
self.마리수, self.금액 = 0, 0
self.i += 1
self.중복확인.append(생선이름)
self.주문상품_목록.addWidget(생선_주문, self.i, 0)
self.주문상품_목록.addWidget(self.스핀박스_만들기(), self.i, 3)
self.주문상품_목록.setAlignment(Qt.AlignTop)
self.스핀박스.valueChanged.connect(lambda:self.계산하기(생선가격))
# 총수량과 총금액을 계산하기 위한 메서드
def 계산하기(self, 생선가격):
self.마리수 = self.스핀박스.value()
self.금액 = self.마리수 * 생선가격
self.총수량.setText(str(self.마리수 + self.마리수_temp))
self.총금액.setText(str(self.금액 + self.금액_temp))
정정버튼 = QPushButton('정정하기',self)
결제버튼 = QPushButton('결제하기',self)
정정버튼.clicked.connect(lambda:self.정정하기_버튼클릭())
결제버튼.clicked.connect(lambda:self.결제하기_버튼클릭())
# 정정하기 버튼 클릭했을 경우 실행되는 메서드
def 정정하기_버튼클릭(self):
# 마리수, 금액, 중복확인리스트 초기화
self.마리수 = 0
self.금액 = 0
self.마리수_temp = 0
self.금액_temp = 0
self.중복확인 = []
self.스핀박스_리스트 = []
self.i = 0
# ui초기화
self.총수량.setText('- 마리')
self.총금액.setText(' - 원')
# ui초기화 - 주문상품_목록 초기화
self.위젯삭제하기()
# 결제하기 버튼 클릭했을 경우 실행되는 메서드
def 결제하기_버튼클릭(self):
if self.총금액.text() == ' - 원':
self.총금액.setText('0')
self.오늘총금액 += int(self.총금액.text())
self.오늘매출.setText(f'오늘 총 매출 : {self.오늘총금액}원')
self.정정하기_버튼클릭()
def 위젯삭제하기(self):
for i in reversed(range(self.주문상품_목록.count())):
삭제할위젯 = self.주문상품_목록.itemAt(i).widget()
self.주문상품_목록.removeWidget(삭제할위젯)
삭제할위젯.setParent(None)
def 스핀박스_삭제하기(self):
마지막위젯 = self.스핀박스_리스트.pop(-1)
self.주문상품_목록.removeWidget(마지막위젯)
마지막위젯.deleteLater()