title: How to avoid to delete treemodel info when editing?
body: <p>Good morning. I have finally created a treeconfig program to read a txt, then edit it in the interface, and then save it, but I have a problem.</p>
  
  <p>I know that there is a treemodel example that is editable (<a href="http://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html" rel="nofollow noreferrer">http://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html</a>), but this one is not using libconfig.h++</p>
  
  <p>I decided to use libconfig.h++ in my linux because I can filter which kind of information is appearing in the values (int/string/...), because in the other example without libconfig, it uses qVariant, and accept all the types of inputs.</p>
  
  <p>So even comparing with the other example, I am not able to make the following work:
  My problem is that when I try to edit one value, the information inside dissapears, and if I click outside the value, it becomes 0. How can I avoid this both things? I want to edit a string in the middle for example, or just not to delete then info when missclicking or something.</p>
  
  <p>The images below show an attempt at editing the value for confTimeout. Note that the text inside disappears when it is clicked into edit-mode <em>and</em> that the text sets to 0 when it is clicked out of focus.</p>
  
  <p><img src="https://i.stack.imgur.com/eMHYc.png" alt=""></p>
  
  <p><img src="https://i.stack.imgur.com/w9HD7.png" alt=""></p>
  
  <p><img src="https://i.stack.imgur.com/O1WI2.png" alt=""></p>
  
  <p>mainwindow.cpp</p>
  
  <pre><code>#include "mainwindow.h"
  #include "ui_mainwindow.h"
  
  #include &lt;QTextStream&gt;
  
  MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent),
      ui(new Ui::MainWindow)
  {
      ui-&gt;setupUi(this);
  }
  
  void MainWindow::setConfig(libconfig::Config *config)
  {
      tm = std::make_unique&lt;TreeModel&gt;(config, this);
      ui-&gt;treeView-&gt;setModel(tm.get());
  }
  
  MainWindow::~MainWindow()
  {
      delete ui;
  }
  
  /*
  void MainWindow::on_treeView_activated(const QModelIndex &amp;index)
  {
      QString val = ui-&gt;treeView-&gt;model()-&gt;data(index).toString();
      ui-&gt;lineEdit-&gt;setText(val);
  }
  
  */
  
  void MainWindow::on_pushButton_clicked()
  {
      tm-&gt;saveSettings();
  }
  </code></pre>
  
  <p>treeitem.cpp</p>
  
  <pre><code>#include "treeitem.h"
  #include &lt;libconfig.h++&gt;
  
  static QVariant getIndexOrName(const libconfig::Setting &amp;setting)
  {
      if (!setting.isRoot()) {
          const auto &amp;parent = setting.getParent();
          if (parent.isArray() || parent.isList())
              return setting.getIndex();
      }
  
      return setting.getName();
  }
  
  static QVariant getValueOrSize(const libconfig::Setting &amp;setting)
  {
      using namespace libconfig;
      switch (setting.getType()) {
      // scalar types
      case Setting::TypeInt:
          return setting.operator int();
  
      case Setting::TypeInt64:
          return setting.operator long long();
  
      case Setting::TypeFloat:
          return setting.operator double();
  
      case Setting::TypeString:
          return setting.c_str();
  
      case Setting::TypeBoolean:
          return setting.operator bool();
  
  
      // aggregate types
      case Setting::TypeGroup:
          return QString{"Group. Size: %1"}.arg(setting.getLength());
  
      case Setting::TypeArray:
          return QString{"Array. Size: %1"}.arg(setting.getLength());
  
      case Setting::TypeList:
          return QString{"List. Size: %1"}.arg(setting.getLength());
  
  
      // not used
      case Setting::TypeNone:
          break;
      }
  
      return QVariant{};
  }
  
  static bool setValue(libconfig::Setting &amp;setting, const QVariant &amp;value)
  {
      using namespace libconfig;
      switch (setting.getType()) {
      // scalar types
      case Setting::TypeInt:
          if (value.canConvert(QVariant::Int)) {
              setting = value.toInt();
              return true;
          }
      case Setting::TypeInt64:
          if (value.canConvert(QVariant::LongLong)) {
              setting = value.toLongLong();
              return true;
          }
      case Setting::TypeFloat:
          if (value.canConvert(QVariant::Double)) {
              setting = value.toFloat();
              return true;
          }
      case Setting::TypeString:
          if (value.canConvert(QVariant::String)) {
              setting = value.toString().toStdString();
              return true;
          }
      case Setting::TypeBoolean:
          if (value.canConvert(QVariant::Bool)) {
              setting = value.toBool();
              return true;
          }
      default:
          break;
      }
  
      return false;
  }
  
  TreeItem::TreeItem(libconfig::Setting *setting, TreeItem *parentItem)
      : m_setting{setting}, m_parentItem{parentItem}
  {
      if (setting-&gt;isAggregate()) {
          for (auto &amp;setting : *setting) {
              m_subSettings.push_back(new TreeItem(&amp;setting, this));
          }
      }
  }
  
  TreeItem::~TreeItem() { qDeleteAll(m_subSettings); }
  
  TreeItem *TreeItem::child(int row) { return m_subSettings.at(row); }
  
  int TreeItem::childCount() const { return m_subSettings.size(); }
  
  int TreeItem::columnCount() const { return 2; }
  
  QVariant TreeItem::data(int column) const
  {
      switch (column) {
      case 0:
          return getIndexOrName(*m_setting);
      case 1:
          return getValueOrSize(*m_setting);
      default:
          return QVariant{};
      }
  }
  
  bool TreeItem::setData(const QVariant &amp;value)
  {
      if (m_setting-&gt;isAggregate())
          return false;
  
      return setValue(*m_setting, value);
  }
  
  int TreeItem::row() const
  {
      if (!m_parentItem)
          return 0;
  
      return m_parentItem-&gt;m_subSettings.indexOf(const_cast&lt;TreeItem *&gt;(this));
  }
  
  TreeItem *TreeItem::parentItem() { return m_parentItem; }
  </code></pre>
  
  <p>treemodel</p>
  
  <pre><code>    #include "treemodel.h"
      #include "treeitem.h"
  
      #include &lt;QFile&gt;
      #include &lt;libconfig.h++&gt;
      #include &lt;QDateTime&gt;
  
      TreeModel::TreeModel(libconfig::Config *config, QObject *parent)
          : QAbstractItemModel{parent}, m_rootSetting{std::make_unique&lt;TreeItem&gt;(
                                                          &amp;(config-&gt;getRoot()), nullptr)}, m_config{config}
      {
      }
  
      TreeModel::~TreeModel()
      {
      }
  
      QVariant TreeModel::data(const QModelIndex &amp;index, int role) const
      {
          if (!index.isValid())
              return QVariant();
  
          if (role != Qt::DisplayRole)
              return QVariant();
  
          TreeItem *item = static_cast&lt;TreeItem*&gt;(index.internalPointer());
  
          return item-&gt;data(index.column());
      }
  
      bool TreeModel::setData(const QModelIndex &amp;index, const QVariant &amp;value, int role)
      {
          if (!index.isValid())
              return false;
  
          if (role != Qt::EditRole)
              return false;
  
          TreeItem *item = static_cast&lt;TreeItem*&gt;(index.internalPointer());
          return item-&gt;setData(value);
      }
  
      Qt::ItemFlags TreeModel::flags(const QModelIndex &amp;index) const
      {
  
          if (!index.isValid())
              //return Qt::NoItemFlags;
              return 0;
  
          //return QAbstractItemModel::flags(index);
          return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
      }
  
      QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
                                     int role) const
      {
          if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
              return QVariant{};
  
          switch (section) {
          case 0:
              return "Name";
          case 1:
              return "Value";
          default:
              return QVariant{};
          }
      }
  
  QModelIndex TreeModel::index(int row, int column,
                               const QModelIndex &amp;parent) const
  {
      if (!hasIndex(row, column, parent))
          return QModelIndex();
  
      TreeItem *parentItem;
  
      if (!parent.isValid())
          parentItem = m_rootSetting.get();
      else
          parentItem = static_cast&lt;TreeItem*&gt;(parent.internalPointer());
  
      TreeItem *childItem = parentItem-&gt;child(row);
      if (childItem)
          return createIndex(row, column, childItem);
      else
          return QModelIndex();
  }
  
  QModelIndex TreeModel::parent(const QModelIndex &amp;index) const
  {
      if (!index.isValid())
          return QModelIndex();
  
      TreeItem *childItem = static_cast&lt;TreeItem *&gt;(index.internalPointer());
      TreeItem *parentItem = childItem-&gt;parentItem();
  
      if (parentItem == m_rootSetting.get())
          return QModelIndex();
  
      return createIndex(parentItem-&gt;row(), 0, parentItem);
  }
  
  int TreeModel::rowCount(const QModelIndex &amp;parent) const
  {
      TreeItem *parentItem;
      if (parent.column() &gt; 0)
          return 0;
  
      if (!parent.isValid())
          parentItem = m_rootSetting.get();
      else
          parentItem = static_cast&lt;TreeItem*&gt;(parent.internalPointer());
  
      return parentItem-&gt;childCount();
  }
  
  int TreeModel::columnCount(const QModelIndex &amp;parent) const
  {
      if (parent.isValid())
          return static_cast&lt;TreeItem*&gt;(parent.internalPointer())-&gt;columnCount();
      else
          return m_rootSetting-&gt;columnCount();
  }
  
  bool TreeModel::saveSettings(QString filename) const
  {
      if (filename.isEmpty())
          filename = QString::fromLocal8Bit(m_config-&gt;getRoot().getSourceFile());
      QString today = QDateTime::currentDateTime().toString("_yyyy.MM.dd_hh:mm");
      QFile::copy(filename, filename+today+".backup");
      try {
          m_config-&gt;writeFile(filename.toLocal8Bit().constData());
      } catch (...) {
          return false;
      }
  
      return true;
  }
  </code></pre>
  
  <p>o</p>
  
  <p>o</p>
  
  <p>o</p>
  
  <p>o</p>
  
  <p>EDIT:::</p>
  
  <p>First of all, thanks @vahancho and @trebuchetMS
  .
  I have tried with vahancho example, but it throws an issue</p>
  
  <p><a href="https://i.stack.imgur.com/eMHYc.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/eMHYc.png" alt="enter image description here"></a></p>
  
  <p>Also I tried with with other combinations, but he idea is not to allow for example a "string" where a "int" should be placed.</p>
  
  <p>I have also checked again the editableTreeModel of QtExamples, but it allows a string where a int should be placed, and I do not want this</p>
  
  <pre><code>QVariant TreeModel::data(const QModelIndex &amp;index, int role) const
  {
      if (!index.isValid())
          return QVariant();
  
      if (role != Qt::DisplayRole &amp;&amp; role != Qt::EditRole)
          return QVariant();
  
      TreeItem *item = getItem(index);
  
      return item-&gt;data(index.column());
  }
  </code></pre>
  
  <p>Any idea?</p>