728x90

Qt를 설치할 때 볼 수 있던 아래와 같은 구조가지는 UI Component를 TreeWidget이라고 합니다. Qt에서 TreeWidget을 사용하는 법에 대해 간단히 소개하려고 합니다.

먼저 UI는 아래와 같이 구성했습니다. 상단에 QTreeWidget 그리고 하단에는 선택한 Item의 Text를 확인할 수 있는 Label과 선택된 Item에 자식 Item을 추가할 수 있는 Insert와 해당 Item을 지울 Delete 버튼입니다.

먼저 간단하게 Header와 몇가지 Item을 추가해보겠습니다.

#include "mainwindow.h"
#include "./ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTreeWidgetItem* headerItem = new QTreeWidgetItem;
    headerItem->setText(0, "Name");
    headerItem->setText(1, "Price");
    ui->treeWidget->setHeaderItem(headerItem);  // header

    QTreeWidgetItem* Parent = new QTreeWidgetItem(ui->treeWidget);
    Parent->setText(0, "Nintendo");

    QTreeWidgetItem* Child = new QTreeWidgetItem(Parent);
    Child->setText(0, "Zelda");
    Child->setText(1, "70000");
}

MainWindow::~MainWindow()
{
    delete ui;
}

Nintendo라는 부모 Item 아래 Zelda 라는 자식 Item을 추가했습니다.

여기에 선택된 Item의 Name을 label에 보여주는 Connect를 추가해보겠습니다.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTreeWidgetItem* headerItem = new QTreeWidgetItem;
    headerItem->setText(0, "Name");
    headerItem->setText(1, "Price");
    ui->treeWidget->setHeaderItem(headerItem);  // header

    QTreeWidgetItem* Parent = new QTreeWidgetItem(ui->treeWidget);
    Parent->setText(0, "Nintendo");

    QTreeWidgetItem* Child = new QTreeWidgetItem(Parent);
    Child->setText(0, "Zelda");
    Child->setText(1, "70000");

    connect(ui->treeWidget, &QTreeWidget::itemClicked, [&] (QTreeWidgetItem *item, int column) {
        QString sName = item->text(0);
        ui->lbTreeItemTitle->setText(sName);
    });
}

다음으로 Add Child Item, Delete Item 코드입니다.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTreeWidgetItem* headerItem = new QTreeWidgetItem;
    headerItem->setText(0, "Name");
    headerItem->setText(1, "Price");
    ui->treeWidget->setHeaderItem(headerItem);  // header

    QTreeWidgetItem* Parent = new QTreeWidgetItem(ui->treeWidget);
    Parent->setText(0, "Nintendo");

    QTreeWidgetItem* Child = new QTreeWidgetItem(Parent);
    Child->setText(0, "Zelda");
    Child->setText(1, "70000");

    connect(ui->treeWidget, &QTreeWidget::itemClicked, [&] (QTreeWidgetItem *item, int column) {
        QString sName = item->text(0);
        ui->lbTreeItemTitle->setText(sName);
    }); // Display Current Selected Item Name(Column = 0)

    connect(ui->pb_AddChild, &QPushButton::clicked, [&] {
        QTreeWidgetItem* pCurrentSelectedItem = ui->treeWidget->currentItem();
        if ( pCurrentSelectedItem == nullptr ) { return; }

        QTreeWidgetItem* pNewChild = new QTreeWidgetItem;
        pNewChild->setText(0, ui->le_ChildTitle->text());
        pCurrentSelectedItem->addChild(pNewChild);
    }); // Add Child Item

    connect(ui->pb_DeleteItem, &QPushButton::clicked, [&] {
        QTreeWidgetItem* pCurrentSelectedItem = ui->treeWidget->currentItem();
        if ( pCurrentSelectedItem == nullptr ) { return; }

        delete pCurrentSelectedItem;
    }); // Delete Current Item
}

다음은 Item을 접고 펼칠때마다 Column의 크기를 재 조정할 수 있는 기능입니다. 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTreeWidgetItem* headerItem = new QTreeWidgetItem;
    headerItem->setText(0, "Name");
    headerItem->setText(1, "Price");
    ui->treeWidget->setHeaderItem(headerItem);  // header

    QTreeWidgetItem* Parent = new QTreeWidgetItem(ui->treeWidget);
    Parent->setText(0, "Nintendo");

    QTreeWidgetItem* Child = new QTreeWidgetItem(Parent);
    Child->setText(0, "Zelda");
    Child->setText(1, "70000");

    connect(ui->treeWidget, &QTreeWidget::itemClicked, [&] (QTreeWidgetItem *item, int column) {
        QString sName = item->text(0);
        ui->lbTreeItemTitle->setText(sName);
    }); // Display Current Selected Item Name(Column = 0)

    connect(ui->pb_AddChild, &QPushButton::clicked, [&] {
        QTreeWidgetItem* pCurrentSelectedItem = ui->treeWidget->currentItem();
        if ( pCurrentSelectedItem == nullptr ) { return; }

        QTreeWidgetItem* pNewChild = new QTreeWidgetItem;
        pNewChild->setText(0, ui->le_ChildTitle->text());
        pCurrentSelectedItem->addChild(pNewChild);
    }); // Add Child Item

    connect(ui->pb_DeleteItem, &QPushButton::clicked, [&] {
        QTreeWidgetItem* pCurrentSelectedItem = ui->treeWidget->currentItem();
        if ( pCurrentSelectedItem == nullptr ) { return; }

        delete pCurrentSelectedItem;
    }); // Delete Current Item

    connect(ui->treeWidget, &QTreeWidget::itemExpanded, [&] (QTreeWidgetItem *item) {
        ui->treeWidget->resizeColumnToContents(0);
        ui->treeWidget->resizeColumnToContents(1);
    }); // Resize Columns

    connect(ui->treeWidget, &QTreeWidget::itemCollapsed, [&] (QTreeWidgetItem *item) {
        ui->treeWidget->resizeColumnToContents(0);
        ui->treeWidget->resizeColumnToContents(1);
    }); // Resize Columns
}

마지막으로 TreeWidgetItem에 체크박스를 추가하고 체크 상태에 따라 부모와 자식의 상태도 자동으로 변하는 기능입니다.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTreeWidgetItem* headerItem = new QTreeWidgetItem;
    headerItem->setText(0, "Name");
    headerItem->setText(1, "Price");
    ui->treeWidget->setHeaderItem(headerItem);  // header

    QTreeWidgetItem* Parent = new QTreeWidgetItem(ui->treeWidget);
    Parent->setCheckState(0, Qt::Unchecked);
    Parent->setFlags(Parent->flags() | Qt::ItemIsAutoTristate | Qt::ItemIsUserCheckable );
    Parent->setText(0, "Nintendo");

    QTreeWidgetItem* Child = new QTreeWidgetItem(Parent);
    Child->setFlags(Child->flags() | Qt::ItemIsUserCheckable );
    Child->setCheckState(0, Qt::Unchecked);
    Child->setText(0, "Zelda");
    Child->setText(1, "70000");

    Child = new QTreeWidgetItem(Parent);
    Child->setFlags(Child->flags() | Qt::ItemIsUserCheckable );
    Child->setCheckState(0, Qt::Unchecked);
    Child->setText(0, "Mario");
    Child->setText(1, "75000");

    Child = new QTreeWidgetItem(Parent);
    Child->setFlags(Child->flags() | Qt::ItemIsUserCheckable );
    Child->setCheckState(0, Qt::Unchecked);
    Child->setText(0, "Pockemon");
    Child->setText(1, "60000");

    connect(ui->treeWidget, &QTreeWidget::itemClicked, [&] (QTreeWidgetItem *item, int column) {
        QString sName = item->text(0);
        ui->lbTreeItemTitle->setText(sName);
    }); // Display Current Selected Item Name(Column = 0)

    connect(ui->pb_AddChild, &QPushButton::clicked, [&] {
        QTreeWidgetItem* pCurrentSelectedItem = ui->treeWidget->currentItem();
        if ( pCurrentSelectedItem == nullptr ) { return; }

        QTreeWidgetItem* pNewChild = new QTreeWidgetItem;
        pNewChild->setText(0, ui->le_ChildTitle->text());
        pCurrentSelectedItem->addChild(pNewChild);
    }); // Add Child Item

    connect(ui->pb_DeleteItem, &QPushButton::clicked, [&] {
        QTreeWidgetItem* pCurrentSelectedItem = ui->treeWidget->currentItem();
        if ( pCurrentSelectedItem == nullptr ) { return; }

        delete pCurrentSelectedItem;
    }); // Delete Current Item

    connect(ui->treeWidget, &QTreeWidget::itemExpanded, [&] (QTreeWidgetItem *item) {
        ui->treeWidget->resizeColumnToContents(0);
        ui->treeWidget->resizeColumnToContents(1);
    }); // Resize Columns

    connect(ui->treeWidget, &QTreeWidget::itemCollapsed, [&] (QTreeWidgetItem *item) {
        ui->treeWidget->resizeColumnToContents(0);
        ui->treeWidget->resizeColumnToContents(1);
    }); // Resize Columns
}

자식 Item에 Check 시에는 자식이 다수일 경우에는 Qt::PartiallyChecked이고 다 선택되면 Qt::Checked 상태 그리고 부모에서 Check 시에는 자식 Item이 모두 Qt::Checked 상태로 변하게 됩니다.

만약에 자식 item에는 checkbox를 두지 않고 싶으면 부모에 Qt::ItemIsAutoTristate는 제거하면 됩니다. 

728x90

+ Recent posts