PDA

View Full Version : How to populate Combobox in QTableView



ronak.vashi
30th November 2010, 16:40
Hi,

I have an application where user enters transaction entries in bulk and application saves it in database. I am using QTableView for transaction entry. It has 7 columns and 1 row by default. There is a button given to add more transaction rows.

Out of 7 columns one column is Transaction Type which is a QComboBox which should be populated from database table.

I am using Qt's Model-View-Delegate concept to show combobox and other widgets on each cell.

Query:


How to populate combobox from database table in UI class (AddBankTrxns) ?
I don't want to add sql queries in delegate class (ComboBoxDelegate).


Classes used :

AddBankTrxns : UI class where Transaction table is shown.
ComboBoxDelegate : Delegate class to show table cell as ComboBox.

Thanks in advance.

franz
30th November 2010, 19:03
You could add a specific item role (MySuperDuperRole = Qt::UserRole + x) that provides your delegate with the options (and thereby keep the sql queries in the model). The delegate will then fetch the list of options from the model using MySuperDuperRole.

ronak.vashi
1st December 2010, 16:41
You could add a specific item role (MySuperDuperRole = Qt::UserRole + x) that provides your delegate with the options (and thereby keep the sql queries in the model). The delegate will then fetch the list of options from the model using MySuperDuperRole.

Hi
Would you please elaborate more ?? I am not quite familiar with Model-View-Delegate concept.

Where to specify specific item role ??
Where sql queries will go, in AddBankTrxns or in ComboBoxDelegate ??

If you can paste some sample code, that will help

Thanks

MattPhillips
1st December 2010, 18:53
Can't you just use QComboBox::setModel, after calling QSqlTableModel::setQuery to get the data?

ronak.vashi
2nd December 2010, 14:31
May be I can use QSqlTableModel but in that case also still I have to run the query in Delegate class ComboBoxDelegate and I have to create one more connection to database which I want to avoid.

Is there any way to get ComboBox in UI class AddBankTrxns? If I can get ComboBox in this class then it is straightforward to populate it as already db connection is available in this class.

I have pasted code here for reference:

Class : AddBankTrxns



AddBankTrxns::AddBankTrxns(QWidget *parent) :
QWidget(parent),
ui(new Ui::AddBankTrxns)
{
connectionName = "addbanktrxns";
loggedInUserid = 0;

ui->setupUi(this);

headerLabels.append("Trxn Date");
headerLabels.append("Trxn Description");
headerLabels.append("Cheque No.");
headerLabels.append("Trxn Type");
headerLabels.append("Amount");
headerLabels.append("Trxn Category");
headerLabels.append("Remarks");

model = new QStandardItemModel(0, k_BANK_TRNX_COL_CNT);
model->setHorizontalHeaderLabels(headerLabels);
ui->bankTrxnsView->setModel(model);

addTransactionRow(0);
setDBConnection();
}
void AddBankTrxns::addTransactionRow(int row){
model->insertRow(row);
ui->bankTrxnsView->setModel(model);

ui->bankTrxnsView->setItemDelegateForColumn(0, new DateEditDelegate());
ui->bankTrxnsView->setItemDelegateForColumn(1, new LineEditDelegate());
ui->bankTrxnsView->setItemDelegateForColumn(2, new LineEditDelegate());
ui->bankTrxnsView->setItemDelegateForColumn(3, new ComboBoxDelegate());
ui->bankTrxnsView->setItemDelegateForColumn(4, new LineEditDelegate());
ui->bankTrxnsView->setItemDelegateForColumn(5, new LineEditDelegate());
ui->bankTrxnsView->setItemDelegateForColumn(6, new LineEditDelegate());
ui->bankTrxnsView->scrollToBottom();
ui->bankTrxnsView->show();

setRowItemWidgets(row);
// qDebug() << "After:rowcount=" << model->rowCount();
}


Class : ComboBoxDelegate



ComboBoxDelegate::ComboBoxDelegate(QObject *parent) :
QItemDelegate(parent)
{
}

QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QComboBox *editor = new QComboBox(parent);
return editor;
}

void ComboBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
// QString value = index.model()->data(index, Qt::EditRole).toString();

QComboBox *comboBox = static_cast<QComboBox*>(editor);
}

void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
model->setData(index, comboBox->currentText(), Qt::EditRole);
}

void ComboBoxDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}

MattPhillips
2nd December 2010, 22:54
You just want the user to be able to edit entries in the combo box, right? Why do you need your own QItemDelegates at all? I've never used it, but it looks like it's used for custom rendering. QComboBox as it is supports editing individual elements with the default delegates. So just have

ui->my_combo_box->setModel(model);

in your widget constructor, assuming the QComboBox is part of that gui.

ronak.vashi
3rd December 2010, 08:52
No..I don't want user to edit entries in ComboBox. Combo box will be read-only and user just need to select any one option populated.

Actually I just followed method shown in Qt ItemView example of spinbox shown on TableView. I am not sure if there is any other way to show widgets on QTableView w/o using ItemDelegates.

BalaQT
3rd December 2010, 13:34
hi,

QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QComboBox *editor = new QComboBox(parent);
QComboBox::setEditable(false);
// u can populate ur combo here.
return editor;
}


hope it helps
Bala

ronak.vashi
4th December 2010, 17:09
hi,

QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QComboBox *editor = new QComboBox(parent);
QComboBox::setEditable(false);
// u can populate ur combo here.
return editor;
}


hope it helps
Bala

Hi all

Thanks for help. It worked and I was able to populate Combobox list items from createEditor() function, but found a observation that if we are using Delegates then setEditorData is getting called twice once when view cell is double clicked and when mouse is clicked somewhere else. Not sure why it is behaving like this :confused:.

Infact I find another easy way to set widgets. There is ready made function setIndexWidget() available to set a widget at particular cell.

Now issue with this approach is that I am not able to get cell data. Not able to find suitable function from QTableView or way to read user entered or selected data.

Any idea how to get data from QTableView ?