Important: Please read the Qt Code of Conduct -

QListView / QListWidget with custom data

  • Hello all,

    I am currently adding a GUI to a larger project. So far I used the QGraphicsScene to render a large network and I must say that I am really impressed with it:)

    However, I have a problem with the QListWidget / QListView: I want to display data obtained from another part of the application. Each entry basically consists of a pointer to an object. I want to have an entry in the widget for each pointer with a name which I derive from the data and present as a QString.
    Otherwise, I only need the pointers. I want to be able to select one or multiple items by passing a list of pointers to the widget and I want to notify other widgets of a changed selection, where the other widgets once again only need the pointers which are currently selected. What is the most efficient (with respect to code size and run/compile time) way to implement this using either a QListWidget or a QListView (I don't really care which)?

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Since you already have a list of object, you could implement a QAbstractItemList model on top of your data and thus use a QListView. You can re-use the model on your other widgets needing to access the data.

    Hope it helps

  • I agree with SGaist. Create a QAbstractItemModel adaptor on your underlying data store. If all you need is a list, then by all means use a QAbstractListModel as its base, but I would stick with advertising the API as exposing a QAbstractItemModel. That way, the fact that you're using a list remains an implementation detail, easy to change when needed.

    Note that while it is possible to use QAbstractItemModel's interface for other purposes than model/view, I really recommend against doing that. The API is too generic and too cluncky to be nice to use in other contexts. Instead, provide specialized API on your actual data store.

  • Well, I realize now that my question might have been a little vague. The situation is the following: Lets assume I have the following data model:

    int data[] = {0, 1, 2, 3};

    typedef int Data;

    class Handler
    Data* by_index(int i) const
    return data + i;

    int num_elems() const
    return 4;
    } my_handler;

    QString to_string(Data *data)
    return QString("Data item %1").arg(*data);

    Now I want to display the data in a QListView. For each item I only want to display the QString obtained from to_string and no other formatting. I would also like to have a signal dataChanged(QList<Data*> currently_selected_data) and a function select_data(QList<Data*> to_be_selected)
    Could you give me some more concrete advice on how to achieve this functionality?

  • Lifetime Qt Champion

    Since it's a list, return num_elems for rowCount() and use to_string when data() is called for DisplayRole

    Are you sure you need these two signals ? Item views already provide a selection model

  • Well, I want other components to react to the changed selection. But the normal signal in QAbstractItemView works with these crazy QItemSelection objects which are QLists of QItemSelectionRanges and so on. The problem is that I want a map from the selection as stored in Qt to my data.
    I don't know or care about the way the QItemView stores the selection internally, but I need to map the selection to my data objects.

  • Lifetime Qt Champion

    Well, these signals gives you QModelIndexes that you can use to get your data through the model so you don't have to worry about handling the selection.

    Isn't that what you need ?

  • Well, what is the best way to get a data entries from a QModelIndex? There is an internal pointer (a void*). Can I use that pointer or can I somehow get a map from the QModelIndexes to my Data entries without having to define that map myself?

  • Lifetime Qt Champion

    That's where Andre's specialized API suggestion kicks in, you can provide a function like

    @Data dataForIndex(const QModelIndex &index) const
    if (!index.isValid())
    return Data();
    return _handler.by_index(index.row());

    You can do something similar for a range of indexes

Log in to reply