事情是这样的,要在一个ComboBox中通过树形结构进行内容的选择。
默认的QComboBox展开是下拉的列表。因此需要定制一下。
效果就是这样的
实现上面效果的核心代码就是下面这样的
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
tree=new QTreeWidget(this);
auto* top=new QTreeWidgetItem({"A"});
tree->addTopLevelItem(top);
auto* child=new QTreeWidgetItem(top,{"A1"});
new QTreeWidgetItem(top,{"A2"});
new QTreeWidgetItem(top,{"A3"});
new QTreeWidgetItem(child,{"AA1"});
new QTreeWidgetItem(child,{"AA2"});
top=new QTreeWidgetItem({"B"});
tree->addTopLevelItem(top);
child=new QTreeWidgetItem(top,{"B1"});
new QTreeWidgetItem(top,{"B2"});
new QTreeWidgetItem(top,{"B3"});
new QTreeWidgetItem(child,{"BB1"});
new QTreeWidgetItem(child,{"BB2"});
cbx=new QComboBox(this);
cbx->setEditable(true);
cbx->setModel(tree->model());
cbx->setView(tree);
tree->expandAll();
this->setCentralWidget(cbx);
}
现在有一个问题!
点击树中的任何item,树都会收起来,然后关闭掉。
这不是想要的效果,想要的效果是,点击树中的非最底层节点,树的层级会相应的收起来或者展开。而点击最底层的节点,则选中相应的item,收起来。
一个实现方法是,通过事件处理来解决:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
tree=new QTreeWidget(this);
cbx=new QComboBox(this);
cbx->setEditable(true);
auto* top=new QTreeWidgetItem({"A"});
tree->addTopLevelItem(top);
auto* child=new QTreeWidgetItem(top,{"A1"});
new QTreeWidgetItem(top,{"A2"});
new QTreeWidgetItem(top,{"A3"});
new QTreeWidgetItem(child,{"AA1"});
new QTreeWidgetItem(child,{"AA2"});
top=new QTreeWidgetItem({"B"});
tree->addTopLevelItem(top);
child=new QTreeWidgetItem(top,{"B1"});
new QTreeWidgetItem(top,{"B2"});
new QTreeWidgetItem(top,{"B3"});
new QTreeWidgetItem(child,{"BB1"});
new QTreeWidgetItem(child,{"BB2"});
//在这里设置时,无法过滤MouseButtonRelease事件
// tree->viewport()->installEventFilter(this);
cbx->setModel(tree->model());
cbx->setView(tree);
tree->expandAll();
//在这里设置时,可以过滤MouseButtonRelease事件
tree->viewport()->installEventFilter(this);
this->setCentralWidget(cbx);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if(watched==tree->viewport())
{
qDebug()<<"event of tree";
qDebug()<<"event:"<<event;
if(event->type()==QEvent::MouseButtonPress)
return true;
if(event->type()==QEvent::MouseButtonRelease)
{
qDebug()<<"event of tree MouseButtonRelease";
QMouseEvent* ee=static_cast<QMouseEvent*>(event);
QModelIndex index=tree->indexAt(ee->pos());
if(!index.isValid())
return false;
QTreeWidgetItem* item= static_cast<QTreeWidgetItem*>(index.internalPointer());
if(item->childCount()!=0)
{
if(tree->isExpanded(index))
{
tree->collapse(index);
}
else
tree->expand(index);
}
else
{
qDebug()<<"item selected::"<<item->text(0);
// cbx->setEditText(item->text(0));
cbx->setCurrentText(item->text(0));
cbx->hidePopup();
}
return true;
}
}
return QObject::eventFilter(watched,event);
}
其中下面这句代码目的是实现点击树的下拉三角时不响应两次,响应两次将导致一次点击打开又关闭
if(event->type()==QEvent::MouseButtonPress)
return true;
软件产品展示