我为 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
(功能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
在我看来,我看不出我的代码和他们的代码有什么不同。他们只是设置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;
};