【问题标题】:QComboBox Array AccessQComboBox 数组访问
【发布时间】:2014-06-04 12:18:06
【问题描述】:

我希望能够访问我的 QComboBox 中的值,而不必使用 itemText 循环遍历内容。

for( auto i = 0u; i < myQComboBox->count(); i++ )
{
    result[i] = myQComboBox->itemText( i );
}

有没有办法可以访问 QComboBox 的底层 QList,这样我就可以使用 operator[] 甚至更好的迭代器和基于范围的循环?

【问题讨论】:

    标签: c++ arrays qt iterator qcombobox


    【解决方案1】:

    您似乎对语法感到困惑:您想用myQComboBox[i] 替换myQComboBox-&gt;itemText(i)。这很容易做到:

    // implementation
    class ModelAdapter {
      QPointer<QAbstractItemModel> m_model;
    public:
      explicit ModelAdapter(QComboBox & box) : m_model(box.model()) {}
      explicit ModelAdapter(QAbstractItemModel * model) : m_model(model) {}
      QVariant operator[](int i) { return m_model->index(i, 0); }
    };
    
    // point of use
    ModelAdapter model(myQComboBox);
    for( auto i = 0; i < myQComboBox->count(); i++ )
    {
        result[i] = model[i];
    }
    

    使用好的编译器,您可以执行以下操作并让它生成与直接使用combobox.model-&gt;index(i, 0) 相同的代码。我不明白这有什么意义,但是,嘿,有可能:)

    // implementation
    class Adapter {
      QAbstractItemModel* m_model;
    public:
      explicit Adapter(QComboBox & box) : m_model(box.model()) {}
      explicit Adapter(QAbstractItemModel * model) : m_model(model) {}
      QVariant operator[](int i) { return m_model->index(i, 0); }
    };
    
    // point of use
    for( auto i = 0; i < myQComboBox->count(); i++ )
    {
        result[i] = Adapter(myQComboBox)[i];
    }
    

    类似的适配器可以为您提供迭代器。

    【讨论】:

    • 这个想法似乎比我希望的解决方案更复杂。但是,如果我能让迭代器运行,我可以使用std::algorithm 将数据传入和传出QComboBox 但是,我似乎在ModelAdapter 类的迭代器版本中实现了迭代器,这需要一段时间做对。我是否使实施复杂化了?有没有一种简单的方法可以做到这一点?
    • @JonathanMee 等等,7 行解决方案太复杂了?这个类隐藏在某个地方的标题中。唯一的“参与”是您希望使用模型的块中的单行。我经常看到有人计算实现的大小而不是使用它所需的代码的大小,这让我无所适从。在需要语句的情况下,你不会比单个语句更小,所以事实上,这是尽可能小的。我已经展示了它的另一种变体。我稍后会添加迭代器。
    • 所以我决定使用int 来保持位置并将其用于迭代器。我继承自std::random_access_iterator_tag 并实现了它的operations。我是说那很费时间。如果有更好的方法,我很想听。
    • @JonathanMee 再次,实现完成一次。重要的是它使用起来有多容易——毕竟,如果你真的需要它,你会希望非常非常频繁地使用它。如果你只会使用它十几次或更少,你可能会浪费你的时间,甚至担心它。
    【解决方案2】:

    您可以使用组合框的模型检索项目数据。这是一个示例,我将如何做到这一点:

    QComboBox combo;
    combo.addItem("Item 1");
    
    QAbstractItemModel *model = combo.model();
    QModelIndex idx = model->index(0, 0); // Refers to the first item
    QString item = model->data(idx).toString(); // Returns 'Item 1'
    

    要访问组合框的第二个和更多项,只需更改 index() 函数调用中的行号:

    QModelIndex idx = model->index(0, 0);
                    the row number ^
    

    到目前为止,我还不知道有任何基于迭代器的组合框 API,但您可以使用 QAbstractItemModel 的所有优势。

    【讨论】:

    • 我承认我在使用QAbstractModel 方面的经验有限,但这似乎对我没有任何帮助,而不是打电话给myComboBox-&gt;itemText( i ) 现在我打电话给model-&gt;index( i, 0 )。有没有一种方法让我错过了 QAbstractItemModel 让我更接近使用基于范围的循环?
    • @JonathanMee,这两种方法是等效的,但是使用简单的for 循环有什么问题?否则我不知道你需要什么 API。
    • 我有一个面向 UI 的方法,它接受一个 std::vector,它填充一个 QComboBox,处理用户输入,然后从 QComboBox 填充一个 std::vector 并返回它。循环工作正常,但我在代码中的很多地方都这样做,并且能够使用迭代器可以让我直接在任何地方返回 std::vector,而不是临时创建它。
    猜你喜欢
    • 2014-12-05
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 2012-08-18
    • 2012-08-08
    • 2012-12-21
    相关资源
    最近更新 更多