- 천 단위 쉼표 자동 입력의 필요성
- PySide6와 QLineEdit 기본 이해하기
- 입력 제한 설정: 숫자만 입력받기
- 천 단위 쉼표 자동 추가 기능 구현
- 커서 위치 유지하기
- 포커스 이벤트 처리하기
- 전체 코드 분석 및 활용 방법
천 단위 쉼표 자동 입력의 필요성
금액이나 큰 숫자를 다루는 애플리케이션을 개발할 때,
사용자 경험을 향상시키는 중요한 기능 중 하나가 바로 천 단위 쉼표 자동 추가 기능입니다.
예를 들어 '1000000'이라는 숫자보다
'1,000,000'으로 표시하는 것이 가독성이 훨씬 좋습니다.
이러한 기능은 금융 애플리케이션, 회계 프로그램, 판매 관리 시스템 등
숫자를 많이 다루는 다양한 소프트웨어에서 필수적입니다.
사용자가 직접 쉼표를 입력하게 하는 것보다 자동으로 처리해주면
입력 오류를 줄이고 사용자 경험을 크게 향상시킬 수 있습니다.
큰 숫자를 읽을 때 천 단위 쉼표는 숫자의 크기를 직관적으로 파악하는 데 도움을 줍니다. 특히 금융 데이터나 통계 정보를 다룰 때, 사용자가 숫자의 규모를 빠르게 인식할 수 있도록 도와줍니다. 또한 국제 표준에 맞는 숫자 표기법을 따르는 것은 전문적인 애플리케이션 개발에 있어 기본적인 요소입니다.
이 글에서는 PySide6를 사용하여 사용자가 숫자를 입력할 때
자동으로 천 단위 쉼표를 추가해주는 QLineEdit 위젯을 구현하는 방법을 알아보겠습니다.
PySide6와 QLineEdit 기본 이해하기
PySide6는 Qt 프레임워크의 파이썬 바인딩으로,
크로스 플랫폼 GUI 애플리케이션을 개발할 수 있게 해주는 강력한 도구입니다.
QLineEdit은 PySide6에서 제공하는 한 줄 텍스트 입력 위젯으로, 사용자로부터 텍스트 입력을 받을 수 있습니다.
QLineEdit의 주요 기능
QLineEdit은 다음과 같은 다양한 기능을 제공합니다:
- 텍스트 입력 및 편집: 사용자가 키보드로 텍스트를 입력하고 편집할 수 있습니다.
- 입력 마스크: 특정 형식(예: 전화번호, 날짜 등)에 맞는 입력만 허용할 수 있습니다.
- 유효성 검사(Validation): QValidator를 사용하여 입력값의 유효성을 검사할 수 있습니다.
- 이벤트 처리: textChanged, editingFinished 등의 시그널을 통해 다양한 이벤트를 처리할 수 있습니다.
- 스타일 및 모양 설정: 테두리, 배경색, 글꼴 등을 설정할 수 있습니다.
기본 QLineEdit 설정하기
먼저 기본적인 QLineEdit을 설정하는 코드를 살펴보겠습니다:
import sys
from PySide6.QtWidgets import QApplication, QWidget
from line_edit_test_ui import Ui_Form
class MyWidget(QWidget):
def __init__(self):
super().__init__()
# UI 설정
self.ui = Ui_Form()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec())
위 코드는 Qt Designer로 만든 UI 파일을 불러와 기본적인 위젯을 설정하는 코드입니다.
이제 이 기본 코드에 천 단위 쉼표 자동 추가 기능을 구현해 보겠습니다.
입력 제한 설정: 숫자만 입력받기
천 단위 쉼표 자동 추가 기능을 구현하기 전에,
먼저 QLineEdit에 숫자만 입력할 수 있도록 제한해야 합니다.
이를 위해 PySide6의 QRegularExpressionValidator를 사용하겠습니다.
정규 표현식 Validator 설정하기
rx = QRegularExpression("^[0-9,]*$")
validator = QRegularExpressionValidator(rx)
self.ui.lineEdit.setValidator(validator)
위 코드에서 사용한 정규 표현식 "^[0-9,]*$"
는 다음을 의미합니다:
^
: 문자열의 시작[0-9,]
: 숫자(0-9)와 쉼표(,)만 허용*
: 앞의 패턴이 0번 이상 반복될 수 있음$
: 문자열의 끝
이 정규 표현식은 숫자와 쉼표만 입력할 수 있도록 제한합니다.
쉼표를 허용하는 이유는 우리가 자동으로 쉼표를 추가할 것이기 때문입니다.
정규 표현식(Regular Expression)은 문자열의 패턴을 정의하는 강력한 도구입니다. 여기서는 간단히 숫자와 쉼표만 허용하는 패턴을 사용했지만, 정규 표현식을 더 복잡하게 구성하여 다양한 입력 형식(예: 이메일, 전화번호, 날짜 등)을 검증할 수 있습니다. 정규 표현식에 대해 더 알고 싶다면 온라인 정규 표현식 테스트 도구를 활용해 보세요.
천 단위 쉼표 자동 추가 기능 구현
이제 사용자가 숫자를 입력할 때마다 천 단위로 쉼표를 자동으로 추가하는 기능을 구현해 보겠습니다.
이를 위해 QLineEdit의 textChanged 시그널에 연결할 함수를 작성합니다.
textChanged 시그널 연결하기
self.ui.lineEdit.textChanged.connect(self.format_number)
위 코드는 QLineEdit의 텍스트가 변경될 때마다 format_number 함수를 호출하도록 설정합니다.
format_number 함수 구현하기
def format_number(self, text):
"""텍스트가 변경될 때 호출되어 1000단위 쉼표를 추가합니다."""
if not text:
return
# 현재 커서 위치 저장
cursor_pos = self.ui.lineEdit.cursorPosition()
# 쉼표 제거
text_without_commas = text.replace(',', '')
# 숫자가 아닌 문자가 있으면 처리하지 않음
if not text_without_commas.isdigit() and text_without_commas:
return
# 쉼표 추가 전 텍스트 길이
old_len = len(text)
# 1000단위 쉼표 추가
if text_without_commas:
number = int(text_without_commas)
formatted_text = f"{number:,}"
# 텍스트 변경 시그널 일시 차단
self.ui.lineEdit.blockSignals(True)
self.ui.lineEdit.setText(formatted_text)
self.ui.lineEdit.blockSignals(False)
# 새 텍스트 길이
new_len = len(formatted_text)
# 커서 위치 조정 (쉼표가 추가되었을 때 커서 위치 유지)
diff = new_len - old_len
self.ui.lineEdit.setCursorPosition(cursor_pos + diff)
위 함수는 다음과 같은 단계로 천 단위 쉼표를 자동으로 추가합니다:
- 입력된 텍스트가 비어있는지 확인합니다.
- 현재 커서 위치를 저장합니다.
- 입력된 텍스트에서 모든 쉼표를 제거합니다.
- 쉼표가 제거된 텍스트가 숫자인지 확인합니다.
- 숫자라면, 천 단위 쉼표를 추가한 새 텍스트를 생성합니다.
- QLineEdit의 텍스트를 새 텍스트로 설정합니다.
- 커서 위치를 적절히 조정합니다.
blockSignals(True)
를 호출하여 시그널을 일시적으로 차단하는 것은 매우 중요합니다. 이렇게 하지 않으면 setText()
를 호출할 때 다시 textChanged
시그널이 발생하여 무한 루프에 빠질 수 있습니다. 작업이 완료된 후에는 반드시 blockSignals(False)
를 호출하여 시그널을 다시 활성화해야 합니다.
커서 위치 유지하기
천 단위 쉼표 자동 추가 기능을 구현할 때 가장 까다로운 부분 중 하나는
사용자의 커서 위치를 적절하게 유지하는 것입니다.
사용자가 숫자를 입력하면 쉼표가 추가되면서 텍스트의 길이가 변하게 되고,
이에 따라 커서 위치도 조정해야 합니다.
커서 위치 조정 로직
# 쉼표 추가 전 텍스트 길이
old_len = len(text)
# ... 쉼표 추가 작업 ...
# 새 텍스트 길이
new_len = len(formatted_text)
# 커서 위치 조정 (쉼표가 추가되었을 때 커서 위치 유지)
diff = new_len - old_len
self.ui.lineEdit.setCursorPosition(cursor_pos + diff)
위 코드에서는 다음과 같은 방식으로 커서 위치를 조정합니다:
- 쉼표 추가 전 텍스트의 길이를 저장합니다.
- 쉼표가 추가된 후 텍스트의 길이를 계산합니다.
- 두 길이의 차이를 계산합니다.
- 원래 커서 위치에 이 차이를 더하여 새 커서 위치를 설정합니다.
이렇게 하면 사용자가 숫자를 입력할 때 커서가 갑자기 다른 위치로 이동하는 불편함 없이 자연스럽게 천 단위 쉼표가 추가됩니다.
커서 위치 관리는 사용자 경험에 큰 영향을 미칩니다. 사용자가 입력하는 동안 커서가 예상치 못한 위치로 이동하면 혼란스럽고 불편함을 느낄 수 있습니다. 특히 숫자 입력 필드에서는 이러한 세부 사항에 주의를 기울여 사용자가 자연스럽게 입력할 수 있도록 해야 합니다.
포커스 이벤트 처리하기
사용자가 QLineEdit에서 포커스를 잃을 때(예: 다른 위젯을 클릭할 때)
최종적으로 형식을 맞추는 것이 좋습니다.
이를 위해 QLineEdit의 focusOutEvent를 오버라이드하여 처리합니다.
focusOutEvent 오버라이드하기
# 포커스 이벤트 연결
self.ui.lineEdit.focusOutEvent = self.on_focus_out
def on_focus_out(self, event):
"""포커스를 잃을 때 호출되어 최종적으로 형식을 맞춥니다."""
text = self.ui.lineEdit.text()
if text:
# 쉼표 제거
text_without_commas = text.replace(',', '')
if text_without_commas:
# 숫자로 변환 후 다시 포맷팅
number = int(text_without_commas)
formatted_text = f"{number:,}"
self.ui.lineEdit.setText(formatted_text)
# 기본 이벤트 처리
super(MyWidget, self).focusOutEvent(event)
위 코드는 다음과 같은 작업을 수행합니다:
- QLineEdit의 focusOutEvent를 우리가 정의한 on_focus_out 함수로 대체합니다.
- 포커스를 잃을 때 현재 텍스트를 가져옵니다.
- 텍스트에서 쉼표를 제거합니다.
- 숫자로 변환한 후 다시 천 단위 쉼표를 추가합니다.
- 기본 focusOutEvent를 호출하여 원래의 이벤트 처리를 수행합니다.
이 기능은 사용자가 입력을 완료하고 다른 위젯으로 이동할 때 최종적으로 형식을 정리하는 데 유용합니다.
전체 코드 분석 및 활용 방법
이제 전체 코드를 살펴보고 어떻게 활용할 수 있는지 알아보겠습니다.
# -*- coding: utf-8 -*-
import sys
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QRegularExpressionValidator
from PySide6.QtCore import QRegularExpression
from line_edit_test_ui import Ui_Form
class MyWidget(QWidget):
def __init__(self):
super().__init__()
# UI 설정
self.ui = Ui_Form()
self.ui.setupUi(self)
# 숫자만 입력 가능하도록 validator 설정
# 쉼표를 포함한 숫자 패턴을 허용 (쉼표는 자동으로 추가되기 때문)
rx = QRegularExpression("^[0-9,]*$")
validator = QRegularExpressionValidator(rx)
self.ui.lineEdit.setValidator(validator)
# 텍스트 변경 시그널 연결
self.ui.lineEdit.textChanged.connect(self.format_number)
# 포커스 이벤트 연결
self.ui.lineEdit.focusOutEvent = self.on_focus_out
def format_number(self, text):
"""텍스트가 변경될 때 호출되어 1000단위 쉼표를 추가합니다."""
if not text:
return
# 현재 커서 위치 저장
cursor_pos = self.ui.lineEdit.cursorPosition()
# 쉼표 제거
text_without_commas = text.replace(',', '')
# 숫자가 아닌 문자가 있으면 처리하지 않음
if not text_without_commas.isdigit() and text_without_commas:
return
# 쉼표 추가 전 텍스트 길이
old_len = len(text)
# 1000단위 쉼표 추가
if text_without_commas:
number = int(text_without_commas)
formatted_text = f"{number:,}"
# 텍스트 변경 시그널 일시 차단
self.ui.lineEdit.blockSignals(True)
self.ui.lineEdit.setText(formatted_text)
self.ui.lineEdit.blockSignals(False)
# 새 텍스트 길이
new_len = len(formatted_text)
# 커서 위치 조정 (쉼표가 추가되었을 때 커서 위치 유지)
diff = new_len - old_len
self.ui.lineEdit.setCursorPosition(cursor_pos + diff)
def on_focus_out(self, event):
"""포커스를 잃을 때 호출되어 최종적으로 형식을 맞춥니다."""
text = self.ui.lineEdit.text()
if text:
# 쉼표 제거
text_without_commas = text.replace(',', '')
if text_without_commas:
# 숫자로 변환 후 다시 포맷팅
number = int(text_without_commas)
formatted_text = f"{number:,}"
self.ui.lineEdit.setText(formatted_text)
# 기본 이벤트 처리
super(MyWidget, self).focusOutEvent(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec())
위 코드는 PySide6를 사용하여 천 단위 쉼표 자동 추가 기능을 구현한 전체 예제입니다.
활용 방법
이 코드를 활용하는 방법은 다음과 같습니다:
- 기존 프로젝트에 통합: 위 코드의 format_number와 on_focus_out 함수를 기존 프로젝트에 추가하고, QLineEdit 위젯에 연결합니다.
- 커스텀 위젯 생성: QLineEdit을 상속받아 천 단위 쉼표 자동 추가 기능을 가진 커스텀 위젯을 만들어 재사용할 수 있습니다.
- 기능 확장: 필요에 따라 소수점 처리, 통화 기호 추가 등의 기능을 추가할 수 있습니다.
커스텀 위젯 예제
다음은 QLineEdit을 상속받아 만든 커스텀 위젯 예제입니다:
from PySide6.QtWidgets import QLineEdit
from PySide6.QtGui import QRegularExpressionValidator
from PySide6.QtCore import QRegularExpression
class CommaNumberLineEdit(QLineEdit):
"""천 단위 쉼표가 자동으로 추가되는 QLineEdit 커스텀 위젯"""
def __init__(self, parent=None):
super().__init__(parent)
# 숫자와 쉼표만 입력 가능하도록 설정
rx = QRegularExpression("^[0-9,]*$")
validator = QRegularExpressionValidator(rx)
self.setValidator(validator)
# 텍스트 변경 시그널 연결
self.textChanged.connect(self.format_number)
def format_number(self, text):
"""텍스트가 변경될 때 호출되어 1000단위 쉼표를 추가합니다."""
if not text:
return
# 현재 커서 위치 저장
cursor_pos = self.cursorPosition()
# 쉼표 제거
text_without_commas = text.replace(',', '')
# 숫자가 아닌 문자가 있으면 처리하지 않음
if not text_without_commas.isdigit() and text_without_commas:
return
# 쉼표 추가 전 텍스트 길이
old_len = len(text)
# 1000단위 쉼표 추가
if text_without_commas:
number = int(text_without_commas)
formatted_text = f"{number:,}"
# 텍스트 변경 시그널 일시 차단
self.blockSignals(True)
self.setText(formatted_text)
self.blockSignals(False)
# 새 텍스트 길이
new_len = len(formatted_text)
# 커서 위치 조정 (쉼표가 추가되었을 때 커서 위치 유지)
diff = new_len - old_len
self.setCursorPosition(cursor_pos + diff)
def focusOutEvent(self, event):
"""포커스를 잃을 때 호출되어 최종적으로 형식을 맞춥니다."""
text = self.text()
if text:
# 쉼표 제거
text_without_commas = text.replace(',', '')
if text_without_commas:
# 숫자로 변환 후 다시 포맷팅
number = int(text_without_commas)
formatted_text = f"{number:,}"
self.setText(formatted_text)
# 기본 이벤트 처리
super().focusOutEvent(event)
def get_value(self):
"""쉼표가 제거된 숫자 값을 반환합니다."""
text = self.text()
if not text:
return 0
text_without_commas = text.replace(',', '')
return int(text_without_commas) if text_without_commas else 0
이 커스텀 위젯은 다음과 같이 사용할 수 있습니다:
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel
import sys
class TestWidget(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("금액 입력:")
self.amount_edit = CommaNumberLineEdit()
layout.addWidget(label)
layout.addWidget(self.amount_edit)
self.setLayout(layout)
self.setWindowTitle("천 단위 쉼표 자동 추가 예제")
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = TestWidget()
widget.show()
sys.exit(app.exec())
이렇게 만든 커스텀 위젯은 프로젝트 내 여러 곳에서 재사용할 수 있어 코드 중복을 줄이고 유지보수를 용이하게 합니다.
- 소수점 지원: 정수뿐만 아니라 소수점이 있는 실수도 처리할 수 있도록 확장할 수 있습니다.
- 통화 기호 추가: 원화(₩), 달러($) 등의 통화 기호를 자동으로 추가할 수 있습니다.
- 최대값 제한: 입력할 수 있는 최대값을 설정하여 유효한 범위 내의 숫자만 입력받을 수 있습니다.
- 음수 지원: 필요에 따라 음수 입력을 허용하고 처리할 수 있습니다.
결론
이 글에서는 PySide6를 사용하여 QLineEdit에 천 단위 쉼표 자동 추가 기능을 구현하는 방법을 알아보았습니다.
주요 내용을 요약하면 다음과 같습니다:
- QRegularExpressionValidator를 사용하여 입력을 숫자와 쉼표로 제한했습니다.
- textChanged 시그널을 연결하여 텍스트가 변경될 때마다 천 단위 쉼표를 자동으로 추가했습니다.
- 커서 위치를 적절히 조정하여 사용자 경험을 향상시켰습니다.
- focusOutEvent를 오버라이드하여 포커스를 잃을 때 최종적으로 형식을 맞추도록 했습니다.
- QLineEdit을 상속받아 재사용 가능한 커스텀 위젯을 만들었습니다.
이러한 기능은 금융 애플리케이션, 회계 프로그램, 판매 관리 시스템 등
숫자 입력이 많은 애플리케이션에서 사용자 경험을 크게 향상시킬 수 있습니다.
또한 이 기본 코드를 확장하여 소수점 처리, 통화 기호 추가, 최대값 제한 등 다양한 기능을 추가할 수 있습니다.
PySide6의 강력한 기능과 파이썬의 유연성을 활용하면 사용자 친화적인 GUI 애플리케이션을 쉽게 개발할 수 있습니다.
[ 파이썬 관련 블로그 글 목록 ]
파이썬(Python) 블로그 목록
'PYTHON GUI' 카테고리의 다른 글
[ PySide6 ] QHeaderView : 테이블 헤더 커스터마이징 방법 (0) | 2025.05.27 |
---|---|
[ Pyside6 ] QStandardItemModel로 데이터 테이블 쉽게 만들기 (0) | 2025.05.26 |
[ PySide6 ] QTableWidget 열 너비 자동 조절 후 마우스로 수동 조절하는 방법 (0) | 2025.05.24 |
[ PySide6 ] QTableWidget에 체크박스 추가하는 방법 (1) | 2025.05.22 |
[ PySide6 ] QTableWidget 메서드 기본 가이드: 테이블 위젯 기본기 익히기 (2) | 2025.05.21 |