PDA

View Full Version : QComboBox listview in separate dialog



tomasl
17th September 2012, 18:41
I want the list view of QComboBox to be in a separate dialog widget. To achieve this, I've subclassed QComboBox, and use the showPopup() and hidePopup() functions to view the dialog. The dialog now takes a QListView as constructor parameter from the combo, but doing it this way, I see that the list in dialog does not have the same selection as the original combo. Should I do the QListView pointer differently?



ComboBox::ComboBox(QWidget *parent, QString strTitle) :
QComboBox(parent)
{

m_pListView = new QListView(this);

QFont newfont = font();
newfont.setPixelSize(globalUI->zoomInt(9));
m_pListView->setFont(newfont);
setMinimumContentsLength(10);
setView(m_pListView);

m_pComboList = new ComboList(this, m_pListView);
SetTitle(strTitle);

}

void ComboBox::SetTitle(QString strTitle)
{
m_pComboList->SetTitle(strTitle);
}

void ComboBox::showPopup ()
{
m_pComboList->exec();
}

void ComboBox::hidePopup ()
{
m_pComboList->hide();
}

ComboList::ComboList(QWidget *parent, QListView *pListView, QString strTitle):
DialogExt(parent)
{
// Only to be shown when combobox popup is to be shown
this->hide();

if (pListView == 0)
{
qWarning() << "[ComboList::ComboList] listView is 0";
return;
}
// List
pListView->setVerticalScrollMode(QListWidget::ScrollPerPixel) ;
pListView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
pListView->setWordWrap(true);

m_pTextEditSearchFilter = new textNumericInput(this); //this is a subclass of QLineEdit
connect(m_pTextEditSearchFilter, SIGNAL(SigTextChanged(QString)), this, SLOT(FilterChanged(QString)));

//used for filtering list view
m_pProxyModel = new QSortFilterProxyModel(this);
m_pProxyModel->setSourceModel(pListView->model());
pListView->setModel(m_pProxyModel);

m_ppushBack = new MenuButton(this, ":/icons/back_white" + globalUI->GetImageSuffix(),tr("Back"), globalUI->zoomSize(QSize(40,30)),false);
globalUI->setMenuButtonProperties(m_ppushBack,UIToolbox::MBT SubMenuButton);

QFrame *pFrameMenuBar = new QFrame(this);
pFrameMenuBar->setStyleSheet("background: gray;");
QHBoxLayout *playoutmenuBar = new QHBoxLayout(pFrameMenuBar);
playoutmenuBar->setMargin(0);
playoutmenuBar->setSpacing(0);
playoutmenuBar->addStretch();
playoutmenuBar->addWidget(m_ppushBack);
playoutmenuBar->addStretch();

m_plblTitle = new QLabel(strTitle, this);
m_plblTitle->setWordWrap(true);
m_plblTitle->setAlignment(Qt::AlignCenter);
m_plblTitle->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_plblTitle->setStyleSheet("background: #D8D8D8; font-size: " + QString::number(globalUI->zoomInt(7)) + "px;");

QWidget *widPlaceholderMain = new QWidget();
QVBoxLayout *playoutMain = new QVBoxLayout(widPlaceholderMain);
playoutMain->setMargin(0);
playoutMain->addWidget(m_plblTitle);
playoutMain->addSpacing(1);
playoutMain->addWidget(m_pTextEditSearchFilter);
playoutMain->addSpacing(1);

QWidget *widPlaceholder = new QWidget();
QVBoxLayout *playoutMainScroll = new QVBoxLayout(widPlaceholder);
playoutMainScroll->addWidget(pListView);

QScrollArea *scroll = new QScrollArea(this);
scroll->setContentsMargins(0,0,0,0);
scroll->setFrameShape(QFrame::NoFrame);
scroll->setLineWidth(0);
scroll->setWidgetResizable(true);
scroll->setMinimumHeight(0);
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
scroll->setWidget(widPlaceholder);

QVBoxLayout *layVMain = new QVBoxLayout(this);
layVMain->setMargin(0);
layVMain->setSpacing(0);
layVMain->addWidget(widPlaceholderMain);
layVMain->addWidget(scroll);
layVMain->addWidget(pFrameMenuBar);
}

void ComboList::SetTitle(QString strTitle)
{
m_plblTitle->setText(strTitle);
}

void ComboList::FilterChanged(QString strFilter)
{
m_pProxyModel->setFilterRegExp(QRegExp(strFilter, Qt::CaseInsensitive, QRegExp::FixedString));

}

pkj
17th September 2012, 19:17
QComboBox::model(). Use it to get the model and have a independent QListView in your dialog. Set the model of this QListView to the model from QCombobox.

tomasl
17th September 2012, 20:04
Thanks for the hint.
I tried changing the dialog constructor to this:


ComboList::ComboList(QWidget *parent, QAbstractItemModel *pListModel, QString strTitle):
DialogExt(parent)

And set up the model like this:

m_pList = new QListView(this);
m_pList->setModel(pListModel);

This however gives the same result as initially. The dialog view is populated correctly, but the selected item is not set in the dialog list. And when selecting something here, the original combobox does not show the changed item.

pkj
18th September 2012, 04:36
If you need the selected items to be in sync then you need to share the selection model. A selection model belonging to one view can be obtained using the view's selectionModel() function, and shared between many views with setSelectionModel().
Get QComboBox::view()::selectionModel(). Then QListView::setSelectionModel(...)