QComboBox를 이용한 단어자동완성

이번에는 Python과 PyQt5의 QComboBox를 이용한 자동완성(AutoCompletion)을 살펴보겠습니다.

좀 쉽게 생각하고 만들어 보았으나, 만드는 과정에서 한가지 문제점이 있었습니다.

바로 QComboBox에 QLineEdit를 추가해 목록을 수정가능하게 만드는 과정에서, 입력한 단어가 QComboBox에 원치않게 추가되는 부분이 있었습니다.

예를 들면 콤보박스에 추가되는 아이템의 목록이 아래 리스트와 같다면,

allWords = ['부서', '사원', '이름', '직급', '나이']

아래와 같이 콤보박스의 아이템들이 보여집니다.


"나" 라는 단어를 검색한 후 아래와 같이 아이템이 Popup 된 상태에서 엔터키를 누르면 "나"라는 단어가 의도치 않게 콤보박스의 목록에 삽입되어 나오는 문제입니다.


해결과정은 아래 소스코드분석에서 말씀드리겠습니다.

먼저 전체 코드는 아래와 같습니다.
from PyQt5.QtWidgets import QApplication, QWidget, QComboBox, QLineEdit, QCompleter, QVBoxLayout
from PyQt5.QtCore import Qt
import sys

QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)

class CWidget(QWidget):

    def __init__(self):
        super().__init__()       

        # 단어 리스트                                              
        allWords = ['부서', '사원', '이름', '직급', '나이']

        # QCombo 생성
        self.cmb = QComboBox(self)
        self.cmb.addItems(allWords)
        # QCombo 가 Editiable 한 경우 적은 내용이 추가되지 않도록
        self.cmb.setInsertPolicy(QComboBox.NoInsert)
                    
        # LineEdit 생성 후 QCombo에 추가 
        lineEdit = QLineEdit()
        self.cmb.setLineEdit(lineEdit)

        # Completer 생성 및 QCombo 연결
        completer = QCompleter(allWords)   
        # Completer 모드 설정       
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.cmb.setCompleter(completer)  
        
        box = QVBoxLayout()
        box.addWidget(self.cmb)
        self.setLayout(box)
        self.show()        


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = CWidget()    
    sys.exit(app.exec_())


16번 라인에서 QComboBox class의 객체를 생성하고, 단어리스트(allWords) 를 아이템으로 추가합니다.

QComboBox의 allItems() 함수는 하나씩 아이템을 추가하는 allItem() 함수의 복수형이며,  한번에 단어리스트를 추가해주는 기능을 제공합니다.

이후, 위에서 언급한 콤보박스의 원치 않는 아이템 추가를 막기 위해 setInsertPolicy() 함수를 반드시 추가하고 전달인자로 QComboBox.NoInsert(or 상수 0) 를 넣어주어야 합니다.

아래는 Qt의 도움말에서 인용한 InsertPolicy 열거형 타입 (C++ enum) 값 정보입니다.

PyQt는 C++로 만들어진 Qt class들의 Python binding 이기 때문에, PyQt의 도움말보다 오리지널 Qt(C++)의 도움말을 참조하는 것이 더 도움이 됩니다. 물론 C++을 이해하고 있다는 가정하에서 입니다.
enum QComboBox::InsertPolicy
This enum specifies what the QComboBox should do when a new string is entered by the user.


Constant
Value
Description
QComboBox::NoInsert
0
The string will not be inserted into the combobox.
QComboBox::InsertAtTop
1
The string will be inserted as the first item in the combobox.
QComboBox::InsertAtCurrent
2
The current item will be replaced by the string.
QComboBox::InsertAtBottom
3
The string will be inserted after the last item in the combobox.
QComboBox::InsertAfterCurrent
4
The string is inserted after the current item in the combobox.
QComboBox::InsertBeforeCurrent
5
The string is inserted before the current item in the combobox.
QComboBox::InsertAlphabetically
6
The string is inserted in the alphabetic order in the combobox.
다음은 콤보박스에 QLineEdit를 설정하고 QCompleter class를 설정하면 자동완성기능은 끝입니다.

다만, QCompleter class 와 QComboBox 연결시 QCompleter의 멤버함수인 setCompletionMode() 함수의 전달인자로 QCompleter.UnfilteredPopupCompletion 을 넘기는 것을 잊지 마세요.

아래는 CompletionMode에 대한 Qt Document 도움말 입니다.

enum QCompleter::CompletionMode
This enum specifies how completions are provided to the user.


Constant
Value
Description
QCompleter::PopupCompletion
0
Current completions are displayed in a popup window.
QCompleter::InlineCompletion
2
Completions appear inline (as selected text).
QCompleter::UnfilteredPopupCompletion
1
All possible completions are displayed in a popup window with the most likely suggestion indicated as current.
모든 완성단어가 팝업 표시되고, 가장 가능성이 높은 단어가 현재(Current Item)로 표시된다고 합니다.

감사합니다.

댓글

이 블로그의 인기 게시물

Qt Designer 설치하기

PyQt5 기반 동영상 플레이어앱 만들기