0

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

  • std::map

    typedef std::map< CompanyData, std::vector< ContractorData >, LessData< CompanyData >> 公司;

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

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

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

以及我需要它QTreeView用上面的这些数据创建的所有东西!

任何人都可以帮忙吗?

非常感谢!

4

1 回答 1

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;

其中CompanyData,ContractorsData是简单的结构...

祝你今天过得愉快!

于 2011-11-17T14:16:12.583 回答