qt - QTableview: display data in specific column based on value in other column -
i have sqlite table containing (among other things) "position" , "state" field.
i want display table in qtableview position header column , state in right column :
id | 1 | 2 | 3 1 | | | 2 | | | e
which represents following database entries :
id | position | state 1 | 1 | 2 | 3 | e
what best way ?
thank !
edit : not sure if changes need qtableview editable (by overriding setdata method of qsqlquerymodel)
the simplest option case create class inherits qsqltablemodel
, modify necessary functions shown below:
sqltablemodel.h
#ifndef sqltablemodel_h #define sqltablemodel_h #include <qsqltablemodel> class sqltablemodel : public qsqltablemodel { const qstring statename = "state"; const qstring positionname = "position"; public: int columncount(const qmodelindex &parent = qmodelindex()) const; void settable(const qstring &tablename); qvariant data(const qmodelindex &index, int role = qt::displayrole) const; qvariant headerdata(int section, qt::orientation orientation, int role = qt::displayrole) const; qt::itemflags flags(const qmodelindex &index) const; bool setdata(const qmodelindex &index, const qvariant &value, int role = qt::editrole); private: int max_position; int index_position; int index_state; void reset(); }; #endif // sqltablemodel_h
sqltablemodel.cpp
#include "sqltablemodel.h" #include <qbrush> #include <qsqlquery> #include <qsqltablemodel> #include <qsqlrecord> #include <qtimer> int sqltablemodel::columncount(const qmodelindex &parent) const { return qsqltablemodel::columncount(parent)+ max_position;; } void sqltablemodel::settable(const qstring &tablename) { qsqltablemodel::settable(tablename); index_position = fieldindex(positionname); index_state = fieldindex(statename); reset(); } qvariant sqltablemodel::data(const qmodelindex &index, int role) const { if(role == qt::foregroundrole){ return qbrush(qt::black); } const int number_of_columns = qsqltablemodel::columncount(); if(index.column()>= number_of_columns){ if(role==qt::displayrole){ int position = qsqltablemodel::data(this->index(index.row(), index_position), qt::displayrole).toint(); if(index.column() == number_of_columns + position - 1){ return qsqltablemodel::data(this->index(index.row(), index_state), qt::displayrole).tostring(); } } } return qsqltablemodel::data(index, role); } qvariant sqltablemodel::headerdata(int section, qt::orientation orientation, int role) const { if(orientation == qt::horizontal && role == qt::displayrole && section >= qsqltablemodel::columncount()) return section - qsqltablemodel::columncount() + 1; return qsqltablemodel::headerdata(section, orientation, role); } qt::itemflags sqltablemodel::flags(const qmodelindex &index) const { if(index.column() >= qsqltablemodel::columncount()){ return qt::itemisselectable| qt::itemiseditable| qt::itemisenabled; } return qsqltablemodel::flags(index); } bool sqltablemodel::setdata(const qmodelindex &index, const qvariant &value, int role) { if(role==qt::editrole){ const int number_of_columns = qsqltablemodel::columncount(); if(index.column() >= number_of_columns){ bool result1 = qsqltablemodel::setdata(this->index(index.row(), index_position), index.column()-number_of_columns +1, role); bool result2 = qsqltablemodel::setdata(this->index(index.row(), index_state), value, role); return result1 && result2; } if(index.column() == index_position){ qtimer::singleshot(0, this, &sqltablemodel::reset); } } return qsqltablemodel::setdata(index, value, role); } void sqltablemodel::reset() { qsqlquery q; q.exec(qstring("select max(%1) %2").arg(positionname).arg(tablename())); int val; while (q.next()) { val = q.value(0).toint(); } if(val != max_position){ beginresetmodel(); max_position = val; endresetmodel(); } }
input:
id |position |state 1 |1 |a 2 |2 |s 3 |1 |c 4 |4 |b 5 |3 |v
output:
the complete example can found in following link
Comments
Post a Comment