Important: Please read the Qt Code of Conduct -

SqlModel::data() - select based on value in other cells

  • I made a new SqlModel based on QSqlQueryModel, and a new data() function to color rows, and colums.

    The way updating of a view model works in Qt, is that all events involving a cell trigger a call to data() on all cells in the view.

    So for example to alternate backround color on the rows, you just tell it to paint odd and even row number in different color.

    In my own data() function i have added code to paint background color on specific rows - and i can say things like

    if(role == Qt::BackgroundRole && index.row() == 1){
        return QVariant(QColor(Qt::yellow));

    to paint a specific row yellow.

    But what if I want to only paint that row yellow if column 2 on the same row has the value of "completed" ????

    The available index passed to the data() function, is only referring to the cell I'm on, and i have no access to evaluate other cells.

    I want to be able to evaluate other cells, check on their content before painting the current cell i'm on.

    How in the world to i do that ??

    I can only think of very messy ways of doing it, and I really need to know what the proper way of doing this is.

    [Edit: Continues from here ~kshegunov]

  • Well, I just wrote my way out of it, creating a new index - just to make it work.

    Did not have time to wait for someone to come up with a better way. If you have a better way of doing it, please let me know. The code below is working, but its just seems messy to me.

    QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
         // Its possible to get to the model from the index, so i create 
         // a new pointer to the model
         const QAbstractItemModel * model = index.model();
        // I use the new model pointer to create a new index 
        // to a cell I want to evaluate
        QModelIndex index2 = model->index(index.row(), 1, QModelIndex()); 
        // Index2 is now pointing to the 2nd cell on the current row
        QVariant value2 = QSqlQueryModel::data(index2, Qt::DisplayRole);
        // I can now test the content in that cell, and see if it is blank
        if(value2.toString() == "" && role == Qt::BackgroundRole) {
            // if it is blank i set the background color
            return QVariant(QColor(Qt::yellow));
        // if this is not background role, it is data display role, 
        // and i have to return the content value of the cell
        QVariant value = QSqlQueryModel::data(index, role);
        return value;

  • Moderators

    @A.K.G. said in SqlModel::data() - select based on value in other cells:

    The code below is working, but its just seems messy to me.

    Nope. That's what I'd have suggested.

  • @kshegunov Thank you for the help!! Now if this gets more complex, and it will because I have tons of things going on in my views, and lots of records in hundreds of columns... then I wonder if I can make it more efficient. The point being that the view runs this code on every single cell, every time anything at all happens with the view. In other words, you click on a cell, then all the cells are reset with this code.

    As long as I only have the little bit of code shown in these examples, it does not matter, but when the views have picture and there is a lot more going on, I'm worried that it will be slow. I therefor am trying to keep focus on making this as fast as possible from the start.

    Any ideas ?? Or is there no way to make this faster - less repetitive / doing less on every cell ??

  • This is what i ended up doing:

        QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
            if (role == Qt::BackgroundRole && QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole).toString().isEmpty()){
                return QColor(Qt::yellow);
            return QSqlQueryModel::data(index, role);

Log in to reply