Emanuele
Emanuele

Reputation: 2394

How to properly show QIcon on a QTreeWidget child?

I successfully managed to show a QIcon on the TopLevelItem. But the problem comes when to add the icon on the children, how do I do that?

Below a snippet from the example I am building:

mainwindow.cpp

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

    QTreeWidgetItem *top1 = new QTreeWidgetItem({ "Images" });
    QTreeWidgetItem *top2 = new QTreeWidgetItem({ "Path" });
    QTreeWidgetItem *top3 = new QTreeWidgetItem({ "Segmentation" });

    QList<QTreeWidgetItem*> children1;
    QList<QTreeWidgetItem*> children2;
    QList<QTreeWidgetItem*> children3;

    children1.append(new QTreeWidgetItem({ "Original" }));
    children1.append(new QTreeWidgetItem({ "Sample" }));
    children1.append(new QTreeWidgetItem({ "Black/White" }));

    children2.append(new QTreeWidgetItem({ "Left Side" }));
    children2.append(new QTreeWidgetItem({ "Right Side" }));
    children2.append(new QTreeWidgetItem({ "Center Side" }));

    children3.append(new QTreeWidgetItem({ "Edge Detection" }));
    children3.append(new QTreeWidgetItem({ "Clustering" }));
    children3.append(new QTreeWidgetItem({ "Region-Based" }));
    children3.append(new QTreeWidgetItem({ "Mask RNN" }));

    top1->addChildren(children1);
    top1->setIcon(0, QIcon("/home/ultrasound_mapper/laserscan.png"));
    top2->addChildren(children2);
    top2->setIcon(0, QIcon("/home/ultrasound_mapper/laserscan.png"));
    top3->addChildren(children3);
    top3->setIcon(0, QIcon("/home/ultrasound_mapper/laserscan.png"));

    ui->treeWidget->addTopLevelItems({ top1, top2, top3 });

}

What I have done so far:

I went through the following post which helped me with managing the icon for the TopLevelItem but when I tried to do the same for the children I didn't have the same luck.

I used a QList to take care of all the children in the following way :

QList<QTreeWidgetItem*> children1;

I am now wondering if that could be a good way to proceed since no icon where added. Of course I tried the following but didn't work:

children1->setIcon(0, QIcon("/home/ultrasound_mapper/laserscan.png"));

Because setIcon is not a member function among the choices and am wondering if there is a more detailed procedure to do that.

I also used this, this but none of them was useful to do that.

Thanks for pointing in the right direction to solve this problem.

Upvotes: 0

Views: 495

Answers (1)

scopchanov
scopchanov

Reputation: 8419

Answer to your question

To access the children of an item you need to use QTreeWidgetItem::child:

top1->child(0)->setIcon(0, QIcon("/home/ultrasound_mapper/laserscan.png"));

Proper solution

That being said, I would approach the problem in another way.

I would create a helper function, e.g.:

QTreeWidgetItem *createItem(const QString &name, const QString &iconPath)
{
    auto *item = new QTreeWidgetItem(name);

    item->setIcon(0, QIcon(iconPath));

    return item;
}

Then I would use it like that:

top1->addChild(createItem("Original", "/home/ultrasound_mapper/laserscan.png"));
top1->addChild(createItem("Sample", "/home/ultrasound_mapper/laserscan.png"));
...

And there is no need to keep a list with the children, as they are accissible through the child method.

Example

Here is how to apply the proposed solution in your case:

auto *top1 = createItem("Images", "/home/ultrasound_mapper/laserscan.png");
auto *top2 = createItem("Path", "/home/ultrasound_mapper/laserscan.png");
auto *top2 = createItem("Segmentation", "/home/ultrasound_mapper/laserscan.png");

top1->addChild(createItem("Original", "/home/ultrasound_mapper/laserscan.png"));
top1->addChild(createItem("Sample", "/home/ultrasound_mapper/laserscan.png"));
top1->addChild(createItem("Black/White", "/home/ultrasound_mapper/laserscan.png"));

top2->addChild(createItem("Left Side", "/home/ultrasound_mapper/laserscan.png"));
top2->addChild(createItem("Right Side", "/home/ultrasound_mapper/laserscan.png"));
top2->addChild(createItem("Center Side", "/home/ultrasound_mapper/laserscan.png"));

top3->addChild(createItem("Edge Detection", "/home/ultrasound_mapper/laserscan.png"));
top3->addChild(createItem("Clustering", "/home/ultrasound_mapper/laserscan.png"));
top3->addChild(createItem("Region-Based", "/home/ultrasound_mapper/laserscan.png"));
top3->addChild(createItem("Mask RNN", "/home/ultrasound_mapper/laserscan.png"));

ui->treeWidget->addTopLevelItems({ top1, top2, top3 });

As you see, the code has become cleaner and more maintainable.

Note: Of course you could put the correct images. However, if you indend to use only one image, then you can omit the iconPath parameter and set a fixed image as an icon.

Upvotes: 1

Related Questions