트리 모델 완성기 예제
트리 모델 완성기 예제는 마침표를 구분 기호로 사용하여 자식, 손자녀 및 손자녀 수준 개체에 액세스하는 계층적 모델에 완성 기능을 제공하는 방법을 보여줍니다.
완성자 예제와 마찬가지로 완성 모드 및 대소문자 구분을 선택할 수 있는 QComboBox 객체와 줄 바꿈 완성을 위한 QCheckBox 객체를 제공합니다.
리소스 파일
트리모델 컴플리터의 내용은 treemodel.txt에서 읽습니다. 이 파일은 다음을 포함하는 treemodelcompleter.qrc 리소스 파일에 포함되어 있습니다:
<!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/"> <file>resources/treemodel.txt</file> </qresource> </RCC>
트리모델 컴플리터 클래스 정의
TreeModelCompleter
은 QCompleter 의 서브클래스로, parent 을 인수로 하는 생성자와 parent 및 model 을 인수로 하는 생성자 두 개가 있습니다.
class TreeModelCompleter : public QCompleter { Q_OBJECT Q_PROPERTY(QString separator READ separator WRITE setSeparator) public: explicit TreeModelCompleter(QObject *parent = nullptr); explicit TreeModelCompleter(QAbstractItemModel *model, QObject *parent = nullptr); QString separator() const; public slots: void setSeparator(const QString &separator); protected: QStringList splitPath(const QString &path) const override; QString pathFromIndex(const QModelIndex &index) const override; private: QString sep; };
이 클래스는 보호된 함수 splitPath() 및 pathFromIndex()를 트리 모델에 맞게 재구현합니다. 트리 모델에 맞게 QCompleter 을 사용자 정의하는 방법에 대한 자세한 내용은 Handling Tree Models 을 참조하세요.
TreeModelCompleter
또한 Q_PROPERTY() 매크로를 사용하여 선언되는 구분자 속성이 있습니다. 구분 기호에는 READ 및 WRITE 속성과 해당 함수 separator()
및 setSeparator()
가 있습니다. Q_PROPERTY ()에 대한 자세한 내용은 Qt의 프로퍼티 시스템을 참조하십시오.
TreeModelCompleter 클래스 구현
첫 번째 생성자는 부모를 가진 TreeModelCompleter
객체를 생성하고, 두 번째 생성자는 부모와 QAbstractItemModel, model 를 가진 객체를 생성합니다.
TreeModelCompleter::TreeModelCompleter(QObject *parent) : QCompleter(parent) { } TreeModelCompleter::TreeModelCompleter(QAbstractItemModel *model, QObject *parent) : QCompleter(model, parent) { }
separator()
함수는 구분 문자열을 반환하는 게터 함수입니다.
QString TreeModelCompleter::separator() const { return sep; }
앞서 언급했듯이 기본 구현이 QFileSystemModel 또는 목록 모델에 더 적합하기 때문에 splitPath()
함수를 다시 구현했습니다. QCompleter 경로를 각 수준에서 일치하는 문자열 목록으로 분할하기 위해 QString::split()을 사용하여 sep
을 구분 기호로 사용하여 경로를 분할합니다.
QStringList TreeModelCompleter::splitPath(const QString &path) const { return (sep.isNull() ? QCompleter::splitPath(path) : path.split(sep)); }
pathFromIndex()
함수는 트리 모델에 대한 completionRole()의 데이터를 반환합니다. 이 함수는 기본 구현이 목록 모델에 더 적합하기 때문에 다시 구현되었습니다. 구분 기호가 없으면 QCompleter 의 기본 구현을 사용하고, 그렇지 않으면 prepend() 함수를 사용하여 위쪽으로 이동하여 데이터를 누적합니다. 그런 다음 이 함수는 구분 기호를 사용하여 서로 다른 레벨의 객체를 조인하는 QStringList, dataList
을 반환합니다.
QString TreeModelCompleter::pathFromIndex(const QModelIndex &index) const { if (sep.isNull()) return QCompleter::pathFromIndex(index); // navigate up and accumulate data QStringList dataList; for (QModelIndex i = index; i.isValid(); i = i.parent()) dataList.prepend(model()->data(i, completionRole()).toString()); return dataList.join(sep); }
MainWindow 클래스 정의
MainWindow
클래스는 QMainWindow 의 하위 클래스이며 5개의 사용자 정의 슬롯을 구현합니다: about()
, changeCase()
, changeMode()
, highlight()
, 그리고 updateContentsLabel()
입니다.
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); private slots: void about(); void changeCase(int); void changeMode(int); void highlight(const QModelIndex &index); void updateContentsLabel(const QString &sep);
또한 이 클래스에는 createMenu()
와 modelFromFile()
의 두 개의 비공개 함수와 QTreeView, QComboBox, QLabel, TreeModelCompleter
및 QLineEdit 의 비공개 인스턴스가 있습니다.
private: void createMenu(); QAbstractItemModel *modelFromFile(const QString &fileName); QTreeView *treeView = nullptr; QComboBox *caseCombo = nullptr; QComboBox *modeCombo = nullptr; QLabel *contentsLabel = nullptr; TreeModelCompleter *completer = nullptr; QLineEdit *lineEdit = nullptr; };
MainWindow 클래스 구현
MainWindow
의 생성자는 부모를 가진 MainWindow
객체를 생성하고 completer
와 lineEdit
를 초기화합니다. createMenu()
함수가 호출되어 "파일" 메뉴와 "도움말" 메뉴가 설정됩니다. completer
의 모델은 modelFromFile()
에서 가져온 QAbstractItemModel 으로 설정되고 highlighted() 신호는 MainWindow
의 highlight()
슬롯에 연결됩니다.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { createMenu(); completer = new TreeModelCompleter(this); completer->setModel(modelFromFile(":/resources/treemodel.txt")); completer->setSeparator(QLatin1String(".")); QObject::connect(completer, QOverload<const QModelIndex &>::of(&TreeModelCompleter::highlighted), this, &MainWindow::highlight); QWidget *centralWidget = new QWidget; QLabel *modelLabel = new QLabel; modelLabel->setText(tr("Tree Model<br>(Double click items to edit)")); QLabel *modeLabel = new QLabel; modeLabel->setText(tr("Completion Mode")); modeCombo = new QComboBox; modeCombo->addItem(tr("Inline")); modeCombo->addItem(tr("Filtered Popup")); modeCombo->addItem(tr("Unfiltered Popup")); modeCombo->setCurrentIndex(1); QLabel *caseLabel = new QLabel; caseLabel->setText(tr("Case Sensitivity")); caseCombo = new QComboBox; caseCombo->addItem(tr("Case Insensitive")); caseCombo->addItem(tr("Case Sensitive")); caseCombo->setCurrentIndex(0);
QLabel 객체 modelLabel
, modeLabel
및 caseLabel
가 인스턴스화됩니다. 또한 QComboBox 객체 modeCombo
및 caseCombo
도 인스턴스화되어 채워집니다. 기본적으로 completer
의 모드는 "필터링된 팝업"이며 대소문자를 구분하지 않습니다.
QLabel *separatorLabel = new QLabel; separatorLabel->setText(tr("Tree Separator")); QLineEdit *separatorLineEdit = new QLineEdit; separatorLineEdit->setText(completer->separator()); connect(separatorLineEdit, &QLineEdit::textChanged, completer, &TreeModelCompleter::setSeparator); QCheckBox *wrapCheckBox = new QCheckBox; wrapCheckBox->setText(tr("Wrap around completions")); wrapCheckBox->setChecked(completer->wrapAround()); connect(wrapCheckBox, &QAbstractButton::clicked, completer, &QCompleter::setWrapAround); contentsLabel = new QLabel; contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(separatorLineEdit, &QLineEdit::textChanged, this, &MainWindow::updateContentsLabel); treeView = new QTreeView; treeView->setModel(completer->model()); treeView->header()->hide(); treeView->expandAll(); connect(modeCombo, &QComboBox::activated, this, &MainWindow::changeMode); connect(caseCombo, &QComboBox::activated, this, &MainWindow::changeMode); lineEdit = new QLineEdit; lineEdit->setCompleter(completer);
MainWindow
에 모든 객체를 배치하기 위해 QGridLayout 을 사용합니다.
QGridLayout *layout = new QGridLayout; layout->addWidget(modelLabel, 0, 0); layout->addWidget(treeView, 0, 1); layout->addWidget(modeLabel, 1, 0); layout->addWidget(modeCombo, 1, 1); layout->addWidget(caseLabel, 2, 0); layout->addWidget(caseCombo, 2, 1); layout->addWidget(separatorLabel, 3, 0); layout->addWidget(separatorLineEdit, 3, 1); layout->addWidget(wrapCheckBox, 4, 0); layout->addWidget(contentsLabel, 5, 0, 1, 2); layout->addWidget(lineEdit, 6, 0, 1, 2); centralWidget->setLayout(layout); setCentralWidget(centralWidget); changeCase(caseCombo->currentIndex()); changeMode(modeCombo->currentIndex()); setWindowTitle(tr("Tree Model Completer")); lineEdit->setFocus(); }
createMenu()
함수는 필요한 QAction 객체를 설정하고 '파일' 메뉴와 '도움말' 메뉴에 추가합니다. 이러한 작업의 triggered() 신호는 해당 슬롯에 연결됩니다.
void MainWindow::createMenu() { QAction *exitAction = new QAction(tr("Exit"), this); QAction *aboutAct = new QAction(tr("About"), this); QAction *aboutQtAct = new QAction(tr("About Qt"), this); connect(exitAction, &QAction::triggered, qApp, &QApplication::quit); connect(aboutAct, &QAction::triggered, this, &MainWindow::about); connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); QMenu *fileMenu = menuBar()->addMenu(tr("File")); fileMenu->addAction(exitAction); QMenu *helpMenu = menuBar()->addMenu(tr("About")); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); }
changeMode()
함수는 사용자가 선택한 완료 모드에 해당하는 index 을 수락하고 그에 따라 completer
의 모드를 변경합니다.
void MainWindow::changeMode(int index) { QCompleter::CompletionMode mode; if (index == 0) mode = QCompleter::InlineCompletion; else if (index == 1) mode = QCompleter::PopupCompletion; else mode = QCompleter::UnfilteredPopupCompletion; completer->setCompletionMode(mode); }
about()
함수는 트리 모델 컴플리터 예제에 대한 간략한 설명을 제공합니다.
void MainWindow::about() { QMessageBox::about(this, tr("About"), tr("This example demonstrates how " "to use a QCompleter with a custom tree model.")); }
changeCase()
함수는 cs 의 값에 따라 Case Sensitive 과 Case Insensitive 모드를 번갈아 사용합니다.
void MainWindow::changeCase(int cs) { completer->setCaseSensitivity(cs ? Qt::CaseSensitive : Qt::CaseInsensitive); }
main()
함수
main()
함수는 MainWindow
을 인스턴스화하고 show() 함수를 호출하여 표시합니다.
int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow window; window.show(); return app.exec(); }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.