【问题标题】:Need example about nodes in QAbstractItemModel for QTreeView?需要有关 QTreeView 的 QAbstractItemModel 中节点的示例吗?
【发布时间】:2011-10-07 11:44:47
【问题描述】:

问题:我正在寻找有关将模型(基于 QAbstractItemModel)创建到 QTreeView 的示例,但找不到 sane 代码。 Qt的例子是基于QStandardModel的,不是很实用也很复杂,Internet examples是基于python的?!代码...其他信息无法给我正确的方向。所以,这就是我所拥有的:

  • std::map

    typedef std::map, LessData> Companies;

这是数据示例(CompanyName + ContractorsNames):

[Microsoft]*
   [Bill Gates]
   [Steve Balmer]
   [...]
[Apple]*
   [Steve Jobs - R.I.P.]
   [Wozniak]
[OtherStuff]*
...

where * 表示 - 可扩展项(父项)

我需要它来使用上面的数据创建QTreeView

有人可以帮忙吗?

非常感谢!

【问题讨论】:

  • 你看the official Qt examples for Item View classes了吗?如果有一件事你不能指责 Qt,那就是它的文档质量。
  • Mat,你想说的是,这个例子( URL - doc.qt.nokia.com/latest/… ,见 TreeModel::setupModelData() func )真的很好回答我的问题吗?我认为不是...它基于文件读取,从该文件填充...是的,这很好,Qt 文档很棒,但我只是从std::map 创建树。我知道,我必须创建一些 node 类,但是如何将它与继承自 QAbstractItemModel 的类结合起来 - 我不知道......嗯,也许你是对的,也许我需要搞砸这个例子......
  • 您找不到开箱即用的示例。但它们为您提供了如何使用 API 的基础知识。阅读它们,最好对它们进行编码和编译,以了解它们是如何工作的。一旦你得到了它,你就可以将它适应你的代码。只是您在该评论中提出的问题告诉我您没有花足够的时间阅读示例和模型视图框架文档。
  • 好吧,我猜你是对的。谢谢!

标签: qt qt4 qtreeview


【解决方案1】:

所以,由于这里没有发布任何帖子,我在这里发布了我自己的解决方案(也使用了文本过滤):

void ContractorsFilter::onCustomFilterChanged( const QString& text )
{
     try
     {
          struct MatchFilter
          {
               // data
               QString        filter_;
               Companies&     filtered_recipients_;

               // methods
               MatchFilter( const QString& _filter, Companies& _recipients )
                    : filter_( _filter )
                    , filtered_recipients_( _recipients )
               {
                    filtered_recipients_.clear();
               }

               void operator()( const Companies::value_type& val ) const
               {
                    bool isFound = false;
                    std::vector< ContractorData >::const_iterator con_i( val.second.begin() ), con_e( val.second.end() );
                    for( ; con_i != con_e; ++con_i )
                    {
                         const QString contractorName = (*con_i).name;
                         if( contractorName.contains( filter_, Qt::CaseInsensitive ) )
                         {
                              filtered_recipients_[ val.first ].push_back( (*con_i) );
                              isFound = true;
                         }
                    }

                    const QString companyName = val.first.name;
                    if( companyName.contains( filter_, Qt::CaseInsensitive ) )
                    {
                         filtered_recipients_[ val.first ].push_back( ContractorData() );
                    }
               }
          };

          struct FillView
          {
               // data
               QFont     boldFont;
               QBrush    whiteBrush;

               QStandardItemModel* model_;

               // methods
               FillView( QStandardItemModel* model )
                    : model_( model )
               {
                    model_->clear();
               }

               void operator ()( const Companies::value_type& val ) const
               {
                    struct AppendContractors 
                    {
                         // data
                         QStandardItem* parent_;

                         // methods
                         AppendContractors( QStandardItem* _parent = 0 )
                              : parent_( _parent )
                         {}

                         bool isEmpty( const ContractorData& contractor ) const
                         {
                              return contractor.id.isEmpty();
                         }

                         void operator()( const std::vector< ContractorData >::value_type& contractor ) const
                         {
                              if( !isEmpty( contractor ) )
                              {
                                   QStandardItem *item = 0;

                                   QList< QStandardItem* > line;
                                   line << ( item = new QStandardItem( QIcon( ACCOUNT_ITEM_ICON ), contractor.name ) );
                                   item->setSizeHint( QSize( 0, 25 ) );

                                   parent_->appendRow( line );
                              }
                         }
                    };

                    QStandardItem *parentItem = model_->invisibleRootItem();

                    // добавляем новую компанию + контрагента
                    QList< QStandardItem* > line;
                    line << ( parentItem = new QStandardItem( QIcon( COMPANY_ITEM_ICON ), val.first.name ) );
                    parentItem->setSizeHint( QSize( 0, 25 ) );

                    model_->appendRow( line );

                    std::for_each( val.second.begin(), val.second.end(), AppendContractors( parentItem ) );
               }
          };

          // удаляем символ(ы), которые не фильтруются
          // формируется новая таблица, которая и будет использоваться моделью для отображения
          std::for_each( data_.begin(), data_.end(),
               MatchFilter( text, filter_data_ ) );

          // вывод отфильтрованных контрагентов
          std::for_each( filter_data_.begin(), filter_data_.end(),
               FillView( model_ ) );

          ui_.treeView->expandAll();
     }
     catch( const std::exception& e )
     {
          Core::errLog( "ContractorsFilter::onCustomFilterChanged", e.what() );
          throw;
     }
}

PS:输入Companies是一个

typedef std::map< CompanyData, ContractorsData, LessData< CompanyData > > Companies;

其中CompanyDataContractorsData 是简单结构...

祝你有美好的一天!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-29
    • 2016-07-20
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多