[Interest] Depending QCombobox
Michele Ciampichetti
cia.michele at gmail.com
Thu Jan 12 08:51:44 CET 2012
Hello Alex,
thanks for your answer. Could you send any example of your ideas?
I attach what I got, so you can valutate it.
1) I subclass QRelationalDelegate to make the column behaves different
class PicLoadDelegate: public QSqlRelationalDelegate
{
Q_OBJECT
public:
PicLoadDelegate(QObject * parent = 0 ): QSqlRelationalDelegate(parent)
{}
~PicLoadDelegate()
{}
void setEditorData(QWidget *editor, const QModelIndex &index) const
{
switch(index.column()) {
case 4:
{
const QSqlRelationalTableModel * sqlModel = qobject_cast
<const QSqlRelationalTableModel *>(index.model());
QSqlTableModel * childModel = sqlModel ?
sqlModel->relationModel(index.column()) : 0;
QString filter=QString("CodRegione=(SELECT ID FROM REGIONI
WHERE NOME='%1')").arg(sqlModel->index(index.row(),10).data().toString());
childModel->setFilter(filter);
QComboBox * combo = qobject_cast <QComboBox *>(editor);
if(!sqlModel || !combo){
QSqlRelationalDelegate::setEditorData(editor,index);
return;
}
combo->setModel(childModel);
combo->setCurrentIndex(combo->findText(sqlModel->data(index).toString()));
break;
}
case 5:{
const QSqlRelationalTableModel * sqlModel = qobject_cast
<const QSqlRelationalTableModel *>(index.model());
QSqlTableModel * childModel = sqlModel ?
sqlModel->relationModel(index.column()) : 0;
QString filter=QString("CodProvincia=(SELECT ID FROM
PROVINCE WHERE NOME='%1')").arg(sqlModel->index(index.row(),4).data().toString());
childModel->setFilter(filter);
QComboBox * combo = qobject_cast <QComboBox *>(editor);
if(!sqlModel || !combo){
QSqlRelationalDelegate::setEditorData(editor,index);
return;
}
combo->setModel(childModel);
combo->setCurrentIndex(combo->findText(sqlModel->data(index).toString()));
break;
}
case 9: // do something special for blob column 2
{
QLabel *label = qobject_cast<QLabel*>(editor);
//Q_ASSERT(label);
if (label) {
QByteArray imageData = index.data(Qt::EditRole).toByteArray();
QPixmap pixmap;
if (pixmap.loadFromData(imageData))
label->setPixmap(pixmap);
}
break;
}
default:
QSqlRelationalDelegate::setEditorData(editor, index);
}
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index ) const
{
switch(index.column()) {
case 9: // do something special for blob column 2
{
QLabel *label = qobject_cast<QLabel*>(editor);
Q_ASSERT(label);
if (label) {
QBuffer buf;
buf.open(QIODevice::WriteOnly);
if (label->pixmap()!=0){
if (label->pixmap()->save(&buf,"PNG"))
model->setData(index, buf.data(), Qt::EditRole);
}else
model->setData(index, buf.data(), Qt::EditRole);
}
break;
}
default: // so does anything we've missed
{
if (!index.isValid())
return;
QSqlRelationalTableModel *sqlModel =
qobject_cast<QSqlRelationalTableModel *>(model);
QSqlTableModel *childModel;
QComboBox *combo = qobject_cast<QComboBox *>(editor);
if (combo)
childModel= qobject_cast<QSqlTableModel
*>(combo->model());
else
childModel = sqlModel ?
sqlModel->relationModel(index.column()) : 0;
if (!sqlModel || !childModel || !combo) {
QItemDelegate::setModelData(editor, model, index);
return;
}
int rows = childModel->rowCount();
QString name= combo->accessibleName();
QString testo = combo->currentText();
int currentItem = combo->currentIndex();
int childColIndex =
childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn());
int childEditIndex =
childModel->fieldIndex(sqlModel->relation(index.column()).indexColumn());
QString display =
childModel->data(childModel->index(currentItem,
childColIndex)).toString();
int indice =
childModel->data(childModel->index(currentItem,
childEditIndex)).toInt();
sqlModel->setData(index,
childModel->data(childModel->index(currentItem, childColIndex),
Qt::DisplayRole),
Qt::DisplayRole);
sqlModel->setData(index,
childModel->data(childModel->index(currentItem, childEditIndex),
Qt::EditRole),
Qt::EditRole);
break;
}
}
2) I use the signal-slot link to change the content of the QComboBox at
selection of the master one:
LMForn class constructor
[...]
connect(ui->cboRegione,SIGNAL(currentIndexChanged(int)),this,SLOT(
setFilterProv(int)));
connect(ui->cboProv,SIGNAL(currentIndexChanged(int)),this,SLOT(setFilterCom(int)));
[...]
void LMForn::setFilterProv(int currentIndex){
mdlProv = new QSqlTableModel(this);
mdlProv->setTable("Province");
mdlProv->setFilter (QString("CodRegione=(SELECT ID FROM REGIONI
WHERE NOME='%1')").arg(ui->cboRegione->currentText()));
mdlProv->select();
ui->cboProv->setModel(mdlProv);
}
void LMForn::setFilterCom(int currentIndex){
mdlCom = new QSqlTableModel(this);
mdlCom->setTable("Comuni");
mdlCom->setFilter (QString("CodProvincia=(SELECT ID FROM PROVINCE
WHERE NOME='%1')").arg(ui->cboProv->currentText()));
mdlCom->select();
ui->cboComune->setModel(mdlCom);
}
It work in this way: if I have a congruent configuration of three combobox,
the load is ok, but if I change one of three, the update of the
QSqlRelationalTableModel fails and need two time of same configuration to
objain the saving.
What could be the mistake? If I watch in debug the combo->currentIndex() or
combo->currentText() are corrects, but the save data don't write data into
model. It want preserve the relations on data? How can I solve this problem?
Thanks a lot for your time
Michele
2012/1/12 Alex Malyushytskyy <alexmalvtk at gmail.com>
> Since nobody posted I decided to give my comments, even though I have
> not worked with mentioned classes.
> As far as I see your problem,
>
> You need to be able:
>
> 1. to be notified when selection in combo-box is changed
>
> This can be done by overriding createEditor and connecting combobox
> signal (mostly likely you would want activated (const QString& ) )
> to custom slot.
> I recommend to use Qt::QueuedConnection.
> This should insure that slots is not called when data is still changing.
>
> 2. apply filter to model index based on selection value.
>
> Do this in the custom slot I mentioned above.
> Only difficulty might be to find out index for which slot is called.
>
> I would subclassed QComboBox,
> added variable where I would store QModelIndex it was created for and
> signal activated ( const QModelIndex& , const QString& ),
> which I would emit when selection changed
>
> This way you will have enough information about
> where action happened and what current selection is.
>
> So you might find out index you have to apply filter to.
>
>
> Regards,
> Alex
>
> On Tue, Jan 10, 2012 at 9:45 AM, Michele Ciampichetti
> <cia.michele at gmail.com> wrote:
> > Hello to everybody,
> > To solve this problem, i trying to subclass a QSqlRelationalDelegate, so
> > that, at che column of second combobox, I can apply a filter on the
> > QSqlTableModel returned by relationalModel; but i can't do this, because
> the
> > delegate use only a const QModelIndex so i can't access the complete
> model
> > and use the setFilter method. This is my code:
> >
> > void setEditorData(QWidget *editor, const QModelIndex &index) const
> > {
> > switch(index.column()) {
> > case 4:{
> > const QSqlRelationalTableModel * sqlModel = qobject_cast<const
> > QSqlRelationalTableModel *>(index.model());
> >
> >
> sqlModel->setFilter(QString("CodProvincia=%1").arg(sqlModel->index(index.row,10).data().toInt());
> > QComboBox * combo = qobject_cast<QComboBox *> (editor);
> > if (!sqlModel || !combo){
> > QItemDelegate::setEditorData(editor,index);
> > return;
> > }
> >
> >
> combo->setCurrentIndex(combo->findText(sqlModel->data(index).toString()));
> > break;}
> >
> > But it return an error, because the index is only a constant. This is the
> > error:
> >
> > ..\picloaddelegate.h:24: error: passing 'const QSqlRelationalTableModel'
> > as 'this' argument of 'virtual void QSqlTableModel::setFilter(const
> > QString&)' discards qualifiers
> >
> >
> > Any ideas of how resolve it?
> >
> >
> > thanks a lot for your time!
> >
> > Michele
> >
> >
> >
> >
> > 2012/1/9 Michele Ciampichetti <cia.michele at gmail.com>
> >>
> >> Good morning to all,
> >> How can I create 3 depending QCombobox, for example Country, City and
> Zip
> >> Code, so that when I select one, the other ones are filtered by the
> value of
> >> the first one? I'm use a QSqlRelationalTableModel and 3 relations (so
> also 3
> >> QSqlTableModel). I know that I can use QComboBox signal to filter data
> of
> >> QSqlTableModel, but if I use the QDataWidgetMapper the search on it
> don't
> >> fire any QCombobox Signal, so, how can I got what I want?
> >>
> >>
> >> Thanks a lot for your time!
> >>
> >> Michele
> >
> >
> > _______________________________________________
> > Interest mailing list
> > Interest at qt-project.org
> > http://lists.qt-project.org/mailman/listinfo/interest
> >
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20120112/6602d483/attachment.html>
More information about the Interest
mailing list