Page 1 of 2 12 LastLast
Results 1 to 20 of 25

Thread: Color a row - QSqlRelationalTableModel or QSqlQueryModel

  1. #1
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Color a row - QSqlRelationalTableModel or QSqlQueryModel

    I am trying both QSqlRelationalTableModel and QSqlQueryModel to view records from a database in a QtableView, but when I want to do something as simple as setting a background color on a row, i bang my head on the wall,... two days, and still nothing is working... i cant believe how impossible it is to find a simple solution to this. I have read so many messages on forums and various websites, and there is nothing that works, it all suggests the same things that does not work. You can for example not use:

    model->setData(index, QVariant(QColor(Qt::yellow)), Qt::BackgroundRole);

    ... because both QSqlRelationalTableModel and QSqlQueryModel is ignoring Qt::BackgroundRole. QSqlQueryModel is read only, so only model->data() works for getting data. QSqlRelationalTableModel can model->setData() but it only cares about Qt::EditRole, and ignores all I try to do with background color.

    I have found some extremely long and complicated solutions, that might work, but I cant believe that i have to write several pages of code to set a freaking background color on a row.

    Please, if someone knows how to do this, I would really appreciate some help on this.
    Thank you,

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    You can derive from the model class and reimplement data() such that it returns something for the Qt::BackgroundRole.
    Whether you set that value from outside or whether the value is determined in the model itself is up to you.

    You can use a QIdentityProxyModel between the model and the view to provide data for additional roles.
    More or less very similar to the first approach, but works independent of what the source model is.

    You can set your own item delegate that draws the background in a way you want.

    First option is obviously the easiest one, only a handful of lines of code, the last one is the most demanding one.

    Cheers,
    _

  3. #3
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Well, if I create a new class, and a new data(), then i can use the index it receives and read what row im on, and what column im on, and set the color on the row if I know the row number i want.

    But lets say i want to put blue background on the row if column 2 is blank. I cant get to my model to create a new index to check on that column from within the data().

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Quote Originally Posted by AKG View Post
    But lets say i want to put blue background on the row if column 2 is blank.
    Then you retrieve the value for column 2 of the same row and check it?

    Quote Originally Posted by AKG View Post
    I cant get to my model to create a new index to check on that column from within the data().
    You don't need to "get to my model", inside data() you are the model.

    But even if you weren't QModelIndex::model() always gives you access to the model an index came from.

    Cheers,
    _

  5. #5
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Im not explaining well, that is why you don't see what I am actually trying to ask. Sorry about that, english is not my primary language.

    I have a view with lots of images and hundres of columns, and a ton of rows, so when data() is called by the view on every cell every time the user clicks on something, it takes a lot of time to refresh if I do to much in the data() function.

    I understand how to do all that is suggested, and i can get it to do all i want, but the code i end up with is just not fast enough. There is to much code that does things like getting my model from the index, then creating a new index, then getting the row and the column of the cell i am checking the content of from that index, for then finally setting some changes to a cell.... remember, this code is run for every single cell, every singe time something in the view is clicked.

    Someone on a different forum made me aware of the sibling function, that lets me stay on the same row, ans i assume all columns are sibling of the same row ?? I have not tired it at this time, but if that is true, i guess that will shorten the code a bit.

    I just wish i could do a row at a time, or some other logic ... maybe saving the criteria for the cells in the database, and then displaying every second column, hiding the "setting column" ... i don't know.

    If the columns in my database alternate between one settings row, then one content column. The data() function will read the setting row to find out what and how to display it, and display what ever is in the content column.

    any thoughts ?? I feel like Im stubling around in the dark right now. Just cant get this to go faster.

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Quote Originally Posted by AKG View Post
    Im not explaining well, that is why you don't see what I am actually trying to ask. Sorry about that, english is not my primary language.
    Then maybe post the code for data()?

    Quote Originally Posted by AKG View Post
    Someone on a different forum made me aware of the sibling function, that lets me stay on the same row, ans i assume all columns are sibling of the same row ?? I have not tired it at this time, but if that is true, i guess that will shorten the code a bit.
    sibling() will also just call index().
    If you have the same background color for each cell in a row, you could cache the value.

    Cheers,
    _

  7. #7
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    I don't understand what you mean by cash the value ?

    A simple data() function to deal with background color wold be for example like this:

    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. const QAbstractItemModel * model = index.model();
    4. QModelIndex index2 = model->index(index.row(), 1, QModelIndex()); // position 1 on current row
    5. QVariant value2 = QSqlQueryModel::data(index2, Qt::DisplayRole);
    6. if(value2.toString() == "" && role == Qt::BackgroundRole) { // if the column 2 on the same row is blank we set the color
    7. return QVariant(QColor(Qt::yellow));
    8. }
    9. QVariant value = QSqlQueryModel::data(index, role);
    10. return value;
    11. }
    To copy to clipboard, switch view to plain text mode 

    The code is called on every cell, so every cell on the row that has a blank column 2 will be painted - because this if is true on all cell on that row

    The faster way would be to have a list of what needs to be updated and the indexes saved - and then call a function that goes in to only the selected rows and repaints only those cell that needs extra features / colors etc. This function must be automatically triggered after the view calls the data function on all cells every time it does that.

    Any ideas ?

    Or if I try to ask a more precise question : where can i intercept the code that fires the data() function ?? so that I can add a function call to a function that only selct spesific cells to pain over again... hmmm dont know if im makins sence or not sorry.
    Last edited by AKG; 5th September 2016 at 23:58.

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Quote Originally Posted by AKG View Post
    I don't understand what you mean by cash the value ?
    You determine the value the first time you need it and store it in a data member for retrieval when it is needed again.

    Quote Originally Posted by AKG View Post
    A simple data() function to deal with background color wold be for example like this:
    That is like an example from a C++ recruiter, when potential hires are asked "what is wrong with this".

    Obviously the worst thing is doing unnecessary things all the time which are only needed when retrieving the background color, but in order of execution:

    Quote Originally Posted by AKG View Post
    Qt Code:
    1. const QAbstractItemModel * model = index.model();
    To copy to clipboard, switch view to plain text mode 
    Creating an alias for "this". Through a function call so that the compiler can't easily figure out that "model" and "this" are the same.
    Would be worse of course if QModelIndex::model() weren't inline and a const expression.

    Quote Originally Posted by AKG View Post
    Qt Code:
    1. QModelIndex index2 = model->index(index.row(), 1, QModelIndex()); // position 1 on current row
    2. QVariant value2 = QSqlQueryModel::data(index2, Qt::DisplayRole);
    To copy to clipboard, switch view to plain text mode 
    As already pointed out, doing things not necessary for all calls to data()

    Quote Originally Posted by AKG View Post
    Qt Code:
    1. if(value2.toString() == "" && role == Qt::BackgroundRole) { // if the column 2 on the same row is blank we set the color
    To copy to clipboard, switch view to plain text mode 
    This is one is a classic :-)
    Doing the two condition parts in the wrong order, expensive string comparison before the cheap int comparison.
    Also needlessly doing a string comparison, which would be even worse if QString:perator==() didn't have a const char* overload.
    Very likely needless conversion from QVariant to QString, depending on the column's data.

    Quote Originally Posted by AKG View Post
    Qt Code:
    1. QVariant value = QSqlQueryModel::data(index, role);
    2. return value;
    3. }
    To copy to clipboard, switch view to plain text mode 
    Creating of a local, non-const, variable to force the compiler to track it for optimization.

    Quote Originally Posted by AKG View Post
    The code is called on every cell
    Which usually means that code in data() should not be artifically pessimised a lot.

    Quote Originally Posted by AKG View Post
    so every cell on the row that has a blank column 2 will be painted - because this if is true on all cell on that row
    Which would lend itself to caching.

    Quote Originally Posted by AKG View Post
    The faster way would be to have a list of what needs to be updated and the indexes saved - and then call a function that goes in to only the selected rows and repaints only those cell that needs extra features / colors etc. This function must be automatically triggered after the view calls the data function on all cells every time it does that.
    The view calls data() when it thinks it needs it, e.g. when a new cell comes into view, when the model signals change.

    Quote Originally Posted by AKG View Post
    Or if I try to ask a more precise question : where can i intercept the code that fires the data() function ?? so that I can add a function call to a function that only selct spesific cells to pain over again... hmmm dont know if im makins sence or not sorry.
    That is in the view code, in your case likely somewhere here https://code.woboq.org/qt5/qtbase/sr...eview.cpp.html

    Cheers,
    _

  9. #9
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Thank you,

    I am afraid i am having som problems undestanding what you are saying.
    I would really appreciate if you can write the code for this data() function, so i can see this is code. It is easier for me to understand if you just write it in code how this should be done.

    Thank you again

  10. #10
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Qt products
    Qt5
    Platforms
    MacOS X
    Thanks
    13
    Thanked 153 Times in 150 Posts

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Pardon me for jumping into this thread late, but are you looking for something as simple as the following (uncompiled and untested but should be close):
    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. QVariant value = QSqlQueryModel::data(index, role);
    4.  
    5. if (role == Qt::BackgroundRole && index.column() == 2 && QSqlQueryModel::data(index, Qt::DisplayRole).toString() == "")
    6. value = QColor(Qt::yellow);
    7.  
    8. return value;
    9. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jefftee; 8th September 2016 at 06:20.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Close, but the background color applies for all cells of the row. this would be something more like

    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. if (role == Qt::BackgroundRole) {
    4. const QModelIndex column1Index = this->index(index.row(), 1);
    5. const QVariant value = QSqlQueryModel::data(column1Index, Qt::DisplayRole);
    6.  
    7. if (!value.isValid() || value.toString().isEmpty()) return QColor(Qt::yellow);
    8. }
    9.  
    10. return QSqlQueryModel::data(index, role);
    11. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  12. #12
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Can I not just do this :


    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. if (role == Qt::BackgroundRole) {
    4. const QVariant value = QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole);
    5. if (!value.isValid() || value.toString().isEmpty()) return QColor(Qt::yellow);
    6. }
    7. return QSqlQueryModel::data(index, role);
    8. }
    To copy to clipboard, switch view to plain text mode 

    What do you think ?? Is it to cryptic to understand what cell I'm testing ?? this->index(index.row() does mean this row... so to me this is easier to read - but what do you think ??

    Maybe it is over kill or bad to do this ??? :

    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. if (role == Qt::BackgroundRole) {
    4. if (QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole).toString().isEmpty()) return QColor(Qt::yellow);
    5. }
    6. return QSqlQueryModel::data(index, role);
    7. }
    To copy to clipboard, switch view to plain text mode 

    Crazy to do a one liner ?? :

    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. if (role == Qt::BackgroundRole && QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole).toString().isEmpty()) return QColor(Qt::yellow);
    4. return QSqlQueryModel::data(index, role);
    5. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by AKG; 8th September 2016 at 17:18.

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    That's basically identical to my code, no?
    Just passing the result of index() directly to data(), right?

    Cheers,
    _

  14. #14
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Sorry, I ment to ask you if any of these 3 alternatives would make a slightly faster code, or if it makes no difference ??

    Or maybe this is the fastest wiith more readability ?? What do you think, is it faster code ?? :

    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. if (role == Qt::BackgroundRole && QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole).toString().isEmpty()){
    4. return QColor(Qt::yellow);
    5. }
    6. return QSqlQueryModel::data(index, role);
    7. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by AKG; 8th September 2016 at 18:13.

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

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    I would go for the first of the three options, it is the most readable IMHO.

    Cheers,
    _

  16. #16
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Qt products
    Qt5
    Platforms
    MacOS X
    Thanks
    13
    Thanked 153 Times in 150 Posts

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Quote Originally Posted by anda_skoa View Post
    Close, but the background color applies for all cells of the row. this would be something more like
    Hard to tell what the actual requirements were... So, if the requirement is for a yellow background for each column in a row where column 2 is blank, I'd change my code to be the following:
    Qt Code:
    1. QVariant CustomSqlModel::data(const QModelIndex &index, int role) const
    2. {
    3. QVariant value = QSqlQueryModel::data(index, role);
    4.  
    5. if (role == Qt::BackgroundRole && QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole).toString() == "")
    6. value = QColor(Qt::yellow);
    7.  
    8. return value;
    9. }
    To copy to clipboard, switch view to plain text mode 

    Edit: Fixed *major* bug that resulted in the wrong column being used for the index!
    Last edited by jefftee; 9th September 2016 at 03:29.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  17. #17
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    That is interesting, although column 2 is actually the third column as 0 is column 1
    but why not const ??


    Qt Code:
    1. const QVariant value = QSqlQueryModel::data(this->index(index.row(), 1), Qt::DisplayRole);
    To copy to clipboard, switch view to plain text mode 


    And what is the fastes code ?? I ask because i will be adding a lot of things to this data function, so it will mater later on what is the fastes.
    Last edited by AKG; 9th September 2016 at 07:32.

  18. #18
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Qt products
    Qt5
    Platforms
    MacOS X
    Thanks
    13
    Thanked 153 Times in 150 Posts

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Quote Originally Posted by AKG View Post
    And what is the fastes code ?? I ask because i will be adding a lot of things to this data function, so it will mater later on what is the fastes.
    It doesn't matter which of those is fastest if you're going to be "adding a lot of things to this data function", so I suggest you test all of the code that people have written for you and use whichever you wish as the building blocks for adding your own code.

    So, my recommendation is stop asking for which version of the code is fastest and start writing the code that *you* need in the data function.


    Added after 6 minutes:


    Quote Originally Posted by AKG View Post
    That is interesting, although column 2 is actually the third column as 0 is column 1
    but why not const ??
    I can't believe that I actually have to say this, but change the column number to match your needs! See line 6 and see if you can answer yourself why the variable is not const.
    Last edited by jefftee; 9th September 2016 at 03:26.
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

  19. #19
    Join Date
    Sep 2016
    Posts
    12
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    And i can't belive that you are insinutating and assuming that im stupid.... but if you need to do that, we would both be better off if you don't answer me at all.
    I was trying to say - why not the other example where const was used - not why you did not use const on a value that is receiving a value.

    I was clear in the start that english is not my language and that im spendign lots of time just translating trying to understand the english of what is explained.

    Even in the first message i say i have code that is woriking, but it is to big many lines of code.

    And this discussion is ONLY about speed, as you can see all the code is painting the row yellow so that is clearly not what this is about but to make if faster, because my view is very slow because so many is loaded and going on.
    When is said dont work, i mean it is to slow
    Last edited by AKG; 9th September 2016 at 05:31.

  20. #20
    Join Date
    Dec 2009
    Location
    New Orleans, Louisiana
    Posts
    791
    Qt products
    Qt5
    Platforms
    MacOS X
    Thanks
    13
    Thanked 153 Times in 150 Posts

    Default Re: Color a row - QSqlRelationalTableModel or QSqlQueryModel

    Quote Originally Posted by AKG View Post
    And i can't belive that you are insinutating and assuming that im stupid.... but if you need to do that, we would both be better off if you don't answer me at all.
    I have reread my post and I don't believe that I insinuated or assumed that you are stupid. I just find it astonishing that you ask for people to write code for you and then point out a simple mistake in a code example which I clearly stated was not tested or compiled. How about you test the various code samples people gave you and determine which is fastest or write yourself from scratch rather than demand that someone tell you which is fastest? Learn how to help yourself and you will be much better off in the long run, I promise.

    Regarding why the QVariant was not const, try to make it const and compile the sample I gave you and the answer will become obvious.

    You insist that performance is the only thing that matters and you fret over which trivial versions of code multiple people have voluntarily given to you is most efficient. You admitted that you will be "adding a lot of things to this data function". Don't you think that the "lot of things" you will be adding may perhaps have a more relevant impact to performance than the trivial examples you were given?

    Clearly I don't think I can help you, but my advice to you remains the same. Stop the analysis paralysis and move on to writing the "lot of things" that you need to add to the data method.

    Good luck!
    I write the best type of code possible, code that I want to write, not code that someone tells me to write!

Similar Threads

  1. Replies: 3
    Last Post: 3rd February 2014, 18:04
  2. Replies: 0
    Last Post: 10th September 2013, 12:05
  3. Replies: 4
    Last Post: 8th September 2011, 09:22
  4. Replies: 3
    Last Post: 22nd January 2010, 17:46
  5. Display Label Color by selecting Color Picker
    By sosanjay in forum Qt Programming
    Replies: 1
    Last Post: 25th September 2009, 07:11

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
  •  
Qt is a trademark of The Qt Company.