В общем с чего все началось:
В программке потребовался список который бы представлял из себя выборку представления + еще несколько полей с галочками которые бы юзверь мог потыкать а потом на основе этих галок заполнялись поля в отчете.
Дальше признаюсь ступил причем осознал только сейчас
буквально заклинило что не существующие столбцы от запроса мне не получить принял решение организовать все на уровне модели (хотя ни кто не мешал сделать SELECT *, 0 As p1, 0 As p2, 1 As p3 FROM rec.view) или добавить поля к представлению и юзать QSqlTableModel (без отправки изменений в базу они там все равно не нужны)
ниже то что у меня получилось собрать из разных источников.
кстати опыта у меня совсем мало и половина кода вообще за гранью моего понимания
для хранения записей используется класс
C++ (Qt)
//rectransfer.h
class RecTransfer
{
public:
RecTransfer(int p_sid, int p_id, QString p_sfp, bool p_rec);
~RecTransfer() {qDeleteAll(children); }
int getSID() const { return sid; }
int getID() const { return id; }
QString getSFP() const { return sfp; }
bool getREC() const { return rec; }
int getParentId() const { return parent ? parent->id : -1; }
int row() const {return parent? parent->children.indexOf( const_cast<RecTransfer*>(this) ): 0;}
RecTransfer *parent;
QList<RecTransfer*> children;
int sid, id;
QString sfp;
bool rec;
};
C++ (Qt)
//rectransfer.cpp
#include "rectransfer.h"
RecTransfer::RecTransfer(int p_sid, int p_id, QString p_sfp, bool p_rec): sid(p_sid), id(p_id), sfp(p_sfp), rec(p_rec), parent(0){
}
далее сам класс модели
C++ (Qt)
//rectransfermodel.h
#include "rectransfer.h"
#include <QSqlTableModel>
class RecTransferModel : public QSqlTableModel
{
Q_OBJECT
public:
explicit RecTransferModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount( const QModelIndex& parent ) const;
QModelIndex index(int row, int col, const QModelIndex& parent ) const;
RecTransfer* categoryFromIndex(const QModelIndex& index ) const;
QVariant data ( const QModelIndex &index, int role = Qt::DisplayRole ) const;
QSqlRecord record (int row) const;
bool setData(const QModelIndex &index, const QVariant &value, int role);
QVariant Alterdata( const QModelIndex &index, int column ) const;
Qt::ItemFlags flags( const QModelIndex &index ) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
void refreshModel();
void setRoot( RecTransfer* node );
void setFilt(QString &F);
private:
void setupModel(RecTransfer* parent);
RecTransfer* root;
QSqlDatabase db;
QString Filtr;
};
C++ (Qt)
//rectransfermodel.cpp
RecTransferModel::RecTransferModel(QObject *parent):QSqlTableModel(parent){
root = new RecTransfer(0, 0, tr("Types"),0);
root->parent = 0;
setupModel(root);
}
void RecTransferModel::setupModel(RecTransfer* parent){
db = QSqlDatabase::database();
QSqlQuery q;
QString S;
//формирование запроса к представлению с условием
C++ (Qt)
S = "SELECT EnID, (SE+' '+Na+' '+Pa)As SFP, 0 As rec FROM rec.view";
if( this->Filtr!= "" ){
S += " WHERE "+ this->Filtr;
}
if(q.prepare(S)){
if(q.exec()){
qDebug()<<"Query "<<S;
QList<RecTransfer*> parents;
QList<int> levels;
parents<<parent;
levels<<1;
int i = 1;
while(q.next()){
//раскладывание данных запроса в класс RecTransfer для хранения и дальнейшего проставления галочек
//юзверем
C++ (Qt)
RecTransfer* n = new RecTransfer(i, q.value(0).toInt(), q.value(1).toString(), q.value(2).toBool());
i++;
n->parent = parents.last();
parents.last()->children.append(n);
}
q.clear();
return;
}
}
}
int RecTransferModel::rowCount(const QModelIndex &parent) const{
return categoryFromIndex(parent)->children.count();
}
int RecTransferModel::columnCount( const QModelIndex& parent ) const{
return 4;
}
QModelIndex RecTransferModel::index(int row, int col, const QModelIndex& parent ) const{
RecTransfer* parentNode = categoryFromIndex(parent);
return createIndex(row, col, parentNode->children.value(row) );
}
RecTransfer* RecTransferModel::categoryFromIndex(const QModelIndex& index ) const{
return index.isValid()? static_cast<RecTransfer*>(index.internalPointer()): root;
}
QVariant RecTransferModel::data ( const QModelIndex &index, int role) const{
RecTransfer* node = categoryFromIndex(index);
if( !node ) return QVariant();
if( role == Qt::DisplayRole && index.column() == 0 )return QVariant(node->getSID());
if( role == Qt::DisplayRole && index.column() == 1 )return QVariant(node->id);
if( role == Qt::DisplayRole && index.column() == 2 )return QVariant(node->sfp);
if( role == Qt::DisplayRole && index.column() == 3 )return QVariant(node->rec);
return QVariant();
}
QSqlRecord RecTransferModel::record (int row) const{
//не могу тут ничего придумать
//record запрроса вернуть по моему нельзя потому что он не содержит изменений введенных пользователем
C++ (Qt)
}
bool RecTransferModel::setData(const QModelIndex &index, const QVariant &value, int role){
if (index.isValid() && role == Qt::EditRole){
RecTransfer* node = categoryFromIndex(index);
if(node){
if(index.column() == 3) node->rec = value.toInt();
qDebug()<<"В модель Value"<<value.toInt();
}
emit dataChanged(index, index);
return true;
}
return false;
}
QVariant RecTransferModel::Alterdata( const QModelIndex& index, int column ) const{
if (!index.isValid()) return QVariant();
RecTransfer* node = categoryFromIndex(index);
if(node){
if(column == 0)return QVariant(node->sid);
if(column == 1)return QVariant(node->id);
if(column == 2)return QVariant(node->sfp);
if(column == 3)return QVariant(node->rec);
}else{
if(!node)return QVariant();
else return QVariant(node->sfp);
}
return QVariant();
}
Qt::ItemFlags RecTransferModel::flags( const QModelIndex& index ) const{
if (!index.isValid() || index.column() != 3) return Qt::ItemIsEnabled;
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
QVariant RecTransferModel::headerData(int section, Qt::Orientation orientation, int role) const{
if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0 ) return QString("SID");
if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 1 ) return QString("EnID");
if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 2 ) return QString("SFP");
if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 3 ) return QString("REC");
return QVariant();
}
void RecTransferModel::refreshModel(){
RecTransfer* newRoot = new RecTransfer(0, 0, tr("Types"),0);
newRoot->parent = NULL;
setupModel(newRoot);
setRoot(newRoot);
}
void RecTransferModel::setRoot( RecTransfer* node ){
delete root;
root = node;
reset();
}
void RecTransferModel::setFilt(QString &F){
this->Filtr = F;
this->refreshModel();
}