Delegates and relational table views
-
Hi :)
I am using QSqlRelationalDelegate into a QSqlRelationalTableView, which works fine.
However I'd like the combo box to be able to filter as I type, because it holds several thousands of items. I'd like to know if this can be implemented with this kind of delegate or if I should be looking at QStyledDelegate or something else instead.
Having filter capabilities in the delegate would also be nice, though I think I can solve that in some other way.
I have read the documentation, but the QSqlRelationalDelegate page is so so simple that I am really wondering if that's really all that there's to it. Still learning as I go :)
Thanks everyone.
-
so you have an editable comobox as an editor?
If so you can use QComboBox::setCompleter() on the editor widget (combobox) -
[quote author="raven-worx" date="1376469355"]so you have an editable comobox as an editor?
If so you can use QComboBox::setCompleter() on the editor widget (combobox)[/quote]I don't really know. It's a combo box, but I have no idea how qt handles this internally. I am using QSqlRelationalDelegate, this way:
[code]
ui->tableView_cascosYAccesorios->setItemDelegate(new QSqlRelationalDelegate(ui->tableView_cascosYAccesorios));
[/code]With whatever "editor" it uses by default. I have also tried to declare the delegate separately, but I have no idea how to access its editor, if that's even possible.
That's why I am wondering if I should use another kind of delegate which is more flexible...
Thanks for your help :)
-
Right now, I have this:
[code]
class MySqlDelegate : public QSqlRelationalDelegate
{
Q_OBJECT
public:
explicit MySqlDelegate(QObject *parent = 0);signals:
public slots:
void setEditorData ( QWidget * editor, const QModelIndex & index ) const
{
QSqlRelationalDelegate::setEditorData(editor, index);QComboBox* comboBox = qobject_cast<QComboBox*>(editor); comboBox->setEditable(true); if( comboBox ) { QCompleter* completer = new QCompleter(comboBox); completer->setCompletionColumn(index.column()); completer->setCompletionMode(QCompleter::PopupCompletion); completer->setWrapAround(true); completer->setMaxVisibleItems(10); completer->setCaseSensitivity(Qt::CaseInsensitive); comboBox->setCompleter(completer); connect(comboBox, SIGNAL(editTextChanged(QString)), completer, SLOT(setCompletionPrefix(QString))); } }
};
[/code]It seems the setEditable(true) bit got me as far as to being able to actually edit the combobox, however the filtering doesn't seem to work and I get no popup.
The popup works ok and shows all the elements if I click the down arrow icon, of course. Which is why I know that the combobox has been populated as it should.
I also tried connecting the things in some manner, but it didn't make a difference. Please, don't lauch at me :)
It's my first time with delegates, so, you know... :P
Thank you everyone.
-
so did it solve your problem or do you still have an issue?
-
Nope, sorry for not being so clear.
It doesn't seem to actually filter anything, and the popup doesn't appear as I write.
I'd also like the QComboBox field empty on the first keypress, but that's the not my bigest problem right now, and I should be able to figure that out eventually (or so I hope).
I am having some trouble to find QCompleter/QComboBox examples in the net, plus I don't really know what QSqlRelationalDelegate does under the hood.
I think I need some coffee, then I'll get back to this ;)
-
just some additions to your code:
put the "comboBox->setEditable(true)" inside the if statement to avoid possible crashes.I don't think that you need to connect the completer explicitly. It should be enough to just set it on the combobox.
-
[quote author="raven-worx" date="1376490168"]just some additions to your code:
put the "comboBox->setEditable(true)" inside the if statement to avoid possible crashes.[/quote]Thanks, that makes sense.
[quote]
I don't think that you need to connect the completer explicitly. It should be enough to just set it on the combobox.[/quote]That's what I thought. After all, I am subclassing a completelly functional critter, but it doesn't seem to do a thing (it doesn't do a thing after the explicit connection either, so...).
The items are there, in the popup and I can select them with the mouse. But they are not affected by any kind of filtering, it doesn't matter what I write in the box.
-
ok i think the QCompleter is missing it's values ;)
Try this:
@
class MySqlDelegate : public QSqlRelationalDelegate
{
Q_OBJECTpublic: explicit MySqlDelegate(QObject *parent = 0); void setEditorData ( QWidget * editor, const QModelIndex & index ) const { QSqlRelationalDelegate::setEditorData(editor, index); QComboBox* comboBox = qobject_cast<QComboBox*>(editor); if( comboBox ) { comboBox->setEditable(true); QCompleter* completer = new QCompleter(index.model(), comboBox); completer->setCompletionColumn(index.column()); completer->setCompletionMode(QCompleter::PopupCompletion); completer->setWrapAround(true); completer->setMaxVisibleItems(10); completer->setCaseSensitivity(Qt::CaseInsensitive); comboBox->setCompleter(completer); } } };
@
-
I can't seem to be able to do that. I can't use setModel() either, not on a const QModelIndex& argument... I'll continue trying things, but I'd really appreciate a good book on models, indexes, records, and that stuff. Right now it's all a wonderful spaghetti to me :P
Your help is much appreciated. Thanks again.
-
It seems that we also need to reimplement the method for the model. I ended up using this:
http://qt-project.org/wiki/QSqlRelationalDelegate-subclass-for-QSqlRelationalTableModel
Which "just works" after setting the edit capabilities to true, just as before. I promise to get back to this some day, but I've lost a whole day in this and I am in a bit of a hurry now.
Thank you a ton, this has been quite illustrative, but for now it's a bit over my head. :(