How to create a Combo box in a Tablview Model
Hello,
I am new in QT and trying hard to learn it. I have created a TableView model with 5 columns , i need to create the combo box in 4 and 5 columns with some respective data. I am using the Model View approach which is confusing me . I have read many posts about combobox delegates , can any one reply me which approach is better and easy to insert combobox in a tableview .
This is something close but they are using combo delegates which make the things complex.
Please help me out
Thanks
Re: How to create a Combo box in a Tablview Model
The way a view's cells are drawn is provided by a default QStyledItemDelegate. If you want to change the way the data appears when it is not being editted, or if you want to provide a combo box as the editor, then you need to provide the view with customised (subclassed) QStyledItemDelegate with the paint() and/or createEditor() functions reimplemented. The mechanism is described in the docs.
http://doc.qt.io/qt-5/qstyleditemdelegate.html#details
http://doc.qt.io/qt-5/qtwidgets-item...e-example.html
Re: How to create a Combo box in a Tablview Model
And also check out the spinbox delegate example, it should be very similar to combobox:
http://qt-project.org/doc/qt-4.8/ite...xdelegate.html
1 Attachment(s)
Re: How to create a Combo box in a Tablview Model
Hey ChrisW67,
Exactly you get my point ,star delegate is a good example but i guess i don't have to go through paint() and CreateEditor() because i just have to put the combobox in my 4th and 5th column. Please have a look at the following picture
Attachment 10880
I had followed the basic tecnique of TableView by QAbstractTableModel which display all my data perfectly , but with combobox its confusing me . I also thought to use the Combobox delegate but still confused in that.
thanks
Re: How to create a Combo box in a Tablview Model
QStyledItemDelegate::createEditor() is what puts a functional editor, in your case a QComboBox, in place of the table cell when you go into edit mode on the cell.
QStyledItemDelegate::paint() is what draws the content of the cell when it is not in edit mode. In your case you might want to fake the appearance of a QComboBox or just accept the default behaviour of displaying simple text. I suggest you leave the non-editing appearance as the default at least until you get to grips with creating the editor widget.
The QTableWidget provides an alternate mechanism to put a persistent editor widget into a cell. You can do that for a relativly small number of cells before performance starts to slow.
Re: How to create a Combo box in a Tablview Model
Hey ChrisW67,
I have understood your point but the problem is that i have the TableViewModel on "QAbstractTableModel" and how could i configure my TableView model that on column 5 and 6 i need combo box with some data . This "http://qt-project.org/doc/qt-4.8/sql...ablemodel.html" is the perfect example which i want to achieve but it is based on QSqlQuery class which i am not using . I am getting all the data from xml and storing in QMap's later which is to be displayed in these columns .
Do you suggest combo box delegate ? http://programmingexamples.net/wiki/...mboBoxDelegate Or what do your suggest in this situation ?
Thanks
Re: How to create a Combo box in a Tablview Model
This is not a model side thing, delegates are on the view side of things.
It works with any model.
Cheers,
_
Re: How to create a Combo box in a Tablview Model
The example you link to is exactly the sort of thing you need to be be doing.
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
anda_skoa
This is not a model side thing, delegates are on the view side of things.
It works with any model.
Cheers,
_
I understand that but the problem is if i use the Spinbox delegate example with combo box delegate how i can say that only in 4 and 5 column i need combo box . This http://qt-project.org/doc/qt-4.8/sql...ablemodel.html example is perfect for me but it use internal library of QSqlTableModel which i can not use because i am not using Sql.
Thanks
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
uzairsaeed702
I understand that but the problem is if i use the Spinbox delegate example with combo box delegate how i can say that only in 4 and 5 column i need combo box .
In such cases I can highly recommend to use a facility referred to as the API documentation.
A set of documents describing an API, in this case Qt's model/view classes.
When using such documentation in Qt's documentation browser Qt assistant or on the web, the respective program's functionality even allows to search within these documents!
For example a search on "Delegate" in the documentation of QAbstractItemView would find http://doc.qt.io/qt-5/qabstractitemv...egateForColumn
Repeatedly ignoring any hint on the forum and reiterating a non existant problem will eventually also lead to the solution, but take a lot longer, frustrate everyone involved and not bode well for the future of your programming endeavors.
Cheers,
_
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
uzairsaeed702
I understand that but the problem is if i use the Spinbox delegate example with combo box delegate how i can say that only in 4 and 5 column i need combo box.
I am definitely not an expert, but I have successfully used a ProgressBar delegate as follows. In my MainWindow, I set the item delegate for the view as follows:
Code:
ui->tableView->setItemDelegate(new ProgressBarDelegate());
ProgressBarDelegate is a class derived from QStyledItemDelegate and here's the paint method:
Code:
{
if (!index.isValid())
return;
int col = index.column();
if (col == 5)
{
int progress = index.data().toInt();
progressBarOption.
rect = QRect(option.
rect.
x(), option.
rect.
y() + 5 , option.
rect.
width(), option.
rect.
height() / 1.5);
if (progress == 100)
{
QApplication::style()->drawItemText
(painter, option.
rect, Qt
::AlignCenter|Qt
::AlignVCenter, option.
palette,
true,
QString::number(progress
) + "%");
}
else
{
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.
text = QString::number(progress
) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter|Qt::AlignVCenter;
}
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
return;
}
So you'll see that the delegate is set at the view level and then in the paint method, I only override how the progress bar I want in column 5 is drawn and I call the base class paint method for all other columns.
If I am following your thread correctly, I believe you should be able to take a similar approach.
Good luck.
Re: How to create a Combo box in a Tablview Model
If you only want customised behaviour for a couple of columns (or rows) then you only apply a custom delegate to those columns (or rows). This is exactly what your own linked combo box delegate does.
Jthomps approach is also a way to achieve the goal. The paint() and createEditor() functions look at which column they are being asked to act on and modify their behaviour accordingly. This method ties the delegate fairly closely to this particular view, i.e. You cannot reuse this delegate class on another view with 8 columns to get customised behaviour on columns 3 and 6.
1 Attachment(s)
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
ChrisW67
The example you link to is exactly the sort of thing you need to be be doing.
Hey ChrisW67,
Yes true but in that example everything is handled by QSqlTableModel class which automatically detects the queries and place the combo box where it is necessary , which is invalid in my case. My model
Quote:
TableModel *newTable = new TableModel(XmlMap,this)
Quote:
ui->tableView->setModel(&newTable)
Quote:
ui->tableView->setItemDelegate(&comboBoxDelegate)
creating all the necessary data structure depending on the length of Xmlmap and if i put the delegate then it'll create the combo box with in all the table cell which is what i don't want.
I am thinking to switch on QTableWidget but i have much data to view and on the other hand i am thinking that TableWidget will be slow.
I have tried a simple example through QTableWidget "Quick try"
Code:
ui->tableWidget->setItem(count, columns,newItem);
columns++;
ui->tableWidget->setItem(count, columns, newItem1);
columns++;
ui->tableWidget->setItem(count, columns, newItem2);
comboBox->addItem("modeMap");
comboBox2->addItem("valueMap");
ui->tableWidget->setCellWidget(count,3,comboBox);
ui->tableWidget->setCellWidget(count,4,comboBox2);
And in last i got a good result and it is too easy to handle, but the only problem that it is taking some time to load because my xml contain 1500 rows.
Attachment 10883
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
uzairsaeed702
ui->tableView->setItemDelegate(&comboBoxDelegate)
Let me get this straight:
- you want the delegate in certain columns only
- you ignore the existance of setItemDelegateForColumn, which does exactly that
- you keep pretending that your problem is not solved
Only reason to do that is to troll, right?
Cheers,
_
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
jthomps
I am definitely not an expert, but I have successfully used a ProgressBar delegate as follows. In my MainWindow, I set the item delegate for the view as follows:
Code:
ui->tableView->setItemDelegate(new ProgressBarDelegate());
ProgressBarDelegate is a class derived from QStyledItemDelegate and here's the paint method:
Code:
{
if (!index.isValid())
return;
int col = index.column();
if (col == 5)
{
int progress = index.data().toInt();
progressBarOption.
rect = QRect(option.
rect.
x(), option.
rect.
y() + 5 , option.
rect.
width(), option.
rect.
height() / 1.5);
if (progress == 100)
{
QApplication::style()->drawItemText
(painter, option.
rect, Qt
::AlignCenter|Qt
::AlignVCenter, option.
palette,
true,
QString::number(progress
) + "%");
}
else
{
progressBarOption.minimum = 0;
progressBarOption.maximum = 100;
progressBarOption.progress = progress;
progressBarOption.
text = QString::number(progress
) + "%";
progressBarOption.textVisible = true;
progressBarOption.textAlignment = Qt::AlignCenter|Qt::AlignVCenter;
}
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
return;
}
So you'll see that the delegate is set at the view level and then in the paint method, I only override how the progress bar I want in column 5 is drawn and I call the base class paint method for all other columns.
If I am following your thread correctly, I believe you should be able to take a similar approach.
Good luck.
Hey jthomps,
That looks helpful to me and it gives the clear idea to play for with custom columns . I will try to do it through delegates hopefully it will work.
Thanks
Regards
Uzair saeed
Quote:
Originally Posted by
ChrisW67
If you only want customised behaviour for a couple of columns (or rows) then you only apply a custom delegate to those columns (or rows). This is exactly what your own linked combo box delegate does.
Jthomps approach is also a way to achieve the goal. The paint() and createEditor() functions look at which column they are being asked to act on and modify their behaviour accordingly. This method ties the delegate fairly closely to this particular view, i.e. You cannot reuse this delegate class on another view with 8 columns to get customised behaviour on columns 3 and 6.
Yes i am getting the idea now but in actually Model View concept is bit confusing i guess i have to study that way more time to get the clear idea. But i will try today.
Thanks ChrisW67
Added after 5 minutes:
Quote:
Originally Posted by
anda_skoa
Let me get this straight:
- you want the delegate in certain columns only
- you ignore the existance of setItemDelegateForColumn, which does exactly that
- you keep pretending that your problem is not solved
Only reason to do that is to troll, right?
Cheers,
_
Hey,
It was my previous try but i am getting the combo box in each columns . Problem is only that Model View concept is bit confusing and if i go with QTableWidget its easy but takes time . Actually later from that combo box i have to attach the event which can invoke the dialog so for that complexity i am planing which method would be easy for me. So i am asking question and i am beginner that is why trying approaches .
Thanks
Re: How to create a Combo box in a Tablview Model
Quote:
Yes true but in that example everything is handled by QSqlTableModel class which automatically detects the queries and place the combo box where it is necessary , which is invalid in my case. My model
The example you linked to has nothing to do with an SQL model. The model data can come from anywhere as long as it is presented using the QAbstractItemModel interface. The model provides data only.
The rendering of data in a view has nothing to do with the model. The view passes the painting and editor creation for each cell to a delegate, either the default one or one you provide, and the delegate decides what to display for the data the model is providing. The model may provide data indicating a colour, font, icon etc. but the view delegate can choose how to use (or ignore) that information when displaying the data. The type of editor provided for a cell is entirely decided by the delegate.
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
uzairsaeed702
It was my previous try but i am getting the combo box in each columns
I highly doubt it.
Unless you are still calling setItemDelegate() instead of the correct method.
Cheers,
_
Re: How to create a Combo box in a Tablview Model
Quote:
Originally Posted by
ChrisW67
The
example you linked to has nothing to do with an SQL model. The model data can come from anywhere as long as it is presented using the QAbstractItemModel interface. The model provides data only.
The rendering of data in a view has
nothing to do with the model. The view passes the painting and editor creation for each cell to a delegate, either the default one or one you provide, and the
delegate decides what to display for the data the model is providing. The model
may provide data indicating a colour, font, icon etc. but the view delegate can choose how to use (or ignore) that information when displaying the data. The type of editor provided for a cell is entirely decided by the delegate.
Hey ChrisW67,
Now i understand everything , i am sorry this model view concept is confusing . I will try to alter the delegate class with Paint and create editor and will try to play with it. Hopefully i will achieve my target. I will stick to model view concept instead of QtableWidget .
Thanks for the motivation.
[Solved] How to create a Combo box in a Tablview Model
Finally problem solved after reading again n again about MVC and thanks "All" for the support !!
I have configured the model with Combo box delegate with openPersistentEditor in combo box enabled columns (4,5) .
In ComboBoxDelegate.cpp
Code:
{
if(index.column() == 3 || index.column() == 4)
{
// Create the combobox and populate it
cb
->addItem
(QString("Please Select"));
connect(cb,
SIGNAL(currentIndexChanged
(QString)),
this,
SLOT(print
(QString)));
return cb;
} else
return QStyledItemDelegate::createEditor(parent, option, index);
}
]
And in my TableModel.cpp Class
Code:
]
{
int row = index.row();
int col = index.column();
QMap<QString, QString> qMapPair = listOfItems.at(index.row());
if(index.isValid() && role == Qt::EditRole)
{
switch(col) {
case 3 :
{
qDebug() << "Value From Table Model = " <<value.toString() << "Row" <<row << "xCol"<< col ;
return true;
}
break;
case 4 :
{
qDebug() << "Value From Table Model = " <<value.toString() << "Row" <<row << "xCol"<< col ;
return true;
}
break;
default :
break;}}return false;}
]
and things are working perfectly , now i am working on a event that when i will select any index value in combo box it will populate a dialog which configure the data on my Map. I will ask later for further question .