0

我为 Combobox 创建了一个完成器。

我的组合框.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

完成者视图.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(功能parentindex对我的情况并不重要)

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

在我看来,我看不出我的代码和他们的代码有什么不同。他们只是设置setCompleter(),没有什么特别的,不需要信号/插槽。但我不知道为什么我的代码不起作用。当我在组合框中键入时,什么也没有出现。你能在我的代码中展示我的一些不好的东西吗?

更新

完成者数据.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;
 }

完成者数据.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;
};
4

0 回答 0