Model/View Tutorial role question



  • The model/view tutorial in the docs loads data into a table.
    http://doc.qt.io/qt-5/modelview.html

    src @ examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp

    To get a better idea of how this works, I placed a qDebug() in the data method to see what role value was being passed in

    QVariant HTCModel::data(const QModelIndex &index, int role) const
    {
    
        int row = index.row();
            int col = index.column();
    
            switch(role){
            case Qt::DisplayRole:
                qDebug() << "role received = Qt::DisplayRole #" << role;
                if (row == 0 && col == 1) return QString("<--left");
                if (row == 1 && col == 1) return QString("right-->");
    
                return QString("Row%1, Column%2")
                        .arg(row + 1)
                        .arg(col +1);
                break;
            case Qt::FontRole:
                if (row == 0 && col == 0) //change font only for cell(0,0)
                {
    
                    qDebug() << "role received = Qt::FontRole #" << role;
                    QFont boldFont;
                    boldFont.setBold(true);
                    return boldFont;
                }
                break;
            case Qt::BackgroundRole:
    
                if (row == 1 && col == 2)  //change background only for cell(1,2)
                {
                    qDebug() << "role received = Qt::BackgroundRole #" << role;
                    QBrush redBackground(Qt::red);
                    return redBackground;
                }
                break;
            case Qt::TextAlignmentRole:
    
                if (row == 1 && col == 1) //change text alignment only for cell(1,1)
                {
                    qDebug() << "role received = Qt::TextAlignmentRole #" << role;
                    return Qt::AlignRight + Qt::AlignVCenter;
                }
                break;
            case Qt::CheckStateRole:
    
                if (row == 1 && col == 0) //add a checkbox to cell(1,0)
                {
                    qDebug() << "role received = Qt::CheckStateRole: #" << role;
                    return Qt::Checked;
                }
            }
            return QVariant();
    }
    

    role values of 0, 1, 6, 7, 8, 9, 10 are being passed in.
    Where is this value coming from?
    Is there an invisible random number generator running in this tutorial?



  • Is there an invisible random number generator running in this tutorial?

    No, it's the delegate that has to interrogate the model to know what to paint:

    • 0 = Qt::DisplayRole is the text in the cell
    • 1 = Qt::DecorationRole is the icon in the cell
    • 6 = Qt::FontRole is the font to use in the cell
    • 7 = Qt::TextAlignmentRole is the alignment of the text in the cell
    • 8 = Qt::BackgroundRole is the QBrush used to paint the background of the cell
    • 9 = Qt::ForegroundRole is the QBrush used to paint the text of the cell
    • 10 = Qt::CheckStateRole is the status of the checkbox in the cell

    See also: http://doc.qt.io/qt-5/qt.html#ItemDataRole-enum



  • I did a lookup as well to see what the enumerated values were for. The method is being called from somewhere as the arguments are being set. That's what I don't understand. What is calling MyModel::data with those argument values?
    I don't see that function called from anywhere in the tutorial and I don't see a connect signal/slot expression to set a delegate up.

    • mike

  • Lifetime Qt Champion

    Hi,

    The view(s) on which you set the model.



  • What is calling MyModel::data

    It's called in QStyledItemDelegate::initStyleOption (index.data(Role) is the same as index.model()->data(index,Role) if index.isValid()==true)

    I don't see that function called from anywhere in the tutorial and I don't see a connect signal/slot expression to set a delegate up.

    Any view has a defult delegate it's set in the constructor of the view: link to Qt Source



  • i don't get it. Here's what's in main
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    QTableView tableView;
    MyModel myModel(0);
    tableView.setModel( &myModel );
    tableView.show();
    return a.exec();
    }

    The only methods I see that would do anything are the initialization of the mymodel and the tableview.show() function.

    I have to assume that as the QAbstractTableModel's implemented functions for rowCount, columnCount are called as the view is created. and similarly data is also called from the view. So where's the iterator that determines what role is set to for each of the data calls?



  • The only methods I see that would do anything are the initialization of the mymodel and the tableview.show() function.

    Quite the opposite:

    1. QTableView tableView; calls the constructor of QTableView
    2. the costructor calls the base class constructor
    3. that construcor calls the init() method that creates the delegate q->setItemDelegate(new QStyledItemDelegate(q));
    4. When the view needs to repaint it calls QStyledItemDelegate::paint
    5. paint() calls QStyledItemDelegate::initStyleOption
    6. inside that fuction you can see the calls to index.data(Qt::FontRole);, index.data(Qt::TextAlignmentRole);, etc.

    So where's the iterator that determines what role is set to for each of the data calls?

    There's no iterator they are hard coded.



  • So it's built into the Qt base library then.

    I noticed also that any time the table gets clicked that method must get called again because I get another complete set of qDebug() messages. So paint() makes sense then as to why that happens.

    Thanks


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.