PDA

View Full Version : QSortFilterProxyModel tableview Combobox problem



Kyef
22nd July 2015, 15:25
I have searched and I have not found any valid solutions to my problem with QSortFilterProxyModel. I am asking in the same line with this thread
(http://www.qtcentre.org/threads/27877-QSortFilterProxyModel-and-QSqlRelationalDelegate-in-TableView) and another one here (http://www.qtcentre.org/threads/46930-QSqlRelationalTableModel-with-QSortFilterProxyModel-and-SqlRelationalDelegate) which where not answered. I need to filter the output on my tableview but also be able to edit the columns however, when QSortFilterProxyModel is called, I loose focus of the comboboxes. Is there a work around on this? Bellow is my code



void clsList::strModel()
{
strmodel = new QSqlRelationalTableModel(this);
strmodel->setEditStrategy(QSqlTableModel::OnRowChange);
strmodel->setTable("setCls_str");
strmodel->setFilter("setCls_str.actv1=1");

int clInd = strmodel->fieldIndex("classCode");
int strInd = strmodel->fieldIndex("streams");
int clTInd = strmodel->fieldIndex("clTeach");

strmodel->setRelation(clInd, QSqlRelation("tblClass", "clID", "clCode"));
strmodel->setRelation(strInd, QSqlRelation("tblStreams", "strID", "strName"));
strmodel->setRelation(clTInd, QSqlRelation("allTeachers", "trID", "trName"));

strmodel->setHeaderData(strInd, Qt::Horizontal, tr("Stream"));
strmodel->setHeaderData(clInd, Qt::Horizontal, tr("Class"));
strmodel->setHeaderData(clTInd, Qt::Horizontal, tr("Teacher"));

strmodel->database().transaction();
if(strmodel->submitAll())
{
strmodel->database().commit();
}
else
{
strmodel->database().rollback();
}

if (!strmodel->select()) {
showError(strmodel->lastError());
return;}

strProxy = new SortFilterProxyModel(this);
strProxy->setSourceModel(strmodel);
strProxy->setFilterCaseSensitivity(Qt::CaseInsensitive);

ui->strmv->setModel(strProxy); // with this line all comboboxes disappear on my tableview
// ui->strmv->setModel(strModel); // This line works well....with comboboxes visible on the grid
//but I need to filter data according to some parameters
ui->strmv->setItemDelegate(new QSqlRelationalDelegate(ui->strmv));
ui->strmv->setColumnWidth(clInd,50);
ui->strmv->setColumnWidth(strInd,100);
ui->strmv->setColumnWidth(clTInd,100);
}

Kyef
7th August 2015, 12:20
I am coming to a conclusion that Sqlite Views do not work with the default QSqlRelationalDelegate. When a view is used, editing is locked even when the right flags have been "raised". This could be due to the fact that Sqlite views are ReadOnly, conversely, with MS SQL Server, views work exactly the same way like tables. To whoever is facing the same challenge, you need to create a custom delegate to handle editing otherwise use the table itself. Unfortunately sometimes you may need to some calculated field (i.e where you need to add 'first name' and 'last name'). Below is my delegate that I used to handle editing on my table:



#ifndef DELSTRSETTABLE
#define DELSTRSETTABLE
#include <QtWidgets>
#include <QtSql>

class delStrSetTable : public QSqlRelationalDelegate
{
Q_OBJECT
public:
delStrSetTable(QObject *parent=0):QSqlRelationalDelegate(parent){
QString strg("SELECT trID, trName FROM allTch WHERE trNo>0");
tch = new QSqlQueryModel();
tch->setQuery(strg);
allt = tch->rowCount();

QString str2("SELECT strID, strName FROM tblstreams WHERE strNo>0");
str = new QSqlQueryModel();
str->setQuery(str2);
alls = str->rowCount();

font2.setFamily(QStringLiteral("Arial Narrow"));
font2.setPointSize(10);
}
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
// ComboBox ony in column 4
if(index.column() == 3) {

// Create the combobox on stream column and populate it
QComboBox *sbCb = new QComboBox(parent);
sbCb->setModel(str);
sbCb->setModelColumn(1);
sbCb->setFont(font2);
sbCb->setFrame(false);
return sbCb;
// Create the combobox on teacher column and populate it
} else if (index.column() == 4) {
QComboBox *tchCb = new QComboBox(parent);
tchCb->setModel(tch);
tchCb->setModelColumn(1);
tchCb->setFont(font2);
tchCb->setFrame(false);
return tchCb;

}
else
return QSqlRelationalDelegate::createEditor(parent, option, index);
}
void setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(index.column()==3)
{ QComboBox *combobox = qobject_cast<QComboBox*>(editor);
Q_ASSERT(combobox);

for(int x = 0;x<alls;++x)
{
QModelIndex ID = str->index(x,0);
QModelIndex name = str->index(x,1);
QString fulname = QString(name.data(Qt::DisplayRole).toString());
int id = ID.data().toInt();

if(index.data().toInt() == id){
int cbIndex = combobox->findText(fulname);
if(cbIndex >= 0)
combobox->setCurrentIndex(cbIndex);
}
}
}
else if(index.column()==4)
{ QComboBox *combobox = qobject_cast<QComboBox*>(editor);
Q_ASSERT(combobox);

for(int x = 0;x<allt;++x)
{
QModelIndex ID = tch->index(x,0);
QModelIndex name = tch->index(x,1);
QString fulname = QString(name.data(Qt::DisplayRole).toString());
int id = ID.data().toInt();

if(index.data().toInt() == id){
int cbIndex = combobox->findText(fulname);
if(cbIndex >= 0)
combobox->setCurrentIndex(cbIndex); }
}

} else {
QSqlRelationalDelegate::setEditorData(editor, index);
}
}
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if(index.column()==3)
{ QComboBox *combbox = qobject_cast<QComboBox*>(editor);
Q_ASSERT(combbox);

for(int x = 0;x<alls;++x)
{
QModelIndex ID = str->index(x,0);
QModelIndex name = str->index(x,1);
QString fulname = QString(name.data().toString());
int id = ID.data().toInt();

if(combbox->currentText() == fulname)
model->setData(index,id);
}
}
else if(index.column()==4)
{
QComboBox *combobx = qobject_cast<QComboBox*>(editor);
Q_ASSERT(combobx);

for(int x = 0;x<allt;++x)
{
QModelIndex ID = tch->index(x,0);
QModelIndex name = tch->index(x,1);
QString fulname = QString(name.data().toString());
int id = ID.data(Qt::EditRole).toInt();

if(combobx->currentText() == fulname)
model->setData(index,id);
}

} else
QSqlRelationalDelegate::setModelData(editor, model, index);
}
private:
QSqlQueryModel *tch,*str;
int allt,alls;
QFont font2;
};
#endif // DELSTRSETTABLE