diff --git a/Core/xmlobject.cpp b/Core/xmlobject.cpp
index 503a261ea708c52b4bad00f656a3162fcbddb5bc..d85f236718e527385aee98158e81e4e4e0ecfa0d 100644
--- a/Core/xmlobject.cpp
+++ b/Core/xmlobject.cpp
@@ -225,7 +225,7 @@ int XmlObject::attributeCount() const
     return attributes.count();
 }
 
-QMapIterator<QString, QString> XmlObject::attributesIterator()
+QMapIterator<QString, QString> XmlObject::attributesIterator() const
 {
     return QMapIterator<QString,QString>(attributes);
 }
diff --git a/Core/xmlobject.h b/Core/xmlobject.h
index 73505c8d9ee6e1d9010070b18b10b3f5b13c70bb..f075cf9493935734e219236c80733138b378b787 100644
--- a/Core/xmlobject.h
+++ b/Core/xmlobject.h
@@ -24,7 +24,7 @@ public:
     bool hasAttribute(const QString &name) const;
     int attributeCount() const;
 
-    QMapIterator<QString, QString> attributesIterator();
+    QMapIterator<QString, QString> attributesIterator() const;
 
     /*
      * Set the value of "value" if the attribute with name "name" exist and is an integer
diff --git a/Modules/TreeViewer/treevieweritem.cpp b/Modules/TreeViewer/treevieweritem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..211277c35a4c281e09e52bc316fc4a9f316c06ca
--- /dev/null
+++ b/Modules/TreeViewer/treevieweritem.cpp
@@ -0,0 +1,46 @@
+#include "treevieweritem.h"
+
+
+TreeViewerItem::TreeViewerItem() : QObject(), QTreeWidgetItem()
+{
+
+}
+
+TreeViewerItem::TreeViewerItem(const XmlObject &xml) : TreeViewerItem()
+{
+    this->xml = xml;
+    setText(0, xml.getObjectName());
+
+    int count = 1;
+    auto i = xml.attributesIterator();
+    while(i.hasNext()){
+        i.next();
+        // line = line + ", " + i.value() + " ("+i.key()+")";
+        setText(count, i.value());
+    }
+}
+
+TreeViewerItem::~TreeViewerItem()
+{
+
+}
+
+QList<QString> TreeViewerItem::getAttributesNameList() const
+{
+    QList<QString> list;
+    auto i = xml.attributesIterator();
+    while(i.hasNext()){
+        i.next();
+        list.append(i.key());
+    }
+    return list;
+}
+
+void TreeViewerItem::setAttributesColumn(QList<QString> headers)
+{
+    for(int column = 0; column < headers.count(); column++){
+        if(xml.hasAttribute(headers[column])){
+            setText(column, xml.getAttribute(headers[column]));
+        }
+    }
+}
diff --git a/Modules/TreeViewer/treevieweritem.h b/Modules/TreeViewer/treevieweritem.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9a90cd094bdef80d8adfff55283b0bb2685c439
--- /dev/null
+++ b/Modules/TreeViewer/treevieweritem.h
@@ -0,0 +1,22 @@
+#ifndef TREEVIEWERITEM_H
+#define TREEVIEWERITEM_H
+
+#include <QObject>
+#include <QTreeWidgetItem>
+#include "Core/xmlobject.h"
+
+class TreeViewerItem : public QObject, public QTreeWidgetItem
+{
+    Q_OBJECT
+public:
+    TreeViewerItem();
+    TreeViewerItem(const XmlObject &xml);
+    ~TreeViewerItem();
+
+    QList<QString> getAttributesNameList() const;
+    void setAttributesColumn(QList<QString> headers);
+private:
+    XmlObject xml;
+};
+
+#endif // TREEVIEWERITEM_H
diff --git a/Modules/TreeViewer/treeviewermodule.cpp b/Modules/TreeViewer/treeviewermodule.cpp
index 30f061cbc2fc80c7478897afc61fd1e2085cc93d..0c4e6d3773929010ead91e93dad2bce6fbefa5bc 100644
--- a/Modules/TreeViewer/treeviewermodule.cpp
+++ b/Modules/TreeViewer/treeviewermodule.cpp
@@ -1,17 +1,139 @@
 #include "treeviewermodule.h"
 #include "ui_treeviewermodule.h"
 
+#include <QLabel>
+#include <QDebug>
+#include <QTreeWidget>
+#include "Core/modulemessagesbroker.h"
+#include "treevieweritem.h"
+
 TreeViewerModule::TreeViewerModule(QWidget *parent) : DefaultModule(parent), ui(new Ui::TreeViewerModule)
 {
     ui->setupUi(this);
     defaultContextMenuSetup();
+    setupUI();
 }
 
 TreeViewerModule::~TreeViewerModule()
 {
     delete ui;
+    // The tree viewer items are deleted automatically with the ui QTreeWidget
+}
+
+void TreeViewerModule::setupUI()
+{
+    connect(ui->lineEdit_receivingTopic, &QLineEdit::textChanged, this, &TreeViewerModule::onLineEditTopicTextChanged);
+//    XmlObject test;
+//    test.fromXml("<Root>"
+//                     "<Child1 name='aaaa'>"
+//                         "<Child1.1/>"
+//                         "<Child1.2 name='boo1.2' attr1='provac1.2'/>"
+//                         "<Child1.3/>"
+//                     "</Child1>"
+//                     "<Child2 name='boo' attr1='provac2'/>"
+//                     "<Child3/>"
+//                 "</Root>"
+//                 "");
+
+    //showXmlTree(test);
+
+}
+
+void TreeViewerModule::showXmlTree(const XmlObject &xml)
+{
+    clearTree();
+    TreeViewerItem* root = createTreeItemFromXml(xml);
+    addItem(root);
+    headers.append("Object Name");
+    updateHeaders(root->getAttributesNameList());
+
+    for(int i = 0; i < xml.childCount(); i++){
+        addXmlItem(xml.childAt(i), root);
+    }
+
+    updateItemAttributesColumn();
+}
+
+void TreeViewerModule::addXmlItem(const XmlObject &xml, TreeViewerItem* parent)
+{
+    TreeViewerItem* item = createTreeItemFromXml(xml);
+    addItem(parent, item);
+    updateHeaders(item->getAttributesNameList());
+
+    for(int i = 0; i < xml.childCount(); i++){
+        addXmlItem(xml.childAt(i), item);
+    }
 }
 
+TreeViewerItem *TreeViewerModule::createTreeItemFromXml(const XmlObject &xml)
+{
+    return new TreeViewerItem(xml);
+}
+
+void TreeViewerModule::updateHeaders(const QList<QString> itemAttributes)
+{
+    bool updateHeader = false;
+    for(int i = 0; i < itemAttributes.count(); i++){
+        if(!headers.contains(itemAttributes[i])){
+            headers.append(itemAttributes[i]);
+            updateHeader = true;
+        }
+    }
+
+    if(updateHeader){
+        tree()->setColumnCount(headers.count());
+        tree()->setHeaderLabels(headers);
+    }
+}
+
+void TreeViewerModule::updateItemAttributesColumn()
+{
+    for(TreeViewerItem* item : items){
+        item->setAttributesColumn(headers);
+    }
+}
+
+void TreeViewerModule::setReceivingTopic(const QString &txt)
+{
+    getCore()->getModuleMessagesBroker()->unsubscribe(receivingTopic, this);
+    getCore()->getModuleMessagesBroker()->subscribe(txt, this, [this](const ModuleMessage &msg){
+        onMsgReceived(msg);
+    });
+
+    receivingTopic = txt;
+    if(ui->lineEdit_receivingTopic->text() != txt){
+        ui->lineEdit_receivingTopic->setText(txt);
+    }
+}
+
+void TreeViewerModule::onLineEditTopicTextChanged(const QString &txt)
+{
+    setReceivingTopic(txt);
+}
+
+void TreeViewerModule::clearTree()
+{
+    for(int i = 0; i < items.count(); i++){
+        delete items[i];
+    }
+    items.clear();
+
+    headers.clear();
+}
+
+QTreeWidget *TreeViewerModule::tree()
+{
+    return ui->treeWidget;
+}
+
+void TreeViewerModule::onMsgReceived(const ModuleMessage &msg)
+{
+    XmlObject xml;
+    xml.fromXml(msg.payload());
+    if(!xml.isEmpty()){
+        showXmlTree(xml);
+    }
+}
 
 QWidget *TreeViewerModule::toWidget()
 {
@@ -20,10 +142,39 @@ QWidget *TreeViewerModule::toWidget()
 
 XmlObject TreeViewerModule::toXmlObject()
 {
-    return XmlObject(getName(ModuleId::TREEVIEWER));
+    XmlObject xml(getName(ModuleId::TREEVIEWER));
+
+    if(receivingTopic != SkywardHubStrings::treeViewerReceivingBaseTopic){
+        xml.addAttribute("ReceivingTopic", receivingTopic);
+    }
+
+    return xml;
 }
 
 void TreeViewerModule::fromXmlObject(const XmlObject &xmlObject)
 {
-    Q_UNUSED(xmlObject);
+    QString attrName = "ReceivingTopic";
+    if(xmlObject.hasAttribute(attrName)){
+        setReceivingTopic(xmlObject.getAttribute(attrName));
+    }else{
+        setReceivingTopic(SkywardHubStrings::treeViewerReceivingBaseTopic);
+    }
+}
+
+void TreeViewerModule::addItem(TreeViewerItem *rootItem)
+{
+    tree()->addTopLevelItem(rootItem);
+    //tree()->setItemWidget(rootItem, 1, new QLabel(QString::number(i)));
+    items.insert(0,rootItem);
+}
+
+void TreeViewerModule::addItem(TreeViewerItem *parentItem, TreeViewerItem *childItem)
+{
+    if(parentItem != nullptr && childItem != nullptr){
+        parentItem->addChild(childItem);
+//        tree()->setItemWidget(item2, 1, new QLabel(QString::number(i)+"."+QString::number(c)));
+        items.insert(0,childItem);
+    }
 }
+
+
diff --git a/Modules/TreeViewer/treeviewermodule.h b/Modules/TreeViewer/treeviewermodule.h
index fdcd4bf5d3583d64cfef78b53ccd61843bbc98f6..7d9c2133d2556b6651c4605ba3437cbd1c661a8f 100644
--- a/Modules/TreeViewer/treeviewermodule.h
+++ b/Modules/TreeViewer/treeviewermodule.h
@@ -2,6 +2,11 @@
 #define TREEVIEWERMODULE_H
 
 #include "Modules/DefaultModule/defaultmodule.h"
+#include "Core/xmlobject.h"
+#include "Core/modulemessage.h"
+
+class QTreeWidget;
+class TreeViewerItem;
 
 namespace Ui {
 class TreeViewerModule;
@@ -20,8 +25,28 @@ public:
     XmlObject toXmlObject() override;
     void fromXmlObject(const XmlObject &xmlObject) override;
 
+protected:
+    void setupUI();
+    QTreeWidget *tree();
+
+    void onMsgReceived(const ModuleMessage &msg);
+    void addItem(TreeViewerItem* rootItem);
+    void addItem(TreeViewerItem *parentItem, TreeViewerItem* childItem);
+    void showXmlTree(const XmlObject &xml);
+    void addXmlItem(const XmlObject &xml, TreeViewerItem *parent);
+    TreeViewerItem* createTreeItemFromXml(const XmlObject &xml);
+    void updateHeaders(const QList<QString> itemAttributes);
+    void updateItemAttributesColumn();
+    void setReceivingTopic(const QString &txt);
+    void onLineEditTopicTextChanged(const QString &txt);
+    void clearTree();
+
 private:
     Ui::TreeViewerModule *ui;
+    QList<TreeViewerItem*> items;
+    QList<QString> headers;
+    QString receivingTopic = SkywardHubStrings::treeViewerReceivingBaseTopic;
 };
 
+
 #endif // TREEVIEWERMODULE_H
diff --git a/Modules/TreeViewer/treeviewermodule.ui b/Modules/TreeViewer/treeviewermodule.ui
index c36baefa78e84890293d57da8cb9324dbbb8150f..77bbe0df8764be69584a1b95fa191191669a1846 100644
--- a/Modules/TreeViewer/treeviewermodule.ui
+++ b/Modules/TreeViewer/treeviewermodule.ui
@@ -1,9 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <author/>
- <comment/>
- <exportmacro/>
  <class>TreeViewerModule</class>
- <widget name="TreeViewerModule" class="QWidget">
+ <widget class="QWidget" name="TreeViewerModule">
   <property name="geometry">
    <rect>
     <x>0</x>
@@ -15,7 +13,32 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTreeWidget" name="treeWidget">
+     <column>
+      <property name="text">
+       <string notr="true">1</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>Receiving Topic</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="lineEdit_receivingTopic"/>
+     </item>
+    </layout>
+   </item>
+  </layout>
  </widget>
- <pixmapfunction/>
+ <resources/>
  <connections/>
 </ui>
diff --git a/Modules/moduleslist.cpp b/Modules/moduleslist.cpp
index 26b63a0151f189022393e23195c3bc5111bd1f37..7885ea3cef83c6277876414ed7fb45b4ca7ef241 100644
--- a/Modules/moduleslist.cpp
+++ b/Modules/moduleslist.cpp
@@ -121,7 +121,6 @@ void ModulesList::createModuleList()
     treeViewer.addModuleSourceFiles("Modules/TreeViewer/");
     addModuleInfo(treeViewer);
     #endif
-
 }
 
 
diff --git a/Modules/skywardhubstrings.cpp b/Modules/skywardhubstrings.cpp
index d05c98caa1772b859a5b483613c0e41326d97797..9c12891b46df4b288b9bdb7b64c601d4ffe0a3bf 100644
--- a/Modules/skywardhubstrings.cpp
+++ b/Modules/skywardhubstrings.cpp
@@ -27,6 +27,7 @@ const QString SkywardHubStrings::imageViewerInfo = "Dobule click on a label to o
 // Topics
 const QString SkywardHubStrings::commandsTopic = "TelemetryCommand";
 const QString SkywardHubStrings::telemetryRequestTopic = "TelemetryRequest";
+const QString SkywardHubStrings::treeViewerReceivingBaseTopic = "TreeViewer";
 
 const QString SkywardHubStrings::logCommandsTopic = "LogCommands";
 const QString SkywardHubStrings::raw_event_id = "event_id";
diff --git a/Modules/skywardhubstrings.h b/Modules/skywardhubstrings.h
index fd3943875566130acf57c4a7abf8476c502c1caf..562e71399c5d0f1d614a7030cf86d1a9a8f027a9 100644
--- a/Modules/skywardhubstrings.h
+++ b/Modules/skywardhubstrings.h
@@ -33,6 +33,7 @@ public:
     // Topics
     static const QString commandsTopic;
     static const QString telemetryRequestTopic;
+    static const QString treeViewerReceivingBaseTopic;
 
     static const QString logCommandsTopic;
     static const QString raw_event_id;
diff --git a/SkywardHub.pro b/SkywardHub.pro
index 89fb89067b1c480d4211f9358d6de70f99c8e65d..c0364dbf5bf5dace0086a6063e8e0bc77232c6c4 100644
--- a/SkywardHub.pro
+++ b/SkywardHub.pro
@@ -55,6 +55,7 @@ SOURCES += \
     Modules/Splitter/splittermodule.cpp \
     Modules/Table/tablemodule.cpp \
     Modules/Test/testmodule.cpp \
+    Modules/TreeViewer/treevieweritem.cpp \
     Modules/TreeViewer/treeviewermodule.cpp \
     Modules/Utility/contextmenuseparator.cpp \
     Modules/Utility/modulespicker.cpp \
@@ -113,6 +114,7 @@ HEADERS += \
     Modules/Splitter/splittermodule.h \
     Modules/Table/tablemodule.h \
     Modules/Test/testmodule.h \
+    Modules/TreeViewer/treevieweritem.h \
     Modules/TreeViewer/treeviewermodule.h \
     Modules/Utility/contextmenuseparator.h \
     Modules/Utility/modulespicker.h \