Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] qml: problem with TableView refresh on model update
Forum Updated to NodeBB v4.3 + New Features

[Solved] qml: problem with TableView refresh on model update

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 3 Posters 7.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • _ Offline
    _ Offline
    _rth_
    wrote on 30 Jan 2015, 13:47 last edited by
    #1

    Hello everyone!

    I have simple QML app with TableView on screen. This view displays data from my custom model - derived from QAbstractTableModel:

    @#include "pswlistmodel.h"
    #include <QDebug>

    PswListModel::PswListModel(QObject parent)
    : QAbstractTableModel(parent)
    , hidePsws(true)
    {
    //test
    for (int i=0; i<10; ++i)
    {
    PswElement
    e = new PswElement();
    e->login = "login " + QString::number(i);
    e->name = "name " + QString::number(i);
    e->password = "password " + QString::number(i);
    this->elements.append(e);
    }
    }

    PswListModel::~PswListModel()
    {
    qDeleteAll(this->elements);
    this->elements.clear();
    }

    int PswListModel::rowCount(const QModelIndex& /parent/) const
    {
    return this->elements.size();
    }

    int PswListModel::columnCount(const QModelIndex& /parent/) const
    {
    return 3;
    }

    QVariant PswListModel::data(const QModelIndex& index, int role) const
    {
    if (this->elements.isEmpty())
    return QVariant();

    if (index.row() >= this->elements.size())
        return QVariant();
    
    
    PswElement *e = this->elements[index.row()];
    
    if (role == Qt::DisplayRole)
    {
        //name
        if (index.column() == 0)
            return e->name;
    
        //login
        if (index.column() == 1)
            return e->login;
    
        //password
        if (index.column() == 2)
        {
            if (!this->hidePsws)
                return e->password;
            else
                return "***";
        }
    }
    else if (role == PswNameRole)
        return e->name;
    else if (role == PswLoginRole)
        return e->login;
    else if (role == PswPswRole)
    {
        qDebug() << "get psw (" << index.row() << "), hide: " << this->hidePsws;
        if (!this->hidePsws)
            return e->password;
        else
            return "***";
    }
    
    return QVariant();
    

    }

    QVariant PswListModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
    if (orientation == Qt::Horizontal)
    {
    if (role == Qt::DisplayRole)
    {
    if (section == 0)
    return QString("Name");
    else if (section == 1)
    return QString("Login");
    else if (section == 2)
    return QString("Password");
    }
    else if (role == PswNameRole)
    return "Name";
    else if (role == PswLoginRole)
    return "Login";
    else if (role == PswPswRole)
    return "Password";
    }
    else
    if (orientation == Qt::Vertical)
    return QString();

    return QVariant::Invalid;
    

    }

    QHash<int, QByteArray> PswListModel::roleNames() const
    {
    QHash<int, QByteArray> roles;
    roles[PswNameRole] = "name";
    roles[PswLoginRole] = "login";
    roles[PswPswRole] = "password";
    return roles;
    }

    void PswListModel::showPasswords(bool value)
    {
    qDebug() << "showPasswords: " << value;
    this->hidePsws = value;

    QModelIndex idTop = QAbstractTableModel::index(0, 0);
    QModelIndex idBottom = QAbstractTableModel::index(this->elements.size(), 4);
    
    emit dataChanged(idTop, idBottom);
    

    }@

    TableView in qml works fine, it displays all data from model.

    Now there is CheckBox in qml screen for toggling passwords. When state changes I am calling PswListModel::showPasswords from my custom model (from qDebug, I can see that value is changing). This should toggle the passwords visibility from "***" to real passwords. However, even if emitting dataChanged signal, TableView view in qlm is not refreshed.

    I am using Qt is 5.4.0, QtQuick 2.4 and QtQuick.Controls 1.3. Platform: Windows 7.

    Thanks in advance.

    1 Reply Last reply
    0
    • P Offline
      P Offline
      p3c0
      Moderators
      wrote on 31 Jan 2015, 13:08 last edited by
      #2

      Hi,
      @
      QModelIndex idTop = QAbstractTableModel::index(0, 0);
      QModelIndex idBottom = QAbstractTableModel::index(this->elements.size(), 4);
      @

      I think since idTop starts from 0, idBottom should be 1 less.

      157

      1 Reply Last reply
      0
      • _ Offline
        _ Offline
        _rth_
        wrote on 2 Feb 2015, 11:26 last edited by
        #3

        Good point. Unfortunately that didn't help. Even if the range is correct (from elements.size()-1 to 3), table view in qml is not updated. This approach seems to be wrong.

        I finally figured it out:

        @void PswListModel::showPasswords(bool value)
        {
        qDebug() << "showPasswords: " << value;
        this->showPsws = value;

        this->beginResetModel();
        this->endResetModel();
        

        } @

        Reseting model invokes update of table in qml.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andreaplanet
          wrote on 3 Feb 2015, 23:48 last edited by
          #4

          you may could tell the view that your data changed instead of resetting the whole model. You can specify which data. Here for the whole table:

          @emit dataChanged(index(0,0), index(rowCount()-1,columnCount()-1));@

          1 Reply Last reply
          0
          • _ Offline
            _ Offline
            _rth_
            wrote on 5 Feb 2015, 15:26 last edited by
            #5

            That was my original problem: emitting dataChanged signal didn't refreshed the TableView.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andreaplanet
              wrote on 5 Feb 2015, 17:59 last edited by
              #6

              uhm. dataChanged works. There is something wrong elsewhere.
              index in dataChanged is wrong, not only elementsSize()-1 but also for the columns you are using 4 instead of 2. That could be a reason.

              Did you tried to see if data is invoked after the call to showPasswords.

              Also in showPassword you are updating this->showPsws while in data you are using this->hidePsws. Could be that data is called but you are returing always the same value.

              1 Reply Last reply
              0

              1/6

              30 Jan 2015, 13:47

              • Login

              • Login or register to search.
              1 out of 6
              • First post
                1/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved