Results 1 to 10 of 10

Thread: Change SqlQueryModel QTableView's Row Color

  1. #1
    Join Date
    May 2014
    Location
    Washington D.C. area
    Posts
    7
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Change SqlQueryModel QTableView's Row Color

    Dear All:

    New to Qt - and have created a Tableview from a SqlQuery Model. Problem is - If the Validity Column is > 1 I want
    the entire row to be red...
    I tried something like this but nothing happened...

    Qt Code:
    1. void Edit_Log_Dialog::chk_Valid_Log_Line()
    2. {
    3. QModelIndex chk_line;
    4. QColor rowColor = Qt::red;
    5. int validity;
    6. for (int row = 1; row < current_Log_View->model()->rowCount(); row++)
    7. {
    8. chk_line = current_Log_View->model()->index(row,7);
    9. validity = rfa_Log_Model->data(chk_line, Qt::DisplayRole).toInt();
    10. if (validity > 1)
    11. {
    12. for (int i = 1; i< 8; i++)
    13. {
    14. chk_line = current_Log_View->model()->index(row,i);
    15. rfa_Log_Model->setData(chk_line,rowColor,Qt::ForegroundRole);
    16. }
    17. }
    18. }
    19. }
    To copy to clipboard, switch view to plain text mode 

    I saw something about using QItemDelegate - but wondered if there was an easier way to do this, or do I have to create a subclass
    or something - which I am a bit fuzzy about.

    Thanks, Tb

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Why are you indexing all of your rows and columns starting at "1" instead of zero?

    Why are you using two different models? (current_Log_View->model() and rfa_Log_Model) A QModelIndex retrieved from one model cannot be used to access another model.

    Why are you using Qt::ForegroundRole (which sets the brush used for drawing text) instead of Qt::BackgroundRole (which sets the brush used to fill the background of the table cells)?

    Both foreground and background roles expect a QBrush reference to be passed in the QAbstractItemModel::setData() call, not a QColor.

  3. #3
    Join Date
    May 2014
    Location
    Washington D.C. area
    Posts
    7
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Thanks for the response...

    I'm not sure why I though I needed to start at 1, makes sense that the index's would start at zero.

    The Current_Log_View model IS the rfa_Log_Model. I copied that from code where I was changing the values in the model to reflect something that was changed by the user, so
    though I needed to point at the model and change it's attributes. Since I am really trying to change the view are you saying I should have Current_Log_View->model()->setData(index,..)?

    Tried both Foreground Role and Background Role but neither one seemed to change what the output of the view looked like....

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Current_Log_View model IS the rfa_Log_Model
    Then use rfa_Log_Model only. It doesn't make sense to keep retrieving the model from the view when you already have a pointer to it in rfa_Log_Model.

    Tried both Foreground Role and Background Role but neither one seemed to change what the output of the view looked like....
    And you're setting the color on the model as a QBrush and not a QColor?

    Try calling either QAbstractItemView::reset() or QAbstractItemView::update() although changing the model data should result in this being broadcast to any views.

  5. #5
    Join Date
    May 2014
    Location
    Washington D.C. area
    Posts
    7
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Ok. so I have messed with the CustomSqlQuery examples I saw, and found that it changes the column color depending on a particular column number. I can change it to do it for a row,
    by changing the if to change based on row instead of column but that only work for a specific integer number (row count).
    When I try to figure out a specific value to look for (like 103 on the first column) and change to color for that row only, then it doesn't work as expected. Sometimes
    it gives me a red color, but it depends on which column I am pointing in. Ie., if the last column I accessed was 104 - then it will paint something on that row normal, but If
    I point at column with 103, then click in an entry on the same row , they turn red. At first they were red....

    Is there an example that someone can point me to where you have a column - which when it is say greater than 1 - then this entire row should be red... otherwise it should be the default color.

    Thanks.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Here is a very simple QAbstractTableModel-based example that will color an entire row based on the value in the cell in a particular column.

    Qt Code:
    1. // main.cpp
    2.  
    3. #include "TableTestDlg.h"
    4. #include <QtWidgets/QApplication>
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QApplication a(argc, argv);
    9. TableTestDlg w;
    10. w.show();
    11. return a.exec();
    12. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // TableTestDlg.h
    2.  
    3. #ifndef TABLETEST_H
    4. #define TABLETEST_H
    5.  
    6. #include <QtWidgets/QDialog>
    7.  
    8. class QTableView;
    9. class TableModel;
    10.  
    11. class TableTestDlg : public QDialog
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. TableTestDlg(QWidget *parent = 0);
    17. ~TableTestDlg();
    18.  
    19. private:
    20. TableModel * mpModel;
    21. QTableView * mpView;
    22. };
    23.  
    24. #endif // TABLETEST_H
    25.  
    26. // TableTestDlg.cpp
    27.  
    28. #include "TableTestDlg.h"
    29. #include "TableModel.h"
    30.  
    31. #include <QTableView>
    32. #include <QHBoxLayout>
    33.  
    34. TableTestDlg::TableTestDlg(QWidget *parent)
    35. : QDialog(parent)
    36. {
    37. mpModel = new TableModel( this );
    38. mpView = new QTableView( this );
    39. mpView->setModel( mpModel );
    40.  
    41. QHBoxLayout * pLayout = new QHBoxLayout( this );
    42. pLayout->addWidget( mpView );
    43. setLayout( pLayout );
    44. }
    45.  
    46. TableTestDlg::~TableTestDlg()
    47. {
    48. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // TableModel.h
    2.  
    3. #ifndef TABLEMODEL_H
    4. #define TABLEMODEL_H
    5.  
    6. #include <QAbstractTableModel>
    7. #include <QVector>
    8.  
    9. class TableModel : public QAbstractTableModel
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. TableModel(QObject *parent);
    15. ~TableModel();
    16.  
    17. virtual int rowCount( const QModelIndex & parent = QModelIndex() ) const;
    18. virtual int columnCount( const QModelIndex & parent = QModelIndex() ) const;
    19. virtual QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const;
    20.  
    21. private:
    22. QVector< int > mRowData;
    23. };
    24.  
    25. #endif // TABLEMODEL_H
    26.  
    27. // TableModel.cpp
    28.  
    29. #include "TableModel.h"
    30. #include <QBrush>
    31.  
    32. static int sRowCount = 42;
    33. static int sColumnCount = 4;
    34. static int sNumberColumn = 1;
    35.  
    36. TableModel::TableModel(QObject *parent)
    37. {
    38. mRowData.resize( sRowCount );
    39.  
    40. // Set data to an integer - 0, 1, or 2
    41. for ( int nRow = 0; nRow < sRowCount; ++nRow )
    42. mRowData[ nRow ] = int( 3.0 * double( qrand() ) / double( RAND_MAX ) );
    43. }
    44.  
    45. TableModel::~TableModel()
    46. {
    47. }
    48.  
    49. int TableModel::rowCount( const QModelIndex & parent /*= QModelIndex() */ ) const
    50. {
    51. if ( parent.isValid() )
    52. return 0;
    53. return sRowCount;
    54. }
    55.  
    56. int TableModel::columnCount( const QModelIndex & parent /*= QModelIndex() */ ) const
    57. {
    58. if ( parent.isValid() )
    59. return 0;
    60. return sColumnCount;
    61. }
    62.  
    63. QVariant TableModel::data( const QModelIndex & index, int role /*= Qt::DisplayRole */ ) const
    64. {
    65. QVariant retVal;
    66.  
    67. switch( role )
    68. {
    69. case Qt::DisplayRole:
    70. if ( index.column() == sNumberColumn )
    71. retVal = QString( "%1" ).arg( mRowData[ index.row() ] );
    72. else
    73. retVal = QString( "foo" );
    74. break;
    75.  
    76. case Qt::BackgroundRole:
    77. if ( mRowData[ index.row() ] > 1 )
    78. retVal = QBrush( Qt::red );
    79. else if ( mRowData[ index.row() ] < 1 )
    80. retVal = QBrush( Qt::green );
    81. break;
    82. }
    83. return retVal;
    84. }
    To copy to clipboard, switch view to plain text mode 

    The results look like this TableTest.jpg

    Since you are using a QSqlQueryModel (which is also based on QAbstractTableModel) you have two options:

    1 - Derive a class from QSqlQueryModel and reimplement the data() method. In the Qt::BackgroundRole case, you probably must make a recursive call to data() with Qt::DisplayRole and the QModelIndexthat corresponds to the column you want to check for the threshold value and convert the result to an int. If the value is greater than the threshold, set the return value to the appropriate QBrush as I show above, otherwise return an empty QVariant. For all other roles, return QSqlQueryModel::data() to make sure your results are displayed as they should be.

    2 - Derive a class from QSortFilterProxyModel and use the QSqlQueryModel as the source (QSortFilterProxyModel::setSourceModel()). In your proxy model, implement only the data() method as described in (1) above, except substitute QSortFilterProxyModel::data() for QSqlQueryModel::data().

  7. The following user says thank you to d_stranz for this useful post:

    toadybarker (16th September 2014)

  8. #7
    Join Date
    May 2014
    Location
    Washington D.C. area
    Posts
    7
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Thanks,

    Yes, after I looked a bit further I was able to piece together a solution - but this confirms that I was on the right track. I came up with something like this.

    Qt Code:
    1. CurVideoValidityModel::CurVideoValidityModel(QObject *parent)
    2. :QSqlQueryModel(parent)
    3. {
    4. }
    5. QVariant CurVideoValidityModel::data(const QModelIndex &item, int role) const
    6. {
    7. QModelIndex validityIndex = index(item.row(),5);
    8. QString line_validity = QSqlQueryModel::data(validityIndex).toString();
    9. if ((role == Qt::TextColorRole) && (line_validity == "Y"))
    10. {
    11. return QVariant::fromValue(QColor(Qt::red));
    12. }
    13. else
    14. {
    15. return QSqlQueryModel::data(item,role);
    16. }
    17. }
    To copy to clipboard, switch view to plain text mode 

    I then set my Tableview to this model. Have to refresh the model when I change things, but it seemed to work. Didn't include num rows or anything thing else...

    Thank you so much for the example.

  9. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Didn't include num rows or anything thing else...
    Right, because your QSqlQueryModel base class defines them. QAbstractTableModel defines these as pure virtual methods, and so any concrete class based on it needs to define at least the three methods: rowCount(), columnCount(), and data().

    By the way, I was curious how hard it would be to turn my example into one that uses a QSortFilterProxyModel instead of deriving from the actual model, and it turns out to be pretty simple. Doing so is really what the Qt Model-View architecture is intended for - you map the same model into different views using proxies to extract or modify parts of the model to suit the requirements of the view. This is generally preferred over deriving from the model (as you and I did) to accomplish the same end.

    Have to refresh the model when I change things
    Not sure what you mean by that. It is usually the model that notifies the view that it has changed, and the view updates accordingly. Unless you are changing something like the column used for the comparison or the row color; that's where you lose the connection to the model. If you used a QSortFilterProxyModel, you qould simply call the invalidate() method after changing something external to the model.
    Last edited by d_stranz; 16th September 2014 at 22:51.

  10. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    Quote Originally Posted by d_stranz View Post
    By the way, I was curious how hard it would be to turn my example into one that uses a QSortFilterProxyModel instead of deriving from the actual model, and it turns out to be pretty simple.
    Sounds actually more like a job for QIdentityProxyModel, the proxy only changes data, not structure.

    Cheers,
    _

  11. The following user says thank you to anda_skoa for this useful post:

    d_stranz (17th September 2014)

  12. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Change SqlQueryModel QTableView's Row Color

    QIdentityProxyModel
    Yes, even better. Too many darn classes in Qt to keep track of all of them. I'll keep this in mind the next time I need a proxy model.

Similar Threads

  1. Replies: 7
    Last Post: 25th July 2013, 21:47
  2. Replies: 7
    Last Post: 21st May 2013, 22:17
  3. Replies: 3
    Last Post: 22nd January 2010, 16:46
  4. how to change text color in QTableView?
    By phillip_Qt in forum Qt Programming
    Replies: 2
    Last Post: 28th April 2008, 10:03
  5. QTableView change color of current Cell
    By raphaelf in forum Qt Programming
    Replies: 4
    Last Post: 4th March 2006, 11:22

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.