FrameWork/PyQT

파이썬 라이브러리 PyQT을 통해 에딧와 리스트 뷰, 위젯 컴포넌트를 다루기

JHeaon 2023. 7. 5. 04:29

이번 포스팅에서는 입력값을 다루는 에딧 컴포넌트와 어떤 목록을 보여주는 리스트 위젯 컴포넌트에 대해 알아보자.

 

 

에딧 컴포넌트

Edit component는 말 그대로 값을 받아 처리하는 컴포넌트이다. Html에 비교하자면 input 태그에 비유할 수 있다. 

빨간색 하나 하나가 에딧 박스이다.

에딧 박스 컴포넌트에 대한 함수가 있는데 아래는 그중에서 자주 사용하는 함수의 코드이다.

"""
위에 edit_text를 정의 했다라고 가정한다.
"""

# 에딧 박스에 있는 내용을 변수 text에 저장
text = self.edit_text.text()

# edit_text 라는 Edit 컴포넌트에 Enter 입력이 들어오면 send() 가 실행
self.edit_text.returnPressed.connect(self.send)

# 에딧박스에 있는 내용 삭제
self.edit_text.clear()

 

 

 

 

 

리스트 뷰, 위젯

ListView, ListWidget은 말 그대로 항목을 보여주는 컴포넌트이다. 2개의 컴포넌트는 한 가지의 차이가 있는데 모델이 있냐 없냐의 유무이다. ListView 같은 경우에는 만들어진 모델이 없기 때문에 따로 모델을 설정해 준 뒤 그 모델에 값을 넣어 ListView에 추가하여 보이게 만들어지는 반면 ListWidget은 이미 내장되어 있는 모델이 있기 때문에 값만 넣어서 항목이 보이게 만들 수 있다. 이를 MVC 패턴과 유사하다고도 볼 수 있다. 

MVC

 

 

 

리스트 뷰

ListView는 Model이 없는 View이다. 따라서 Model을 설정해 준 다음에, 각 내용을 추가하는 형식으로 코드를 작성하여야 한다. ListView을 통해 항목을 화면에 뛰우는 순서는 다음과 같다. 

  • Pyside6.QtGui을 통해 모델과 아이템을 추가한다.
  • 리스트 뷰에 들어갈 모델을 만든 뒤, 리스트 뷰에 모델을 설정한다. 
  • 내가 넣고 싶은 객체를 QstandardItem() 인스턴스로 만들어 리스트 뷰에 추가한다. 

이를 구현한 코드는 다음과 같다. 

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLineEdit, QListView,
    QMainWindow, QPushButton, QSizePolicy, QWidget)

# ListView을 위한 모델과, 아이템을 추가해줍니다. 
from PySide6.QtGui import QStandardItemModel, QStandardItem

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(324, 534)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.list_chat = QListView(self.centralwidget)
        self.list_chat.setObjectName(u"list_chat")
        self.list_chat.setGeometry(QRect(10, 20, 301, 451))
        self.horizontalLayoutWidget = QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget")
        self.horizontalLayoutWidget.setGeometry(QRect(10, 480, 301, 41))
        self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.edit_name = QLineEdit(self.horizontalLayoutWidget)
        self.edit_name.setObjectName(u"edit_name")

        self.horizontalLayout.addWidget(self.edit_name)

        self.edit_text = QLineEdit(self.horizontalLayoutWidget)
        self.edit_text.setObjectName(u"edit_text")

        self.horizontalLayout.addWidget(self.edit_text)

        self.btn_send = QPushButton(self.horizontalLayoutWidget)
        self.btn_send.setObjectName(u"btn_send")
        self.btn_send.clicked.connect(self.send)

        self.horizontalLayout.addWidget(self.btn_send)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
        
        # list Veiw을 이용하기 위해서 모델을 생성하고 뷰에 Model을 설정해 줍니다. 
        self.model = QStandardItemModel()
        self.list_chat.setModel(self.model)
        
    def send(self):
        text = self.edit_text.text()
       	
        # text로 받아온 문자열을 QStandardItem() 을 통해 객체화 합니다. 
        item = QStandardItem(text)
        # Item을 해당 모델에 추가합니다. 
        self.model.appendRow(item)

 

 

 

리스트 위젯

그에 반해 ListWidget은 모델이 이미 내장되어 있기 때문에 addItem()만을 이용하여 요소를 추가할 수 있다. 리스트 위젯을 통해 항목을 나타내는 방법은 다음과 같다.

  • 리스트 위젯에 보여주고 싶은 항목을 addItem() 함수를 통해 추가한다.

아래는 이를 구현한 코드이다. 

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(324, 534)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.list_chat = QListWidget(self.centralwidget)
        self.list_chat.setObjectName(u"list_chat")
        self.list_chat.setGeometry(QRect(10, 20, 301, 451))
        self.horizontalLayoutWidget = QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget")
        self.horizontalLayoutWidget.setGeometry(QRect(10, 480, 301, 41))
        self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.edit_name = QLineEdit(self.horizontalLayoutWidget)
        self.edit_name.setObjectName(u"edit_name")

        self.horizontalLayout.addWidget(self.edit_name)

        self.edit_text = QLineEdit(self.horizontalLayoutWidget)
        self.edit_text.setObjectName(u"edit_text")

        self.horizontalLayout.addWidget(self.edit_text)

        self.btn_send = QPushButton(self.horizontalLayoutWidget)
        self.btn_send.setObjectName(u"btn_send")
        self.btn_send.clicked.connect(self.send)
        self.edit_text.returnPressed.connect(self.send)

        self.horizontalLayout.addWidget(self.btn_send)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    
        
    def send(self):
        text = self.edit_text.text()
        # listview 와 달리 바로 addItem() 을 통해서 넣을 수 있다. 
        self.list_chat.addItem(text)

 

만약 리스트 위젯에 있는 항목에 대해 선택한 항목 삭제를 구현하고자 한다면, 아래 처럼 코드를 작성 하면 된다.

def delete(self):
    item = self.list_widget.currentRow()
    self.list_widget.takeItem(item)

 

 

리스트 뷰 vs 리스트 위젯 어떤 것을 사용하여야 할까?

스택오버 플로우나 QT 관련 커뮤니티를 찾아보면 위젯보다는 뷰를 선호하는 경향을 보인다 왜냐하면 위젯은 뷰의 일부분을 구현한 것이기 때문이다. 즉 확장성을 고려하여 작업한다고 했을 때에는 뷰를 선택하는 것이 좋고, 간단한 기능만을 구현한다면 리스트 위젯을 사용하는 것이 좋은 것으로 생각된다. 

 


참조 

https://stackoverflow.com/questions/35675877/when-should-i-use-a-qlistwidget-over-a-qlistview

 

When should I use a QListWidget over a QListView?

From what I understand, QListWidget is built on QListView, and implements a "traditional" list widget, without any model/view concept. Is there any situation where QListWidget should be preferred ...

stackoverflow.com

https://forum.qt.io/topic/91477/qlistview-and-qlistwidget

 

QListView and QListWidget

I've been reading about those two classes ,But can't figure out exactly when to use them. for example , I wanted to create a list of labels to be displayed and when I click on the label something should happen. Instead of doing that I created a QListWidge.

forum.qt.io

 

'FrameWork/PyQT'의 다른글

  • 현재글 파이썬 라이브러리 PyQT을 통해 에딧와 리스트 뷰, 위젯 컴포넌트를 다루기

관련글