PDA

View Full Version : Using a QCombobox to select which coloum to display i QListView



salcin
21st May 2013, 22:39
I have a custom model subclassing QAbstractTableModel. The model contain 4 column of data and in the 5:th column I merge all the data from the other 4 columns.
I want to display one column at a time in a QListView. To select which column to display I want to use a QComboBox. Is there a way to automatically display the available columns in the QComboBox by using the same model as in the QListView?

My thoughts:

Using a qproxymodel to read the headerdata and return it in data(index). Set the proxy model in the QComboBox
Using two separate models

Any other ideas?

Thanks!

ChrisW67
21st May 2013, 23:40
Does tableView->horizontalHeader()->model() give you a suitable model to use as the list model?

salcin
22nd May 2013, 11:55
Maybe. Do you mean that should set the horizontalHeaderModel as the model for the QListView?
I can set the table model as the model for the QListView and select which column to display with ; setModelColumn(0). But I need to extract the headers in some way to display them in a QComboBox. I think I need to use the same model in both views to be sure that they will be updated whenever data is changed in the model.

salcin
23rd May 2013, 11:56
Is there a way to change QListView to use the model's headerData() and coulmnCount() instead of data() and rowCount()?

Santosh Reddy
23rd May 2013, 12:38
You can use proxy model


class HeaderProxy : public QAbstractProxyModel
{
public:
explicit HeaderProxy(QObject * parent = 0)
: QAbstractProxyModel(parent)
{
;
}

QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const
{
if(!parent.isValid())
return createIndex(row, column);
return QModelIndex();
}

QModelIndex parent(const QModelIndex & /*child*/) const
{
return QModelIndex();
}

QModelIndex mapToSource(const QModelIndex & proxyIndex) const
{
if(!proxyIndex.isValid())
return QModelIndex();

return createIndex(proxyIndex.row(), proxyIndex.column());
}

QModelIndex mapFromSource(const QModelIndex & sourceIndex) const
{
if(!sourceIndex.isValid())
return QModelIndex();

return index(sourceIndex.row(), sourceIndex.column() );
}

int rowCount(const QModelIndex &parent) const
{
return sourceModel()->columnCount(parent);
}

int columnCount(const QModelIndex &/*parent*/) const
{
return 1;
}

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
return sourceModel()->headerData(index.row(), Qt::Horizontal, role);
}
};

//elsewhere
TableWidget tableWidget;
tableWidget.show();
// Populate rows, columns and other data.

QListView listView;
listView.show();

QComboBox comboBox;
comboBox.show();

HeaderProxy m;
m.setSourceModel(tableWidget.model());
listView.setModel(&m);
comboBox.setModel(&m);

//connect the required signal of comboBox to listView

salcin
23rd May 2013, 13:26
Thanks!

It is almost what I want. When I use the proxy model in the combobox the items are not selectable. do I have to implement mapSelectionFromSource and mapSelectionToSource for them to be selectable?

Santosh Reddy
23rd May 2013, 13:40
If you are using the proxy in the example which I posted you should be able to select items in QComboBox.

BTW selectable option depends on Qt::ItemFlags HeaderProxy::flags(const QModelIndex &index) const; that too if you implement it, else the base class QAbstractProxyModel implementation should enable you to select by default

salcin
23rd May 2013, 14:32
For some reason, the combobox still displays grayed out items.
I tried to implement
Qt::ItemFlags flags(const QModelIndex & index) const
{
return Qt::ItemIsSelectable;
}

but the combobox didn't respond to that.

Santosh Reddy
23rd May 2013, 21:18
1. Don't implement the flags() function
or
2. return Qt::ItemSeletable | Qt::ItemEnabaled

salcin
24th May 2013, 09:59
Thanks
Adding Qt::ItemIsEnabled did the trick!

aShook
22nd June 2013, 00:05
This seems to only work if the row and column count are static and not changing. When Columns are inserted and removed I get empty feilds everywhere.
What do we need to reimpliment to get the proxy to track the source as it changes size?

Thanks