1
votes

I have a table with 3 columns: {"Scanned","Qty", "Item"}. I am trying to highlight the particular row if the "Scanned" and "Qty" column value matches. I saw some posts which says to implement it in the following

data(const QModelIndex &index, int role) const

I have tried as follow to just change the background color of the table rows regardless but it does not seem to work as suggested:

QVariant TransitItemTableModel::data(const QModelIndex &index, int role) const
{
    switch (role) {
    case TableDataRow:
    {
        return table.at(index.row()).at(index.column());
    }
    case HeadingRow:
    {
        if (index.row() == 0) {
            return true;
        } else {
            return false;
        }
    }
    case Qt::BackgroundRole:
    {
        QBrush redBackground(Qt::green);
        return redBackground;

    }
    default:
        break;
    }

    return QVariant();
}

I am calling

emit dataChanged in the following code below:

bool TransitItemTableModel::setData(const QModelIndex &index, const QVariant &value,
                               int role)  {
    if (!index.isValid() || 
            index.row() < 0 || index.row() >= table.size())
        return false;

    QList<QString> list1 = value.value<QList<QString>>();
    QVector<QString> list2 = list1.toVector();

    table.replace(index.row(), list2);
    emit dataChanged(index, index, {TableDataRow});
    return true;
}

Just for additional info, I have the following roles defined:

enum TableRoles {
        TableDataRow = Qt::UserRole + 1,
        HeadingRow
    };

With regards to the QML code, I am using the following code for display as Table.qml and the lower portion of code shows part of the code using this Table.qml:

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

TableView {
    id: root
    anchors.fill: parent
    clip: true
    signal clicked(int row, int column)
    property var columnWidths: [0.5, 0.5]   // as fractions of parent width
                                            // preferably overwrite this when using
    columnWidthProvider: function (column) { return Math.max(parent.width * columnWidths[column], 1) }

    delegate: Rectangle {
        implicitHeight: text.implicitHeight
        border.color: "#dddddd"
        color: (heading==true)?"#dddddd":"white"
        Text {
            id: text
            text: tabledata
            width: parent.width
            wrapMode: Text.Wrap
            padding: 5
        }
        MouseArea{
            anchors.fill: parent
            onClicked: root.clicked(model.row, model.column)
        }
    }
}
Rectangle {
      color: "transparent"
      Layout.fillWidth: true
      Layout.preferredHeight: parent.height - 250

      Components.Table {
          model: _transitItemTableModelAPI
          columnWidths: [0.2, 0.15, 0.65]
      }
    }
1

1 Answers

1
votes

You should test the validity of your index:

if (index.isValid())
{
    if (role == Qt::DisplayRole)
    {
        return QString("hello data");
    }
    else if (role == Qt::BackgroundRole)
    {
        return QColor(Qt::lightGray);
    }
}

Other than that, your code should work fine. Can you see your data values? You shouldn't, as you are not returning data in case role is Qt::DisplayRole. Are you sure, you hooked your model to your QTableView with setModel();

EDIT: From the doc:

The optional roles argument can be used to specify which data roles have actually been modified. An empty vector in the roles argument means that all roles should be considered modified. The order of elements in the roles argument does not have any relevance.

emit dataChanged(index, index, {TableDataRow}); will not update the BackgroundRole.