Important: Please read the Qt Code of Conduct -

QSqlQueryModel, trees and more

  • I will examplify the problem using the following scenario:

    1. A database that contains:
      • manufacturer: id, description
      • model: id, manufacturerId, description
      • car: id, modelId, description

    So we have a tree-like structure in the db:


    • manufacturer
      • model
        • car

    My target is to make every path in the tree (here the paths are guaranteed to be three) to be listed in a QComboBox.
    So the final UI will be:

    "Manufacturer:" QComboBox
    "Model:" QComboBox
    "Car:" QComboBox

    So what I want is a tree view but displayed as a form with three rows each of which contains a combo box that contains path from the tree.

    How I am currently trying to solve this:

    1. Subclassed QSqlQueryModel and set its query to:
      "SELECT "
      ", "
      "manufacturers.description, "
      ", "
      "models.description, "
      ", "
      "cars.description "
      "FROM "
      "cars "
      "INNER JOIN models "
      "ON cars.modelId = "
      "INNER JOIN manufacturers "
      "ON models.manufacturerId = "
      "ORDER BY "
      "manufacturers.description, "
      "models.description, "

    In the model I override the data() member function and the columnCount() one, so that I have three model columns:

    and for each column I have two roles:
    -> Qt::DisplayRole - returns the description,
    -> RoleId = Qt::UserRole + 1 - the id of the given entity

    So, at this point I have a tabular model of my tree-like data.

    1. Convert the QSqlQueryModel subclass to tree model:
      "This thread": recommends using QAbstractProxyModel and implement the:
      -> mapToSource
      -> mapFromSource
      member functions.

    2. Make each QComboBox use the same instance of the tree model, but making it use different column from it.
      TreeModel* const treeModel = new TreeModel( this ); // the QAbstractProxyModel subclass

    manufacturerComboBox.setModel( treeModel );
    manufacturerComboBox.setModelColumn( 0 );

    modelComboBox.setModel( treeModel );
    modelComboBox.setModelColumn( 1 );

    carComboBox.setModel( treeModel );
    carComboBox.setModelColumn( 2 );

    I am also thinking of using the QDataWidgetMapper class if using a given column for a tree-view doesn't work.

    So my question is: is this the right direction e.g. create a QAbstractProxyModel, and if so how should I implement the mapToSource and mapFromSource? Do I need to implement the parent() member function?

Log in to reply