Qt-interest Archive, February 2008
Add calculated columns to QSqlQueryModel or QSqlTableModel
Message 1 in thread
Hi Everyone,
Using 4.3.1.
I would like to fetch records from the database, but need to add some extra columns to the fetched rows with information that is not in the database. In Delphi you can just add extra columns to the dataset. I expect to be able override the QSqlRecord record () const, but its not virtual. Do I have to implement my own model from scratch, or is it easier to create a proxy model, or is there something else I should be looking at?
Many thanks in advance.
Tony Rietwyk.
--
[ signature omitted ]
Message 2 in thread
On Feb 5, 2008, at 1:42 PM, Tony Rietwyk wrote:
> Hi Everyone,
>
> Using 4.3.1.
>
> I would like to fetch records from the database, but need to add
> some extra columns to the fetched rows with information that is not
> in the database. In Delphi you can just add extra columns to the
> dataset. I expect to be able override the QSqlRecord record ()
> const, but its not virtual. Do I have to implement my own model from
> scratch, or is it easier to create a proxy model, or is there
> something else I should be looking at?
>
> Many thanks in advance.
I just implemented this in my application, and I don't know if my
implementation is the most elegant, but it works. Basically, you sub-
class the exsisting QSqlTableModel, and then just re-implement the
data() function, like so:
class myQSqlQueryModel:public QSqlQueryModel
{
Q_OBJECT
public:
QVariant data(const QModelIndex &item, int role) const;
};
QVariant myQSqlQueryModel::data(const QModelIndex &item, int role) const
{
if (item.column() == <calculated column #> &&
role==Qt::DisplayRole) //if the column is the calculated column, and
it is being requested for the DisplayRole
{
//whatever calculation code is needed
return QVariant(<calculated value>);
}
return QSqlQueryModel::data(item, role); //otherwise, just use the
data function from the base QSqlQueryModel class
}
You then instantiate and use an instance of your inherited class as
you would a standard QSqlTableModel class, using the insertColumns()
function to insert blank columns at the positions your new data()
function expects them. For example, if you wanted column 4 to be the
sum of columns two and three, your if statement in the data function
could look something like if (item.column() == 4 &&
role==Qt::DisplayRole), and then you would need to call
insertColumns(4,1) on the instance of your class. Course, you would
probably want to find a better way of determining the column position
than hard-coding it, but I'll leave that to your imagination :) Hope
this helps!
-----------------------------------------------
Israel Brewster
Computer Support Technician
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------
>
>
> Tony Rietwyk.
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx
> with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
--
[ signature omitted ]
Message 3 in thread
Hi Israel,
Thanks for the reply.
I assumed that I would need to add them to the QSQLRecord, for the sql
model's to work properly.
Tony.
> -----Original Message-----
> From: Israel Brewster [mailto:israel@xxxxxxxxxxxxxxxxxx]
> Sent: Wednesday, 6 February 2008 10:10
> To: Tony Rietwyk
> Cc: qt-interest@xxxxxxxxxxxxx
> Subject: Re: Add calculated columns to QSqlQueryModel or
> QSqlTableModel
>
>
> On Feb 5, 2008, at 1:42 PM, Tony Rietwyk wrote:
>
> > Hi Everyone,
> >
> > Using 4.3.1.
> >
> > I would like to fetch records from the database, but need to add
> > some extra columns to the fetched rows with information
> that is not
> > in the database. In Delphi you can just add extra columns to the
> > dataset. I expect to be able override the QSqlRecord record ()
> > const, but its not virtual. Do I have to implement my own
> model from
> > scratch, or is it easier to create a proxy model, or is there
> > something else I should be looking at?
> >
> > Many thanks in advance.
>
> I just implemented this in my application, and I don't know if my
> implementation is the most elegant, but it works. Basically, you sub-
> class the exsisting QSqlTableModel, and then just re-implement the
> data() function, like so:
>
> class myQSqlQueryModel:public QSqlQueryModel
> {
> Q_OBJECT
> public:
> QVariant data(const QModelIndex &item, int role) const;
> };
>
> QVariant myQSqlQueryModel::data(const QModelIndex &item, int
> role) const
> {
> if (item.column() == <calculated column #> &&
> role==Qt::DisplayRole) //if the column is the calculated column, and
> it is being requested for the DisplayRole
> {
> //whatever calculation code is needed
> return QVariant(<calculated value>);
> }
> return QSqlQueryModel::data(item, role); //otherwise,
> just use the
> data function from the base QSqlQueryModel class
> }
>
> You then instantiate and use an instance of your inherited class as
> you would a standard QSqlTableModel class, using the insertColumns()
> function to insert blank columns at the positions your new data()
> function expects them. For example, if you wanted column 4 to be the
> sum of columns two and three, your if statement in the data function
> could look something like if (item.column() == 4 &&
> role==Qt::DisplayRole), and then you would need to call
> insertColumns(4,1) on the instance of your class. Course, you would
> probably want to find a better way of determining the column
> position
> than hard-coding it, but I'll leave that to your imagination :) Hope
> this helps!
--
[ signature omitted ]
Message 4 in thread
On Feb 5, 2008, at 3:25 PM, Tony Rietwyk wrote:
> Hi Israel,
>
> Thanks for the reply.
>
> I assumed that I would need to add them to the QSQLRecord, for the sql
> model's to work properly.
Well, the code I sent (I could send you the full file if you want)
works in my application to create a display-only calculated column, no
need to mess qith the QSqlRecords- in my case, total number of items
minus number of items used, with the option to display "inf." for
items with unlimited availability. Once set up like this, the object
works as a standard QSqlQueryModel model in all regards, including the
calculated column. Incidentally, It seems perfectly happy to display a
mixture of integers and strings, which somewhat surprised me. One
small potential caviat, however, is that I don't know how it would
behave if the model was submitted back to the database. In my
application the model in question is used as read-only (note that it
is inheriting from QSqlQueryModel, not QSqlTableModel), so I have
never tried that. YMMV.
-----------------------------------------------
Israel Brewster
Computer Support Technician
Frontier Flying Service Inc.
5245 Airport Industrial Rd
Fairbanks, AK 99709
(907) 450-7250 x293
-----------------------------------------------
>
>
> Tony.
>
>
>> -----Original Message-----
>> From: Israel Brewster [mailto:israel@xxxxxxxxxxxxxxxxxx]
>> Sent: Wednesday, 6 February 2008 10:10
>> To: Tony Rietwyk
>> Cc: qt-interest@xxxxxxxxxxxxx
>> Subject: Re: Add calculated columns to QSqlQueryModel or
>> QSqlTableModel
>>
>>
>> On Feb 5, 2008, at 1:42 PM, Tony Rietwyk wrote:
>>
>>> Hi Everyone,
>>>
>>> Using 4.3.1.
>>>
>>> I would like to fetch records from the database, but need to add
>>> some extra columns to the fetched rows with information
>> that is not
>>> in the database. In Delphi you can just add extra columns to the
>>> dataset. I expect to be able override the QSqlRecord record ()
>>> const, but its not virtual. Do I have to implement my own
>> model from
>>> scratch, or is it easier to create a proxy model, or is there
>>> something else I should be looking at?
>>>
>>> Many thanks in advance.
>>
>> I just implemented this in my application, and I don't know if my
>> implementation is the most elegant, but it works. Basically, you sub-
>> class the exsisting QSqlTableModel, and then just re-implement the
>> data() function, like so:
>>
>> class myQSqlQueryModel:public QSqlQueryModel
>> {
>> Q_OBJECT
>> public:
>> QVariant data(const QModelIndex &item, int role) const;
>> };
>>
>> QVariant myQSqlQueryModel::data(const QModelIndex &item, int
>> role) const
>> {
>> if (item.column() == <calculated column #> &&
>> role==Qt::DisplayRole) //if the column is the calculated column, and
>> it is being requested for the DisplayRole
>> {
>> //whatever calculation code is needed
>> return QVariant(<calculated value>);
>> }
>> return QSqlQueryModel::data(item, role); //otherwise,
>> just use the
>> data function from the base QSqlQueryModel class
>> }
>>
>> You then instantiate and use an instance of your inherited class as
>> you would a standard QSqlTableModel class, using the insertColumns()
>> function to insert blank columns at the positions your new data()
>> function expects them. For example, if you wanted column 4 to be the
>> sum of columns two and three, your if statement in the data function
>> could look something like if (item.column() == 4 &&
>> role==Qt::DisplayRole), and then you would need to call
>> insertColumns(4,1) on the instance of your class. Course, you would
>> probably want to find a better way of determining the column
>> position
>> than hard-coding it, but I'll leave that to your imagination :) Hope
>> this helps!
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx
> with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]