QComboBox + QTreeView技巧

实际上,有时有必要在QComboBox中显示树状数据结构。

Qt中用于此类数据结构的标准组件是QTreeView,此外,
QComboBox可以在其内部显示此组件,但是与往常一样,文档中也有很小的空间,因为您不仅需要显示树,还需要设置用户选择的当前元素。

让我们看看如何正确地做。

首先,创建组件本身,该组件将显示数据,为此,我们从QComboBox继承并为其提供所需的属性。

我们在类的关闭部分声明QTreeView类的变量m_view,该变量将在QComboBox中显示树,重新定义2个负责打开和关闭组件行为的函数:

  • void showPopup()覆盖; -当用户扩展列表时执行
  • void hidePopup()覆盖; -当用户通过单击选择项目时执行

我们还添加了hideColumn(int n)函数,该函数将隐藏QTreeView中所需的列,因为如果您的模型由多个列组成,则QComboBox将全部显示(标准组件使用列表),这看起来非常难看

treecombobox.h

#ifndef TREECOMBOBOX_H #define TREECOMBOBOX_H #include <QtWidgets/QComboBox> #include <QtWidgets/QTreeView> class TreeComboBox final : public QComboBox { public: TreeComboBox(); void showPopup() override; void hidePopup() override; void hideColumn(int n); void expandAll(); void selectIndex(const QModelIndex &index); private: QTreeView *m_view = nullptr; }; #endif //TREECOMBOBOX_H 

treecombobox.cpp

 TreeComboBox::TreeComboBox() { m_view = new QTreeView; m_view->setFrameShape(QFrame::NoFrame); m_view->setEditTriggers(QTreeView::NoEditTriggers); m_view->setAlternatingRowColors(true); m_view->setSelectionBehavior(QTreeView::SelectRows); m_view->setRootIsDecorated(false); m_view->setWordWrap(true); m_view->setAllColumnsShowFocus(true); m_view->setItemsExpandable(false); setView(m_view); m_view->header()->setVisible(false); } void TreeComboBox::hideColumn(int n) { m_view->hideColumn(n); } void TreeComboBox::expandAll() { m_view->expandAll(); } void TreeComboBox::selectIndex(const QModelIndex &index) { setRootModelIndex(index.parent()); setCurrentIndex(index.row()); m_view->setCurrentIndex( index ); } void TreeComboBox::showPopup() { setRootModelIndex(QModelIndex()); QComboBox::showPopup(); } void TreeComboBox::hidePopup() { setRootModelIndex(m_view->currentIndex().parent()); setCurrentIndex( m_view->currentIndex().row()); QComboBox::hidePopup(); } 

在构造函数中,我们设置需要查看的树,使其在“ QComboBox”中看起来“嵌入”,删除标题,隐藏扩展元素,并将其设置为显示元素。

在QComboBox中正确安装用户选择的项的技巧是showPopup()和hidePopup()函数。

由于QComboBox使用“平面”模型视图,因此无法在树模型中设置用户选定元素的正确索引,因为它们为此使用相对于父元素的索引:
showPopup()

根元素-我们将根索引设置为无效的模型索引,以便QComboBox显示模型的所有元素。
hidePopup()

根元素-我们设置用户选择的模型元素的父元素的索引,然后相对于父元素,我们通过索引设置所选的用户元素。

它的用法如下:

 int main(int argc, char *argv[]) { QApplication a(argc, argv); QWidget w; QStandardItemModel model; QStandardItem *parentItem = model.invisibleRootItem(); for (int i = 0; i < 4; ++i) { QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); parentItem->appendRow(item); parentItem = item; } TreeComboBox t; t.setModel(&model); t.expandAll(); auto lay = new QVBoxLayout; lay->addWidget( &t); w.setLayout(lay); w.show(); return a.exec(); } 

Source: https://habr.com/ru/post/zh-CN420977/


All Articles