파이썬/PyQt5

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

녹두장군 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_())
반응형