개요
오늘은 PySide6를 활용하여 시/도 -> 시/군/구 -> 읍/면/동 단계별로 연동되는 지역 선택 기능을 구현해볼거다.
목표
- 1. 시/도 선택: 첫 번째
QComboBox
에서 시/도를 선택한다. - 2. 시/군/구 선택: 선택한 시/도에서 해당하는 시/군/구가 두 번째
QComboBox
에 표시된다. - 3. 읍/면/동 선택: 선택한 시/군/구에 해당하는 읍/면/동이 세 번째
QComboBox
에 표시된다. - 4. 각 항목에는 고유한 ID(
sidoID
)가 포함되어 있으며, 이를 기반으로 데이터를 관리한다.
구현
1. 기본 데이터 설계
지역 데이터를 계층적으로 저장하며, 각 항목은 고유한 ID를 가지도록 작성하자.
테스트를 위해 아래와 같은 테스트용 계층 데이터를 임의로 작성하였다.
region_data = {
"서울특별시": {
"sidoID": 1,
"children": {
"강남구": {
"sidoID": 90,
"children": {
"삼성동": 900,
"역삼동": 901,
"논현동": 902
}
},
"송파구": {
"sidoID": 91,
"children": {
"잠실동": 910,
"문정동": 911,
"가락동": 912
}
}
}
},
"경기도": {
"sidoID": 2,
"children": {
"수원시": {
"sidoID": 100,
"children": {
"장안구": 1000,
"권선구": 1001,
"영통구": 1002
}
},
"고양시": {
"sidoID": 101,
"children": {
"일산동구": 1010,
"일산서구": 1011,
"덕양구": 1012
}
}
}
}
}
2. PySide6 UI 구성
QComboBox
를 활용하여 세 개의 콤보박스를 생성한다.
각 콤보박스는 선택 이벤트에 따라 연동될거다.
3. 메인 윈도우 클래스
QMainWindow
를 상속하여 UI를 구성하고 데이터 연동 로직을 추가한다.
class RegionSelector(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("지역 선택")
self.setGeometry(100, 100, 400, 200)
# 메인 위젯 및 레이아웃 설정
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout()
main_widget.setLayout(layout)
# 콤보박스 생성
self.combo_sido = QComboBox()
self.combo_sigungu = QComboBox()
self.combo_eupmyeon = QComboBox()
# 콤보박스 초기화
self.combo_sido.addItem("시/도 선택", -1)
for sido, data in region_data.items():
self.combo_sido.addItem(sido, data["sidoID"])
self.combo_sigungu.addItem("시/군/구 선택", -1)
self.combo_eupmyeon.addItem("읍/면/동 선택", -1)
# 콤보박스를 레이아웃에 추가
layout.addWidget(self.combo_sido)
layout.addWidget(self.combo_sigungu)
layout.addWidget(self.combo_eupmyeon)
# 시그널 연결
self.combo_sido.currentIndexChanged.connect(self.update_sigungu)
self.combo_sigungu.currentIndexChanged.connect(self.update_eupmyeon)
4. 시/군/구 및 읍/면/동 연동
선택 이벤트에 따라 콤보박스를 동적으로 업데이트한다.
def update_sigungu(self):
self.combo_sigungu.clear()
self.combo_eupmyeon.clear()
self.combo_sigungu.addItem("시/군/구 선택", -1)
self.combo_eupmyeon.addItem("읍/면/동 선택", -1)
selected_sido = self.combo_sido.currentText()
if selected_sido in region_data:
for sigungu, data in region_data[selected_sido]["children"].items():
self.combo_sigungu.addItem(sigungu, data["sidoID"])
def update_eupmyeon(self):
self.combo_eupmyeon.clear()
self.combo_eupmyeon.addItem("읍/면/동 선택", -1)
selected_sido = self.combo_sido.currentText()
selected_sigungu = self.combo_sigungu.currentText()
if selected_sido in region_data:
sigungu_data = region_data[selected_sido]["children"].get(selected_sigungu, {})
if "children" in sigungu_data:
for eupmyeon, sidoID in sigungu_data["children"].items():
self.combo_eupmyeon.addItem(eupmyeon, sidoID)
실행 결과
아래는 실행 화면을 캡쳐한 것이다.
- 시/도 선택: "서울특별시" 선택 시, 강남구, 송파구 ..가 표시된다.
- 시/군/구 선택: "강남구" 선택시 삼성동, 역삼동 ..가 표시된다.
또한 선택된 항목의 ID는 QComboBOx.currentData()
로 가져올 수도 있다.
예를 들어:
selected_sido_id = self.combo_sido.currentData()
selected_sigungu_id = self.combo_sigungu.currentData()
selected_eupmyeon_id = self.combo_eupmyeon.currentData()
print(f"시/도 ID: {selected_sido_id}, 시/군/구 ID: {selected_sigungu_id}, 읍/면/동 ID: {selected_eupmyeon_id}")