gpt4 book ai didi

c++ - 带有自定义模型的 QComboBox

转载 作者:行者123 更新时间:2023-11-30 01:11:58 25 4
gpt4 key购买 nike

我有一个自定义存储,我想实现 ListModel 以使用 QComboBox 显示它。为简单起见,我们假设我们有一个 int 列表作为模型的数据,所以这是我对模型和测试程序的实现:

#include <QApplication> 
#include <QDebug>
#include <QAbstractListModel>
#include <QComboBox>
#include <QHBoxLayout>
#include <QPushButton>

QList<int> list;

class MyModel : public QAbstractListModel
{
public:
MyModel( QWidget* parent ):
QAbstractListModel( parent )
{}
~MyModel()
{
qDebug() << __FUNCTION__;
}

QVariant data(const QModelIndex &index, int role) const
{
if ( !index.isValid() )
return QVariant();

if ( ( role == Qt::DisplayRole ) && ( index.row() < list.size() ) )
return QString::number( list.at( index.row() ) );

return QVariant();
}

int rowCount(const QModelIndex &parent) const
{
Q_UNUSED( parent )
return list.size();
}
};

int main ( int argc, char* argv[] )
{
QApplication app ( argc, argv );

QWidget w;
QHBoxLayout* l = new QHBoxLayout();

QComboBox* c = new QComboBox( &w );
c->setModel( new MyModel( c ) );
l->addWidget( c );

QPushButton* b = new QPushButton("+");
QObject::connect( b, &QPushButton::clicked, [](){
list.push_back( qrand() );
qDebug() << list;
} );
l->addWidget( b );

b = new QPushButton("-");
QObject::connect( b, &QPushButton::clicked, [](){
if ( !list.isEmpty() )
list.pop_back();
qDebug() << list;
} );
l->addWidget( b );
w.setLayout( l );
w.show();

return app.exec ();
}

如果我只点击一次按钮添加然后检查列表,它看起来没问题,但是当我再次点击它时,QComboBox 只显示第一个值和一个空行;继续添加新元素对 QComboBox 没有影响。如果我多次点击按钮添加,那么我可以在ComboBox中看到正确的列表。

我不明白发生了什么,我做错了什么。

我在 Windows 7 上使用 Qt5.5.1VS2013 x32

最佳答案

您的模型需要在数据实际发生变化时发出正确的信号。这通常是通过调用 protected 函数 beginInsertRows、endInsertRows 等来完成的...因为这些是 protected ,所以它们只能由 MyModel 中的成员函数调用。此外,为了良好的实践,实际数据(您的 list)应仅由 MyModel 修改。

首先,使 list 成为 MyModel 的私有(private)成员。不应从外部访问它。

private:
QList<int> list;

在 MyModel 中添加两个用于管理 list 的公共(public)函数:

public:
void push(int value)
{
beginInsertRows(list.size(), list.size());
list.push_back(value);
endInsertRows();
}

void pop()
{
if(list.size()>0)
{
beginRemoveRows(list.size()-1, list.size()-1);
list.pop_back();
endRemoveRows();
}
}

在 main 中,在你的模型上保留一个指针

MyModel * m = new MyModel(c);

然后在 main() 中使用这些函数,而不是直接附加到 list 中。

QObject::connect( b, &QPushButton::clicked, [m](){
m->push(qrand());
} );

QObject::connect( b, &QPushButton::clicked, [m](){
m->pop();
} );

等等

替代的,更Qt的方式

pushpop声明为slots:

public slots:
void push()
{
beginInsertRows(list.size(), list.size());
list.push_back(qrand());
endInsertRows();
}

void pop()
{
if(list.size()>0)
{
beginRemoveRows(list.size()-1, list.size()-1);
list.pop_back();
endRemoveRows();
}
}

并将它们直接连接到 main 中的按钮:

QObject::connect( b, &QPushButton::clicked, m, &MyModel::push);

//...

QObject::connect( b, &QPushButton::clicked, m, &MyModel::pop);

关于c++ - 带有自定义模型的 QComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34997685/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com