Комплектник для Combobox не показан - PullRequest
0 голосов
/ 12 марта 2019

Я создаю завершитель для Combobox.

MyComboBox.cpp

MyComboBox::MyComboBox( QWidget *p_parent ) : QComboBox( p_parent )
{
  setEditable( true );

  m_view = new CompleterView();

  m_sourceModel = new CompleterSourceModel( this );
  m_sourceModel->setCompleterData( createTestData() );  //here I put test data for debugging.
  // I have checked, data is loaded into the model successfully.

  setView( m_view );
  setModel( m_sourceModel );

  QCompleter *completer = new QCompleter( m_sourceModel, this );
  completer->setCompletionMode( QCompleter::PopupCompletion );
  completer->setModelSorting( QCompleter::CaseInsensitivelySortedModel );
  completer->setFilterMode( Qt::MatchContains );
  completer->setCaseSensitivity( Qt::CaseInsensitive );
  completer->setWrapAround( true );
  setCompleter( completer );
}

Мое представление основано на TreeView

CompleterView.cpp

CompleterView::CompleterView( QWidget *p_parent ) : QTreeView( p_parent )
{
  setFocusPolicy( Qt::NoFocus );
  setCursor( QCursor( Qt::PointingHandCursor ) );
  setFrameShape( QFrame::NoFrame );
  setSelectionBehavior( QAbstractItemView::SelectRows );
  setSelectionMode( QAbstractItemView::SingleSelection );
  setRootIsDecorated( false );
  setSortingEnabled( true );
  setIndentation( 0 );
  expandAll();
}

Моя модель основана на QAbstractItemModel (функции parent и index здесь не важны для моего случая)

CompleterSourceModel.cpp

CompleterSourceModel::CompleterSourceModel( QObject *p_parent ) : QAbstractItemModel( p_parent )
{
}

QModelIndex CompleterSourceModel::index( int p_row, int p_column, const QModelIndex &p_parent ) const
{  
  return createIndex( p_row, p_column, nullptr );
}

QModelIndex CompleterSourceModel::parent( const QModelIndex &p_index ) const
{
  return {};
}

int CompleterSourceModel::rowCount( const QModelIndex &p_parent ) const
{
  return m_completerData.data().size();
}

int CompleterSourceModel::columnCount( const QModelIndex &p_parent ) const
{
  return m_completerData.headers().size() + 1; //+1 is for my purpose
}

QVariant CompleterSourceModel::data( const QModelIndex &p_index, int p_role ) const
{
  if ( p_role == Qt::UserRole ) 
  {
    if ( m_completerData.data().values().size() > p_index.row() ) 
    {
      return QVariant( static_cast<int>( m_completerData.data().values().at( p_index.row() ) ) );
    }
  }
  else if ( p_role == Qt::DisplayRole )
  {
    QList<QPair<QString, QVariant>> rowContent = m_completerData.data().keys().at( p_index.row() );
    CompleterData::Type type = m_completerData.data().values().at( p_index.row() );
    if ( type == CompleterData::Type::Header || type == CompleterData::Type::SecondHeader )
    {
      if ( p_index.column() == 0 )
      {
        return rowContent.first().first;
      }
    }
    else
    {
      if ( rowContent.size() > p_index.column() )
      {
        return rowContent.at( p_index.column() ).first;
      }
    }
  }

  return {};
}

QVariant CompleterSourceModel::headerData( int p_section, Qt::Orientation p_orientation, int p_role ) const
{
  if ( p_role == Qt::DisplayRole && p_orientation == Qt::Horizontal )
  {
    if ( m_completerData.headers().size() > p_section )
    {
      return m_completerData.headers().at( p_section );
    }
  }

  return {};
}

void CompleterSourceModel::setCompleterData( const CompleterData &p_completerData )
{
  m_completerData = p_completerData;
}

Я посмотрел и сравнил свой код с 4 примерами Qt для Completer пример 1 пример 2 пример 3 пример 4

По-моему, я не вижу различий между кодом mein и их кодом.Они просто устанавливают setCompleter() и ничего более особенного, сигнал / слот не требуется.Но я не знаю, почему мой код не работает.Когда я набираю в выпадающем списке, ничего не появляется.Не могли бы вы показать что-то нехорошее в моем коде?

Обновление

CompleterData.cpp

 QMap < QList<QPair<QString, QVariant>>, CompleterData::Type> CompleterData::data() const
 {
   return m_data;
 }

 void CompleterData::addData( const  QList<QPair<QString, QVariant>> &p_rowData, CompleterData::Type p_type )
 {
   m_data.insert( p_rowData, p_type );
 }

 void CompleterData::setData( const  QMap < QList<QPair<QString, QVariant>>, CompleterData::Type> &p_data )
 {
   m_data = p_data;
 }

 void CompleterData::setTitle( const QString &p_title )
 {
   m_title = p_title;
 }

 const QString &CompleterData::title() const
 {
   return m_title;
 }

 void CompleterData::setHeaders( const QStringList &p_headers )
 {
   m_headers = p_headers;
 }

 const QStringList &CompleterData::headers() const
 {
   return m_headers;
 }

CompleterData.h

class CompleterData
{
public:
  enum Type
  {
     Header,        
     SecondHeader,  
     Data,          
     LastUsed      
  };

  CompleterData() = default;

  QMap <QList<QPair<QString, QVariant>>, CompleterData::Type> data() const;
  void setData( const QMap < QList<QPair<QString, QVariant>>, CompleterData::Type> &p_data );
  void addData( const  QList<QPair<QString, QVariant>> &p_rowData, CompleterData::Type p_type );
  void setHeaders( const QStringList &p_headers );
  void setTitle( const QString &p_label );
  const QStringList &headers() const;
  const QString &title() const;

private:
  QMap <QList<QPair<QString, QVariant>>, CompleterData::Type> m_data;
  QString m_title;
  QStringList m_headers;
};
...