본문으로 바로가기

파이썬(Python) PyQt5 QListWidget 위젯 사용하기

category 파이썬/PyQt5 2021. 11. 13. 09:33
반응형

QListWidget 은 화면에 목록을 보여주고 싶을 때 사용하는 위젯입니다. QListWidgetItem 을 내부 모델 객체로 사용해서 관리합니다. QListView 와 비교해서는 좀더 유연한 화면을 구현할 수 있습니다. 리스트 생성, 데이터 추가, 삭제, 시그널 이벤트 연결에 대해 알아보겠습니다.

 

1. 리스트 위젯 생성과 데이터 추가

 

QListWidget QtWidgets 모듈에 포함되어 있습니다. 리스트 위젯의 생성 방식은 다른 위젯과 동일합니다. 위젯의 크기는 resize 함수를 이용해서 조절했습니다. 위치와 크기를 한번에 지정하고 싶다면 setGeometry() 함수를 이용하세요.

from PyQt5.QtWidgets import QListWidget

# QListWidget 추가
self.listwidget = QListWidget(self)
self.listwidget.resize(150, 100)

 

데이터 추가하는 방법은 여러가지입니다. insertItem() 함수를 사용해서 행 위치 값인 인덱스와 텍스트를 입력하는 방법과 Item 객체인 QListWidgetItem 을 생성해서 추가하는 방법입니다. addItem() 함수는 QListWidgetItem 객체만 필요하며, QListWidget 의 목록 마지막에 들어갑니다.

from PyQt5.QtWidgets import QListWidget, QListWidgetItem

# 값 추가
self.listwidget.insertItem(0, "Chrome")
self.listwidget.insertItem(1, "Explorer")
self.listwidget.insertItem(2, "Firefox")
self.listwidget.insertItem(4, "Edge")

# QListWidgetItem 클래스를 이용해서 추가
self.listwidget.insertItem(5, QListWidgetItem("Browsers"))

# addItem() 함수 이용해서 목록 마지막에 추가
temp_item = QListWidgetItem('Windows10')
self.listwidget.addItem(temp_item)

 

결과는 아래와 같습니다. 스크롤을 없애기 위해 높이 값을 조절하고 싶다면 resize() 함수에서 값을 조절합니다.

 

2. 아이콘 삽입하기

 

리스트에는 텍스트뿐만 아니라 이미지 삽입도 가능합니다. 아이콘을 텍스트 앞에 추가해서 좀더 명확하게 의미를 전달할 수 있습니다. 먼저 QListWidgetItem 객체를 생성합니다. 생성자 함수 중에는 QIcon 객체를 입력하는 것이 있습니다. 첫 번째 파라미터에 QIcon 을 넣고 두 번째에 리스트에 추가할 텍스트를 입력합니다. QIcon 객체는 생성할 때 이미지 경로를 입력합니다. 리스트에 추가하는 함수는 insertItem() addItem() 중 하나를 사용합니다.

from PyQt5.QtWidgets import QListWidget, QListWidgetItem
from PyQt5.QtGui import QIcon

# 아이콘 입력
icon = QIcon('btn.png')
icon_item = QListWidgetItem(icon, 'ICON')
self.listwidget.addItem(icon_item)

 

결과는 다음과 같습니다. 아이콘은 텍스트 왼쪽 시작 부분에 들어갑니다.

 

3. 시그널 이벤트 연결

 

자주 사용하는 시그널의 종류는 아래와 같습니다. 이 중에 선택이 바뀌었을 때 발생하는 itemSelectionChanged 시그널을 연결해서 로그를 찍어 보겠습니다.

 

QListWidget connect 함수를 사용해서 이벤트가 발생했을 때 수행할 함수를 입력합니다. 함수의 구현 내용은 다음과 같습니다.  selectedItems() 함수를 사용해서 배열 객체인 List[QListWidgetItem] 를 반환합니다. for 문을 이용해서 QListWidgetItem 를 하나씩 꺼낸 후 text() 함수를 이용해서 콘솔에 찍습니다.

from PyQt5.QtWidgets import QListWidget, QListWidgetItem

# 시그널 연결
self.listwidget.itemSelectionChanged.connect(self.selectchanged_listwidget)

def selectchanged_listwidget(self):
    lst_item = self.listwidget.selectedItems()# 선택된 데이터 체크
    # 선택된 데이터 출력
    for item in lst_item:
        print(item.text())

 

리스트에 데이터를 선택해 보세요. 그림처럼 콘솔에 선택한 텍스트가 나타납니다.

 

4. 선택한 데이터 삭제

 

리스트에 추가한 항목들을 삭제하는 방법입니다. 우선 삭제를 위한 버튼을 추가했습니다. 버튼의 clicked 시그널 이벤트에 삭제 로직이 들어가 있는 함수를 연결합니다. 삭제를 위해서 첫 번째 체크해야 될 부분은 리스트에서 어떤 항목을 선택했는지 찾는 것입니다. selectedIndexes() 함수를 사용해서 List 에 담긴 QModelIndex 객체를 리턴 받습니다. 다음은 for 문을 돌려서 QModelIndex 를 하나씩 꺼낸 뒤 row() 함수로 선택한 항목이 몇 번째 데이터인지 조회합니다. 그리고 QListWidget model() 함수로 QAbstractItemModel 객체를 리턴 받은 후 removeRow() 함수로 삭제합니다. 파라미터 값은 리스트에서 선택한 항목의 행 번호 입니다.

from PyQt5.QtWidgets import QPushButton

# --- 삭제 버튼 생성
self.delete_button = QPushButton(self);
self.delete_button.move(180, 5)
self.delete_button.setText('Delete')

# 삭제 시그널
self.delete_button.clicked.connect(self.clicked_delete_button)

def clicked_delete_button(self):
    # 선택된 데이터가 있는지 체크
    lst_modelindex = self.listwidget.selectedIndexes()
    # 선택된 데이터 삭제
    for modelindex in lst_modelindex:
        print(modelindex.row())
        self.listwidget.model().removeRow(modelindex.row())

 

결과 화면은 아래와 같습니다. QListWidget 바로 옆에 QPushButton Delete 를 눌러 선택한 아이템을 삭제합니다.

 

지금까지 설명한 전체 소스는 아래와 같습니다.

#!/usr/bin/env python3
import sys
from PyQt5.QtWidgets import QApplication, QListWidget, \
    QListWidgetItem, QMainWindow, QPushButton
from PyQt5.QtGui import QIcon


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 윈도우 설정
        self.setGeometry(300, 300, 500, 300)  # x, y, w, h
        self.setWindowTitle('Status Window')

        # QListWidget 추가
        self.listwidget = QListWidget(self)
        self.listwidget.resize(150, 100)

        # 지정한 행 위치에 값 추가
        self.listwidget.insertItem(0, "Chrome")
        self.listwidget.insertItem(1, "Explorer")
        self.listwidget.insertItem(2, "Firefox")
        self.listwidget.insertItem(4, "Edge")

        # QListWidgetItem 클래스를 이용해서 추가
        self.listwidget.insertItem(5, QListWidgetItem("Browsers"))

        # addItem() 함수 이용해서 목록 마지막에 추가
        temp_item = QListWidgetItem('Windows10')
        self.listwidget.addItem(temp_item)

        # 아이콘 입력
        icon = QIcon('btn.png')
        icon_item = QListWidgetItem(icon, 'ICON')
        self.listwidget.addItem(icon_item)

        # 시그널 연결
        self.listwidget.itemSelectionChanged.connect(self.selectchanged_listwidget)

        # --- 삭제 버튼 생성
        self.delete_button = QPushButton(self);
        self.delete_button.move(180, 5)
        self.delete_button.setText('Delete')

        # 삭제 시그널
        self.delete_button.clicked.connect(self.clicked_delete_button)

    def selectchanged_listwidget(self):
        lst_item = self.listwidget.selectedItems()# 선택된 데이터 체크
        # 선택된 데이터 출력
        for item in lst_item:
            print(item.text())

    def clicked_delete_button(self):
        # 선택된 데이터가 있는지 체크
        lst_modelindex = self.listwidget.selectedIndexes()
        # 선택된 데이터 삭제
        for modelindex in lst_modelindex:
            print(modelindex.row())
            self.listwidget.model().removeRow(modelindex.row())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())
반응형