Solved How to get the actual string, displayed in a QTableView Item
-
Maybe there is something obvious - but I did not find it... So I decided to ask here:
I have a QTableView which gets it's data from a QSqlTableModel. I use my "DateItemFormatter" which is a QStyledItemDelegate, to format one column. [it takes the date coming from the database and formats it into the german date format].
Now I find myself in a method called from a context menu. I have the index of the cell clicked - but: How do I get the formatted text in the item? From the model I can only retrieve the raw data. And calling the displayText from my Delegate myself seems redundand - and with that rediculouse to me (however: it works).
Is there a better way?
Best regards
HM -
@HoMa
I have a certain amount of sympathy with your question. The delegate takes a data item and produces a formatted string. I wanted to use that same string elsewhere than in the table view delegate. People here will tell you it belongs in the delegate ignoring the fact that it may useful elsewhere, a formatted string (mine was wanted for a floating point number in a particular format) may be applicable generally for a data item.Anyway, the long and the short to keep these people happy is to move the body of your delegate into a shared function which the delegate calls but can also be called from elsewhere. Ultimately the delegate takes a data value (or index into model for the value) and produces a formatted string, so factor that bit out. This is better than actually trying to access
displayText
in a delegate which is not accessible elsewhere. -
@HoMa
I have a certain amount of sympathy with your question. The delegate takes a data item and produces a formatted string. I wanted to use that same string elsewhere than in the table view delegate. People here will tell you it belongs in the delegate ignoring the fact that it may useful elsewhere, a formatted string (mine was wanted for a floating point number in a particular format) may be applicable generally for a data item.Anyway, the long and the short to keep these people happy is to move the body of your delegate into a shared function which the delegate calls but can also be called from elsewhere. Ultimately the delegate takes a data value (or index into model for the value) and produces a formatted string, so factor that bit out. This is better than actually trying to access
displayText
in a delegate which is not accessible elsewhere. -
@JonB said in How to get the actual string, displayed in a QTableView Item:
Anyway, the long and the short to keep these people happy is to move the body of your delegate into a shared function which the delegate calls but can also be called from elsewhere.
e.g. in the model's data() function for a custom role.
-
@Christian-Ehrlicher
That is what I did first. But still a couple of the experts (who will remain nameless) here shouted at me that this (particular formatting of a number for my case) was "presentation only" and had no place coming from the model. I was a green noob, and did not dare to argue too much, so I acquiesced, reluctantly. I hope those experts still lose sleepless nights over bullying me so... ;-) -
@JonB Thx for the insights. I went with the shared function - not too nice, but much less casting.
regards
HM -
@JonB said in How to get the actual string, displayed in a QTableView Item:
who will remain nameless
I can take the heat! :)
If it's not "data" it doesn't belong to the model. The most important point for not storing "formatted" versions of the data is that the model is locale-unaware so if you store a floating point formatted in the model it will appear wrong to, for example, a mainland-europe user (as the thousand separator and decimal point are different).
Having said that, my opinion is not gospel and if it makes more sense for your use case to store it in an extra role then I will not hunt you down -
@VRonin said in How to get the actual string, displayed in a QTableView Item:
@JonB said in How to get the actual string, displayed in a QTableView Item:
who will remain nameless
I can take the heat! :)
I carefully maintained anonymity! ;-) Nice to know you still might feel some remorse years later....
I exaggerated slightly. My situation was actually more complex. Briefly: the problem was that the database effectively contained more information about the value returned than the conversion to real/floating point conveyed. If it was originally a 2-decimal-point decimal type then in our case this specifically meant it was to be treated as a money/currency figure. Qt does not have a type for this. For us that meant it had to have fixed 2 dps (including trailing 0s) and it had to have a
£
currency symbol prepended when stringified.The problem was that I inherited code (Python at that) which had like a thousand calls to
data(index)
(not even a role specified), and relied on that behaviour. And sometimes was used inQTableView
but also sometimes used directly without a table. And you could not discern whether a given call from an arbitrary index referred to such a field or to some other non-monetary field. You can see why "lazily" wantingDisplayRole
to return like this was convenient given the state the code was already in.Anyway, what would indeed have been better would have been (as @Christian-Ehrlicher suggested) some other arbitrary role on such indexes to return either the desired formatted string or the fact that it was originally money for the caller to deal with. But that would have meant I had to change every single existing call to
data()
to allow for this. I do accept now that Qt is happier withDisplayRole
returning the amount still as a number, but that was not clear to me at the time as a noob.Still, does you no harm to feel some guilt... ;-)
-
Indeed in this case you have 2 or 3 pieces of data (the integer with the number, an integer telling you where the decimal place should be (or a constant if it's 2), a currency (an enum?)). If you were to write that code from scratch I still think it should be the responsibility of whatever is painting that data (delegate, mapped widget, etc) to put the 3 points together in a human-friendly representation