PyQt개발강좌, 데이터베이스 연동, SQLite와 MySQL을 이용한 데이터베이스 연결

PyQt는 Python을 사용하여 매우 강력하고 사용자 친화적인 GUI 애플리케이션을 개발할 수 있는 프레임워크입니다.
본 강좌에서는 PyQt를 사용하여 SQLite 및 MySQL 데이터베이스에 연결하고, 데이터를 조회하고, 추가, 수정 및 삭제하는 방법에 대해 알아보겠습니다.

목차

1. PyQt 소개

PyQt는 Qt 라이브러리의 Python 바인딩으로, 응용 프로그램 및 툴을 쉽고 빠르게 구축할 수 있는 도구입니다.
PyQt는 다양한 GUI 구성 요소(위젯)를 제공하여 직관적인 사용자 인터페이스를 제공하며,
다양한 플랫폼에서 동작합니다. PyQt를 사용하면 복잡한 GUI를 쉽게 설계하고,
사용자와 상호작용할 수 있는 풍부한 경험을 제공할 수 있습니다.

2. 데이터베이스 기초

데이터베이스는 데이터를 구조적으로 저장하고 관리할 수 있는 시스템입니다.
여기서는 두 가지 데이터베이스 시스템인 SQLite와 MySQL을 사용할 것입니다.
이 둘은 각각의 특징과 장점이 있으며, 애플리케이션의 요구 사항에 따라 선택할 수 있습니다.

2.1 SQLite

SQLite는 파일 기반의 관계형 데이터베이스입니다.
코딩 및 구현이 매우 간단하여, 소규모 프로젝트에 적합합니다.
SQLite는 서버가 필요 없으며, 데이터베이스가 하나의 파일로 저장되어 있어 이동이 용이합니다.

2.2 MySQL

MySQL은 보다 복잡한 웹 애플리케이션에 적합한 서버 기반의 관계형 데이터베이스 관리 시스템입니다.
데이터베이스 서버를 제공하여 네트워크를 통해 여러 클라이언트가 데이터에 접근할 수 있도록 합니다.
대규모 데이터 처리가 필요할 때 유용하게 사용할 수 있습니다.

3. SQLite와 PyQt 연동

SQLite와 PyQt를 통합하여 간단한 데이터베이스 애플리케이션을 만들어보겠습니다.
여기서는 데이터를 추가하고 조회하는 기본적인 예제 코드를 작성합니다.

3.1 SQLite 데이터베이스 설정

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QListWidget, QLabel
import sqlite3

class App(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.create_connection()

    def initUI(self):
        self.setWindowTitle('SQLite와 PyQt 연동')
        self.setGeometry(100, 100, 400, 400)
        
        self.layout = QVBoxLayout()
        
        self.label = QLabel('이름 입력:')
        self.layout.addWidget(self.label)
        
        self.input_name = QLineEdit(self)
        self.layout.addWidget(self.input_name)
        
        self.add_button = QPushButton('추가', self)
        self.add_button.clicked.connect(self.add_data)
        self.layout.addWidget(self.add_button)
        
        self.list_widget = QListWidget(self)
        self.layout.addWidget(self.list_widget)
        
        self.setLayout(self.layout)
        
    def create_connection(self):
        self.connection = sqlite3.connect('test.db')
        self.cursor = self.connection.cursor()
        self.cursor.execute('CREATE TABLE IF NOT EXISTS users (name TEXT)')
        
    def add_data(self):
        name = self.input_name.text()
        if name:
            self.cursor.execute('INSERT INTO users (name) VALUES (?)', (name,))
            self.connection.commit()
            self.input_name.clear()
            self.load_data()

    def load_data(self):
        self.list_widget.clear()
        self.cursor.execute('SELECT name FROM users')
        rows = self.cursor.fetchall()
        for row in rows:
            self.list_widget.addItem(row[0])
        
    def closeEvent(self, event):
        self.connection.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

3.2 코드 설명

위의 코드는 PyQt를 사용하여 SQLite 데이터베이스와 상호작용하는 간단한 애플리케이션입니다.
사용자는 입력 필드에 이름을 입력하고 “추가” 버튼을 클릭하여 데이터를
데이터베이스에 추가할 수 있고, 저장된 데이터를 리스트로 보여줍니다.
주요 기능은 다음과 같습니다.

  • 생성자: 데이터베이스 연결 및 UI 초기화를 수행합니다.
  • initUI: 기본적인 UI 레이아웃을 설정합니다.
  • create_connection: SQLite 데이터베이스에 연결하고 테이블을 생성합니다.
  • add_data: 입력한 이름을 데이터베이스에 추가하고 리스트를 업데이트합니다.
  • load_data: 데이터베이스에서 모든 이름을 가져와 리스트 위젯에 표시합니다.

4. MySQL과 PyQt 연동

이번 섹션에서는 MySQL과 PyQt를 연동하는 방법을 알아보겠습니다.
MySQL 데이터베이스에 연결하기 위해 mysql-connector-python 패키지를 사용합니다.
아래의 코드를 참고하여 MySQL 데이터베이스에 연결하고 데이터를 처리하는 예제를 만들어 보겠습니다.

4.1 MySQL 데이터베이스 설정

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QListWidget, QLabel
import mysql.connector

class App(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.create_connection()

    def initUI(self):
        self.setWindowTitle('MySQL과 PyQt 연동')
        self.setGeometry(100, 100, 400, 400)
        
        self.layout = QVBoxLayout()
        
        self.label = QLabel('이름 입력:')
        self.layout.addWidget(self.label)
        
        self.input_name = QLineEdit(self)
        self.layout.addWidget(self.input_name)
        
        self.add_button = QPushButton('추가', self)
        self.add_button.clicked.connect(self.add_data)
        self.layout.addWidget(self.add_button)
        
        self.list_widget = QListWidget(self)
        self.layout.addWidget(self.list_widget)
        
        self.setLayout(self.layout)
        
    def create_connection(self):
        self.connection = mysql.connector.connect(
            host='localhost',
            user='your_username',
            password='your_password',
            database='your_database'
        )
        self.cursor = self.connection.cursor()
        self.cursor.execute('CREATE TABLE IF NOT EXISTS users (name VARCHAR(255))')

    def add_data(self):
        name = self.input_name.text()
        if name:
            self.cursor.execute('INSERT INTO users (name) VALUES (%s)', (name,))
            self.connection.commit()
            self.input_name.clear()
            self.load_data()

    def load_data(self):
        self.list_widget.clear()
        self.cursor.execute('SELECT name FROM users')
        rows = self.cursor.fetchall()
        for row in rows:
            self.list_widget.addItem(row[0])
        
    def closeEvent(self, event):
        self.connection.close()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    ex.show()
    sys.exit(app.exec_())

4.2 코드 설명

위 코드는 MySQL 데이터베이스와 상호작용하기 위한 애플리케이션입니다.
SQLite 예제와 유사하지만 MySQL에 맞게 수정되었습니다.
코드의 중요한 부분은 다음과 같습니다.

  • 생성자: MySQL 데이터베이스에 연결합니다.
  • create_connection: MySQL DB에 연결하고 테이블을 생성합니다. 사용자 이름, 비밀번호, 데이터베이스 이름을 맞게 설정해야 합니다.
  • add_data: 입력한 이름을 MySQL 데이터베이스에 추가합니다.
  • load_data: 모든 이름을 MySQL에서 가져오고 리스트 위젯에 표시합니다.

5. 결론

본 강좌에서는 PyQt를 사용하여 SQLite 및 MySQL 데이터베이스와 연결하는 방법에 대해 설명하였습니다.
PyQt의 강력한 GUI 구성 요소와 함께 데이터베이스 연동을 통해 효율적인 데이터 관리를 구현할 수 있습니다.
다양한 데이터 처리 로직을 추가하여 더욱 발전된 애플리케이션을 만들어 볼 수 있습니다.
학습한 내용을 바탕으로 자신만의 프로젝트를 시작해 보시기 바랍니다.

© 2023 PyQt 개발 강좌

PyQt개발강좌, 데이터를 위한 커스텀 필터 및 정렬 기능 구현

PyQt는 파이썬을 위한 Qt 애플리케이션 개발 프레임워크로, GUI를 신속하게 개발할 수 있게 해줍니다. 본 강좌에서는 PyQt를 사용하여 데이터를 관리하고 표시하기 위한 커스텀 필터와 정렬 기능을 어떻게 구현할 수 있는지에 대해 자세히 다룰 것입니다. 특히, QTableViewQAbstractTableModel을 활용하여 데이터의 표시, 필터링 및 정렬을 구현하는 방법에 대해 알아볼 것입니다.

1. 기본 개념

PyQt를 활용한 GUI 애플리케이션에서 데이터 관리는 매우 중요합니다. 사용자가 데이터를 쉽게 볼 수 있도록 구현하는 것뿐만 아니라, 데이터를 필터링하고 정렬할 수 있는 강력한 도구를 제공해야 합니다. 이를 위해 다음과 같은 주요 구성 요소를 사용합니다:

  • QTableView: 데이터를 테이블 형태로 표시하기 위한 위젯입니다.
  • QAbstractTableModel: 데이터의 내부 구조를 정의하며, 데이터를 표시하는 방법과 필터링 및 정렬을 관리합니다.
  • 커스텀 필터 및 정렬 기능: 사용자가 원하는 대로 데이터를 필터링하고 정렬할 수 있게 해주는 기능입니다.

2. QTableView와 QAbstractTableModel 소개

QTableView는 데이터를 테이블 형식으로 표시하는 데 사용됩니다. 데이터에 대한 다양한 조작과 표시 설정이 가능합니다. QAbstractTableModel은 데이터를 모델로 관리하는 클래스로, QTableView와 함께 사용되어야 합니다. 모델은 데이터가 어떻게 저장되고 쿼리되는지를 정의합니다.

2.1 QTableView 설정하기

먼저 간단한 PyQt 애플리케이션을 설정하고 QTableView를 사용하는 방법을 살펴보겠습니다. 아래의 코드를 확인하십시오:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QTableView
from PyQt5.QtCore import Qt, QAbstractTableModel, QVariant

class MyModel(QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data

    def rowCount(self, parent=None):
        return len(self._data)

    def columnCount(self, parent=None):
        return len(self._data[0]) if self._data else 0

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            return QVariant(self._data[index.row()][index.column()])

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return QVariant(f'Column {section + 1}')
            else:
                return QVariant(f'Row {section + 1}')
        
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = QMainWindow()
    window.setWindowTitle('QTableView 예제')

    data = [
        ['Alice', 30],
        ['Bob', 25],
        ['Charlie', 35]
    ]

    model = MyModel(data)

    table_view = QTableView()
    table_view.setModel(model)

    layout = QVBoxLayout()
    layout.addWidget(table_view)

    central_widget = QWidget()
    central_widget.setLayout(layout)
    window.setCentralWidget(central_widget)

    window.resize(400, 300)
    window.show()
    sys.exit(app.exec_())

이 코드에서는 가장 간단한 형태의 QTableViewQAbstractTableModel을 설정했습니다. MyModel 클래스를 생성하여 데이터를 보유하고, 데이터의 행과 열 개수를 정의하며, 특정 셀의 데이터를 반환하는 간단한 모델을 구현했습니다.

3. 커스텀 필터 만들기

이제 데이터를 필터링할 수 있는 기능을 추가해보겠습니다. 이를 위해 모델에 필터링 기능을 추가하고, QLineEdit를 사용하여 사용자 입력을 받을 수 있도록 할 것입니다.

3.1 필터 기능 구현

필터 기능을 구현하기 위해 모델 클래스에 필터링 로직을 추가하겠습니다. 사용자가 입력한 필터 문자열 기반으로 데이터를 필터링할 수 있도록 합니다.

class MyModel(QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data
        self._filtered_data = data

    def filterData(self, filter_string):
        self.beginResetModel()
        if filter_string:
            self._filtered_data = [row for row in self._data if filter_string.lower() in row[0].lower()]
        else:
            self._filtered_data = self._data
        self.endResetModel()

    def rowCount(self, parent=None):
        return len(self._filtered_data)

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            return QVariant(self._filtered_data[index.row()][index.column()])

여기에서 filterData 메서드는 입력된 필터 문자열을 기반으로 데이터를 필터링합니다. beginResetModelendResetModel 메서드를 사용하여 모델의 데이터가 변경되었음을 알립니다.

3.2 QLineEdit 추가하기

이제 필터를 입력할 QLineEdit를 사용자 인터페이스에 추가하고, 사용자 입력에 따라 필터를 적용할 것입니다.

from PyQt5.QtWidgets import QLineEdit

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('QTableView 필터링 예제')

        self.data = [
            ['Alice', 30],
            ['Bob', 25],
            ['Charlie', 35]
        ]

        self.model = MyModel(self.data)

        self.table_view = QTableView()
        self.table_view.setModel(self.model)

        self.filter_line_edit = QLineEdit()
        self.filter_line_edit.setPlaceholderText('이름으로 필터링...')
        self.filter_line_edit.textChanged.connect(self.onFilterChanged)

        layout = QVBoxLayout()
        layout.addWidget(self.filter_line_edit)
        layout.addWidget(self.table_view)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

    def onFilterChanged(self, text):
        self.model.filterData(text)

이 코드에서는 QLineEdit를 추가하고, 사용자가 입력하는 텍스트가 변경될 때마다 onFilterChanged 메서드를 호출하여 모델에 필터를 적용합니다.

4. 데이터 정렬 기능 구현하기

다음으로 데이터를 정렬할 수 있는 기능을 추가해보겠습니다. 사용자가 특정 열을 클릭하면 해당 열의 데이터를 정렬할 수 있도록 합니다.

4.1 정렬 기능을 위한 모델 수정

모델에 정렬 기능을 추가하기 위해 별도의 정렬 메서드를 작성하겠습니다. 이 메서드는 지정된 열을 기준으로 데이터를 오름차순 또는 내림차순으로 정렬합니다.

class MyModel(QAbstractTableModel):
    # 기존 코드...

    def sort(self, column, order):
        self.beginResetModel()
        self._filtered_data.sort(key=lambda x: x[column], reverse=(order == Qt.DescendingOrder))
        self.endResetModel()

4.2 QTableView에서 정렬 처리하기

이제 QTableView에서 열 헤더 클릭 시 정렬을 처리할 수 있도록 설정합니다.

self.table_view.setSortingEnabled(True)
self.table_view.horizontalHeader().sectionClicked.connect(self.onHeaderClicked)

def onHeaderClicked(self, index):
    current_order = self.table_view.horizontalHeader().sortIndicatorOrder()
    new_order = Qt.AscendingOrder if current_order == Qt.DescendingOrder else Qt.DescendingOrder
    self.model.sort(index, new_order)

이 코드는 사용자가 열 헤더를 클릭할 때마다 onHeaderClicked 메서드를 호출하여 정렬을 수행합니다.

5. 전체 코드

이제 모든 구성 요소를 통합한 전체 코드를 볼 수 있습니다.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QTableView, QLineEdit
from PyQt5.QtCore import Qt, QAbstractTableModel, QVariant

class MyModel(QAbstractTableModel):
    def __init__(self, data):
        super().__init__()
        self._data = data
        self._filtered_data = data

    def filterData(self, filter_string):
        self.beginResetModel()
        if filter_string:
            self._filtered_data = [row for row in self._data if filter_string.lower() in row[0].lower()]
        else:
            self._filtered_data = self._data
        self.endResetModel()

    def sort(self, column, order):
        self.beginResetModel()
        self._filtered_data.sort(key=lambda x: x[column], reverse=(order == Qt.DescendingOrder))
        self.endResetModel()

    def rowCount(self, parent=None):
        return len(self._filtered_data)

    def columnCount(self, parent=None):
        return len(self._filtered_data[0]) if self._filtered_data else 0

    def data(self, index, role=Qt.DisplayRole):
        if role == Qt.DisplayRole:
            return QVariant(self._filtered_data[index.row()][index.column()])

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                return QVariant(f'Column {section + 1}')
            else:
                return QVariant(f'Row {section + 1}')

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QTableView 필터링 및 정렬 예제')

        self.data = [
            ['Alice', 30],
            ['Bob', 25],
            ['Charlie', 35]
        ]
        self.model = MyModel(self.data)

        self.table_view = QTableView()
        self.table_view.setModel(self.model)
        self.table_view.setSortingEnabled(True)
        self.table_view.horizontalHeader().sectionClicked.connect(self.onHeaderClicked)

        self.filter_line_edit = QLineEdit()
        self.filter_line_edit.setPlaceholderText('이름으로 필터링...')
        self.filter_line_edit.textChanged.connect(self.onFilterChanged)

        layout = QVBoxLayout()
        layout.addWidget(self.filter_line_edit)
        layout.addWidget(self.table_view)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

    def onFilterChanged(self, text):
        self.model.filterData(text)

    def onHeaderClicked(self, index):
        current_order = self.table_view.horizontalHeader().sortIndicatorOrder()
        new_order = Qt.AscendingOrder if current_order == Qt.DescendingOrder else Qt.DescendingOrder
        self.model.sort(index, new_order)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.resize(400, 300)
    window.show()
    sys.exit(app.exec_())

6. 마무리

본 강좌에서는 PyQt를 사용하여 커스텀 필터와 정렬 기능을 포함한 데이터 테이블을 구현하는 방법에 대해 설명하였습니다. QTableViewQAbstractTableModel을 활용하여 유연하고 강력한 데이터 관리를 할 수 있습니다. 이 예제를 기반으로 다양한 기능을 추가하고 지속적으로 발전시켜 나가길 바랍니다.

앞으로도 PyQt에 대한 다양한 강좌를 연구하고, 기술을 확장해 나가기를 바랍니다. 질문이나 코멘트가 있다면 언제든지 남겨주세요!

PyQt개발강좌, QTabWidget을 활용한 다중 탭 구성

PyQt는 Python에서 Qt 프레임워크를 사용하여 GUI 애플리케이션을 개발할 수 있게 해주는 강력한 라이브러리입니다. 다양한 위젯을 제공하여 복잡한 사용자 인터페이스를 쉽게 구성할 수 있습니다. 그 중에서 QTabWidget은 여러 페이지를 탭의 형태로 구성할 수 있는 유용한 위젯입니다. 이 글에서는 QTabWidget의 기본 개념과 사용법에 대해 자세히 설명하고, 실제 예제 코드를 통해 다중 탭을 구현하는 방법을 알아보겠습니다.

QTabWidget 개요

QTabWidget은 여러 개의 탭을 생성하고 각 탭마다 다른 위젯이나 내용을 표시할 수 있는 컨테이너입니다. 사용자는 탭을 클릭하여 다른 페이지로 전환할 수 있으며, 이는 사용자에게 친숙한 탐색 경험을 제공합니다. 일반적인 사용 사례로는 다중 설정, 문서 편집기, 정보 표시 등 다양한 사용자 인터페이스를 구성할 수 있습니다.

QTabWidget의 기본 구성 요소

  • 탭 (Tab): 각 탭은의 글자가 있으며, 이를 통해 사용자는 해당 페이지를 식별하고 선택할 수 있습니다.
  • 페이지 (Page): 각 탭은 특정 위젯이나 레이아웃을 포함하며, 사용자가 선택한 탭에 따라 표시됩니다.
  • 신호 (Signals): 사용자가 탭을 클릭하면 신호가 발생하고, 이를 통해 특정 기능을 실행할 수 있습니다.

QTabWidget 사용법

QTabWidget은 PyQt에서 사용하는 일반적인 위젯 방법과 마찬가지로, 객체 생성 후 위젯을 추가하고 설정할 수 있습니다. 기본적인 사용 방법은 다음과 같습니다:


from PyQt5.QtWidgets import QApplication, QTabWidget, QWidget, QVBoxLayout, QLabel

class MyApp(QTabWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QTabWidget 예제')
        
        # 첫 번째 탭 생성
        tab1 = QWidget()
        tab1_layout = QVBoxLayout()
        tab1_layout.addWidget(QLabel('첫 번째 탭 내용입니다.'))
        tab1.setLayout(tab1_layout)

        # 두 번째 탭 생성
        tab2 = QWidget()
        tab2_layout = QVBoxLayout()
        tab2_layout.addWidget(QLabel('두 번째 탭 내용입니다.'))
        tab2.setLayout(tab2_layout)

        # 탭에 페이지 추가
        self.addTab(tab1, '탭 1')
        self.addTab(tab2, '탭 2')

if __name__ == '__main__':
    app = QApplication([])
    window = MyApp()
    window.show()
    app.exec_()
    

예제 코드 설명

위의 예제에서 다음과 같은 작업을 수행했습니다:

  1. QApplication 인스턴스 생성: QApplication 객체를 생성하여 PyQt의 이벤트 루프를 시작합니다.
  2. QTabWidget 서브 클래스 정의: MyApp 클래스를 정의하고 QTabWidget을 상속받습니다.
  3. 탭에서 사용할 위젯 생성: 각 탭에 대해 QWidget과 QVBoxLayout을 생성하여 레이아웃을 설정합니다.
  4. 탭 추가: addTab 메서드를 사용하여 각 위젯을 탭에 추가합니다.

고급 기능

QTabWidget은 추가적인 기능을 통해 사용자에게 더욱 풍부한 경험을 제공합니다:

  • 아이콘 추가: 각 탭에 아이콘을 추가할 수 있어 더 직관적인 인터페이스를 제공할 수 있습니다.
  • 탭 순서 변경: 사용자가 드래그 앤 드롭으로 탭의 순서를 변경할 수 있도록 설정할 수 있습니다.
  • 신호 처리: 탭의 변경 이벤트를 처리하여 특정 작업을 수행할 수 있습니다.

아이콘 추가 예제


from PyQt5.QtGui import QIcon

# 아이콘 설정
self.addTab(tab1, QIcon('icon1.png'), '탭 1')
self.addTab(tab2, QIcon('icon2.png'), '탭 2')
    

탭 변경 이벤트 처리 예제


self.currentChanged.connect(self.on_tab_changed)

def on_tab_changed(self, index):
    print(f'현재 선택된 탭: {index}')
    

실전 예제: 다중 탭 구성

이제 실제로 여러 탭을 가지고 있으면서, 각 탭에 다양한 위젯을 배치하는 예제를 살펴보겠습니다. 이번 예제에서는 설정 페이지와 정보 페이지 두 개의 탭을 가진 애플리케이션을 구현해보겠습니다.


from PyQt5.QtWidgets import QApplication, QTabWidget, QWidget, QVBoxLayout, QLabel, QPushButton, QLineEdit, QFormLayout

class SettingsTab(QWidget):
    def __init__(self):
        super().__init__()
        layout = QFormLayout()
        self.username = QLineEdit()
        self.password = QLineEdit()
        layout.addRow('사용자 이름:', self.username)
        layout.addRow('비밀번호:', self.password)
        self.setLayout(layout)

class InfoTab(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        layout.addWidget(QLabel('사용 방법: 아래의 설정을 입력하세요.'))
        layout.addWidget(QLabel('설정이 완료되면, 저장 버튼을 클릭하세요.'))
        save_button = QPushButton('설정 저장')
        layout.addWidget(save_button)
        self.setLayout(layout)

class MyApp(QTabWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('다중 탭 예제')

        self.addTab(SettingsTab(), '설정')
        self.addTab(InfoTab(), '정보')

if __name__ == '__main__':
    app = QApplication([])
    window = MyApp()
    window.show()
    app.exec_()
    

예제 코드 설명

위의 예제에서는 두 가지의 탭을 구축했습니다:

  • SettingsTab: 사용자 이름과 비밀번호를 입력 받는 폼 레이아웃을 가지고 있습니다.
  • InfoTab: 사용 방법을 설명하고 설정 저장 버튼을 배치합니다.

타입과 레이아웃을 다르게 구성하여 정보와 설정을 효과적으로 분리할 수 있습니다.

마무리

QTabWidget은 PyQt 애플리케이션에서 다중 페이지를 효과적으로 관리할 수 있는 유용한 도구입니다. 본 글에서는 QTabWidget의 기본 개념 및 사용법, 아이콘 추가, 이벤트 처리, 그리고 실전 예제를 통해 다중 탭 구현 방법을 살펴보았습니다. QTabWidget을 활용하여 사용자가 보다 쉽게 정보를 찾고 사용할 수 있는 UI를 만들어 보세요. 더 많은 PyQt의 기능을 습득하고 다양한 애플리케이션을 제작하는 데 도움이 되길 바랍니다.

PyQt개발강좌, 속성 편집 기능 구현하기 (숫자, 텍스트, 색상 선택 등)

본 글에서는 PyQt를 사용하여 사용자 인터페이스 내에서 속성을 편집할 수 있는 기능을 구현하는 방법을 자세히 설명합니다. 이 강좌에서는 숫자, 텍스트, 색상 선택 등의 다양한 속성을 관리하게 됩니다.

1. PyQt 소개

PyQt는 Python 프로그래밍 언어를 위한 Qt 애플리케이션 프레임워크를 포괄적으로 감쌉니다. 이는 GUI(그래픽 사용자 인터페이스) 애플리케이션을 개발할 때 널리 사용되는 강력한 툴킷입니다. PyQt를 사용하면 C++로 툴킷을 사용할 때와 유사한 방식으로 애플리케이션을 개발할 수 있습니다.

2. 속성 편집기의 필요성

속성 편집기는 일반적으로 그래픽 소프트웨어나 복잡한 사용자 정의 애플리케이션에서 사용자로 하여금 개별 요소의 다양한 속성을 조정할 수 있게 합니다. 예를 들어, 그래픽 디자인 소프트웨어에서는 색상, 텍스트 크기, 도형 크기 등을 조정할 때 속성 편집기를 사용합니다.

3. PyQt 설치

PyQt5는 pip를 사용하여 간단히 설치할 수 있습니다. 다음 명령어를 실행하여 PyQt5를 설치합니다:

pip install PyQt5

4. 기본 애플리케이션 설계

속성 편집기를 구현하기 위해 먼저 PyQt 애플리케이션의 기본 구조를 설정해야 합니다. 아래 코드는 PyQt 애플리케이션의 기본 뼈대를 보여줍니다.


import sys
from PyQt5.QtWidgets import QApplication, QMainWindow

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('속성 편집기')
        self.setGeometry(100, 100, 600, 400)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())
    

위 코드를 실행하면 기본 창이 표시됩니다.

5. 속성 편집 GUI 구성

속성 편집기를 만들기 위해 UI를 구성해야 합니다. 일반적으로 QLineEdit, QSpinBox, QComboBox, QColorDialog와 같은 위젯을 사용하여 속성을 편집할 수 있도록 합니다.

5.1 텍스트 속성 편집

텍스트 속성을 편집하기 위한 QLineEdit를 추가합니다. 사용자는 이 입력 필드에 텍스트를 직접 입력하고 그에 따라 결과가 변경될 수 있습니다.


from PyQt5.QtWidgets import QLineEdit, QLabel, QVBoxLayout, QWidget

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('속성 편집기')
        self.setGeometry(100, 100, 600, 400)

        self.initUI()

    def initUI(self):
        self.label = QLabel('입력한 텍스트:', self)
        self.lineEdit = QLineEdit(self)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.lineEdit)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.lineEdit.textChanged.connect(self.updateLabel)

    def updateLabel(self, text):
        self.label.setText(f'입력한 텍스트: {text}')
    

5.2 숫자 속성 편집

숫자 속성을 편집하기 위해 QSpinBox를 사용할 수 있습니다. 이 위젯은 사용자가 숫자를 직접 입력하거나 스핀 박스를 사용하여 숫자를 조정할 수 있도록 합니다.


from PyQt5.QtWidgets import QSpinBox

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('속성 편집기')
        self.setGeometry(100, 100, 600, 400)

        self.initUI()

    def initUI(self):
        self.label = QLabel('수치:', self)
        self.spinBox = QSpinBox(self)
        self.spinBox.setMinimum(0)
        self.spinBox.setMaximum(100)

        layout = QVBoxLayout()
        layout.addWidget(self.label)
        layout.addWidget(self.spinBox)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.spinBox.valueChanged.connect(self.updateLabel)

    def updateLabel(self, value):
        self.label.setText(f'수치: {value}')
    

5.3 색상 선택 기능

색상 선택 기능을 추가하기 위해 QColorDialog를 사용할 수 있습니다. 사용자는 이 대화 상자를 통해 색상을 선택하고, 선택한 색상에 따라 배경 색상을 변경할 수 있습니다.


from PyQt5.QtWidgets import QPushButton, QColorDialog

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('속성 편집기')
        self.setGeometry(100, 100, 600, 400)

        self.initUI()

    def initUI(self):
        self.button = QPushButton('색상 선택', self)
        self.button.clicked.connect(self.selectColor)

        layout = QVBoxLayout()
        layout.addWidget(self.button)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

    def selectColor(self):
        color = QColorDialog.getColor()
        if color.isValid():
            self.setStyleSheet(f"background-color: {color.name()};")
    

6. 종합 예제

위에서 설명한 모든 기능을 통합한 속성 편집기를 구현해 보겠습니다. 다음은 텍스트, 숫자, 색상을 모두 편집할 수 있는 속성 편집기 코드입니다.


import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QLabel, QVBoxLayout, QWidget, QSpinBox, QPushButton, QColorDialog

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('속성 편집기')
        self.setGeometry(100, 100, 600, 400)

        self.initUI()

    def initUI(self):
        self.labelText = QLabel('입력한 텍스트:', self)
        self.lineEdit = QLineEdit(self)

        self.labelSpin = QLabel('수치:', self)
        self.spinBox = QSpinBox(self)
        self.spinBox.setMinimum(0)
        self.spinBox.setMaximum(100)

        self.buttonColor = QPushButton('색상 선택', self)
        self.buttonColor.clicked.connect(self.selectColor)

        layout = QVBoxLayout()
        layout.addWidget(self.labelText)
        layout.addWidget(self.lineEdit)
        layout.addWidget(self.labelSpin)
        layout.addWidget(self.spinBox)
        layout.addWidget(self.buttonColor)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.lineEdit.textChanged.connect(self.updateTextLabel)
        self.spinBox.valueChanged.connect(self.updateSpinLabel)

    def updateTextLabel(self, text):
        self.labelText.setText(f'입력한 텍스트: {text}')

    def updateSpinLabel(self, value):
        self.labelSpin.setText(f'수치: {value}')

    def selectColor(self):
        color = QColorDialog.getColor()
        if color.isValid():
            self.setStyleSheet(f"background-color: {color.name()};")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())
    

이제 언급된 모든 속성을 편집할 수 있는 기본적인 속성 편집기의 완성입니다. 사용자는 텍스트, 수치 및 색상을 자유롭게 편집할 수 있습니다.

7. 결론

이번 강좌에서는 PyQt를 사용하여 속성 편집기를 구현하는 방법에 대해 알아보았습니다. 텍스트, 숫자 및 색상 선택 기능을 추가함으로써 사용자가 다양한 속성을 편집할 수 있는 애플리케이션을 만들 수 있었습니다. PyQt는 강력하고 유연한 툴킷이므로, 다양한 GUI 애플리케이션에 적용할 수 있는 가능성이 무궁무진합니다.

이제 여러분은 PyQt를 사용하여 복잡한 사용자 인터페이스를 구축할 준비가 되셨습니다. 추가적인 기능을 구현하거나 더 복잡한 요소를 도입하여 개인적인 프로젝트를 진행해 보시기를 추천합니다.

PyQt개발강좌, QWidget 상속을 통한 커스텀 위젯 만들기

PyQt는 Python에서 GUI 애플리케이션을 개발하기 위한 강력한 라이브러리입니다. PyQt를 사용하면 다양한 기본 제공 위젯을 활용할 수 있지만, 때때로 특정 용도에 맞는 커스텀 위젯이 필요할 수도 있습니다. 본 강좌에서는 QWidget 클래스를 상속하여 어떻게 나만의 커스텀 위젯을 만들 수 있는지에 대해 자세히 설명하겠습니다. 예제를 통해 단계별로 진행하며, 최종적으로 완전한 프로그램을 만들 것입니다.

1. PyQt 환경 설정

PyQt5를 설치하려면 아래의 pip 명령어를 사용하세요.

pip install PyQt5

2. QWidget 클래스 이해하기

QWidget는 PyQt의 모든 사용자 인터페이스 요소의 기본 클래스입니다. QWidget 클래스를 상속하여 우리는 자신의 사용자 정의 위젯을 만들 수 있습니다. QWidget 클래스는 기본적으로 GUI 요소, 레이아웃, 이벤트 처리 등의 여러 기능을 제공합니다.

3. 커스텀 위젯 만들기

이제 QWidget을 상속하여 간단한 커스텀 위젯을 만들어 보겠습니다. 이 예제에서 우리는 사용자로부터 입력을 받고, 버튼을 클릭했을 때 해당 입력을 반영하여 텍스트를 표시하는 간단한 위젯을 만들 것입니다.

3.1. 예제 코드 설명

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout

class CustomWidget(QWidget):
    def __init__(self):
        super().__init__()

        # 레이아웃 설정
        self.layout = QVBoxLayout()
        
        # QLabel 초기화
        self.label = QLabel("여기에 텍스트를 입력하세요:", self)
        
        # QLineEdit 초기화
        self.line_edit = QLineEdit(self)
        
        # QPushButton 초기화
        self.button = QPushButton("제출", self)
        self.button.clicked.connect(self.on_click)

        # 레이아웃에 위젯 추가
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.line_edit)
        self.layout.addWidget(self.button)
        
        self.setLayout(self.layout)
        self.setWindowTitle("커스텀 위젯 예제")
    
    def on_click(self):
        # QLabel의 텍스트를 QLineEdit의 입력값으로 변경
        input_text = self.line_edit.text()
        self.label.setText("입력한 텍스트: " + input_text)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    custom_widget = CustomWidget()
    custom_widget.show()
    sys.exit(app.exec_())

3.2. 코드 해설

위의 예제 코드는 다음과 같은 구성 요소로 이루어져 있습니다:

  • CustomWidget 클래스: QWidget을 상속받아 커스텀 GUI 위젯을 정의합니다.
  • 레이아웃 설정: QVBoxLayout을 사용하여 위젯을 수직으로 배치합니다.
  • QLabel: 사용자가 텍스트를 입력하도록 지시하기 위한 라벨입니다.
  • QLineEdit: 사용자가 텍스트를 입력할 수 있는 필드입니다.
  • QPushButton: 사용자가 입력한 텍스트를 제출할 수 있는 버튼입니다.
  • on_click 메소드: 버튼 클릭 시 실행되어, QLineEdit의 텍스트를 QLabel에 반영합니다.

4. 이벤트 처리

PyQt에서 이벤트 처리는 매우 중요합니다. 위 예제에서 버튼 클릭 이벤트는 clicked 시그널을 통해 처리되며, on_click 메소드를 호출합니다. 사용자 정의 위젯에 별도의 이벤트 처리가 필요한 경우, 다수의 이벤트 핸들러를 추가하여 다양한 상호작용을 구현할 수 있습니다.

4.1. 키보드 이벤트 처리

이벤트를 추가로 처리하는 방법에 대해 알아보겠습니다. 예를 들어, QLineEdit에 입력한 후 Enter 키를 누르면 QLabel의 텍스트가 변경되도록 하겠습니다.


def keyPressEvent(self, event):
    if event.key() == Qt.Key_Return:
        self.on_click()

위 코드를 CustomWidget 클래스 안에 추가하면, 사용자가 Enter 키를 눌렀을 때 on_click 메소드가 호출됩니다.

5. 커스텀 위젯에 스타일 적용하기

커스텀 위젯에 스타일을 적용하여 더욱 매력적인 인터페이스를 만들 수 있습니다. 위젯에 다양한 CSS 스타일을 적용할 수 있습니다. 예를 들어, 버튼에 배경 색상을 추가해 보겠습니다.


self.button.setStyleSheet("background-color: lightblue; color: black; font-size: 16px;")

6. 다양한 위젯 조합하기

여러 가지 커스텀 위젯을 조합하여 복잡한 사용자 인터페이스를 만들 수 있습니다. 이런 조합은 복잡한 애플리케이션을 설계할 때 필요합니다. 각각의 위젯을 모듈화하여 필요한 위치에 쌓거나 배치할 수 있습니다.

7. 결론

이번 강좌에서는 PyQt를 사용하여 QWidget을 상속받아 커스텀 위젯을 만드는 방법에 대해 배웠습니다. 간단한 예제를 통해 속성과 메소드, 이벤트 처리 및 스타일링 방법을 익혔습니다. 이러한 기본기를 바탕으로 더 복잡한 애플리케이션을 만들 수 있을 것입니다. PyQt는 매우 유연한 라이브러리이므로, 다양한 가능성을 탐구하며 재미있게 사용할 수 있습니다.

8. 추가 자료

PyQt에 대한 더 많은 자료와 리소스를 찾고자 한다면, 다음의 링크를 참고하시기 바랍니다:

9. Q&A

궁금한 점이나 피드백이 있다면 아래 댓글란에 남겨 주세요. 도움이 필요한 경우 답변해 드리도록 하겠습니다!

이 글은 PyQt에 대한 이해를 돕기 위한 목적으로 작성되었습니다. 많은 도움이 되셨기를 바랍니다!