سؤال

I want to create a software that will browse some database tables and users will be able to edit these tables. Following my reading of this link, I tought that model/view was a good approach for what I need. Look at the following mockup : enter image description here

Knowing this, I have questions to be sure that I understand the concept. Please, tell my if I am in the good direction :

  1. I guess I need to create a model class for each of my tables? (subclassing QAbstractModel). It will look like this :

    class citiesTableModel : public QAbstractItemModel
     {
         Q_OBJECT
     }
    
  2. citiesTableModel constructor will fetch data from the table in the database?

    QAbstractItemModel *model = new citiesTableModel(); //model will contain 2 rows, New York and Seattle
    
  3. Do I need to subclass QTableView for every different model?

    class citiesTableView : public QTableView{}
    
  4. Finnaly, I guess that view.setData and view.setModel need to be reimplemented? setModel will loop over each model rows to build the QTableView, and setData will do proper query to add new data in the model?

Thank you very much.

هل كانت مفيدة؟

المحلول 2

You can use QSqlTableModel for this.

As the doc says, it can be used quite easy:

QSqlTableModel *model = new QSqlTableModel(parentObject, database);
model->setTable("employee");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();
model->setHeaderData(0, Qt::Horizontal, tr("Name"));
model->setHeaderData(1, Qt::Horizontal, tr("Salary"));

QTableView *view = new QTableView;
view->setModel(model);
view->hideColumn(0); // don't show the ID
view->show();

I guess I need to create a model class for each of my tables?

Yes, one model represents one sql table.

citiesTableModel constructor will fetch data from the table in the database?

QSqlTableModel will do it for you:

QSqlTableModel *model = new QSqlTableModel(parentObject, database);
model->setTable("employee");
model->select();

Do I need to subclass QTableView for every different model?

No, you don't. A single QTableview can display any model you set using setModel.

Finnaly, I guess that view.setData and view.setModel need to be reimplemented? setModel will loop over each model rows to build the QTableView, and setData will do proper query to add new data in the model?

Depending on the edit strategy you set using setEditStrategy, the changes will be commited as your are editing table cells, or after you submit them using submitAll.

Also, you may want to take a look at the QDataWidgetMapper. It can map your model data to different widgets and track the changes you are doing editing those widgets.

نصائح أخرى

Basically you have different options:

Either you database is a SQL database. You can use a subclass QSqlTableModel. Otherwise if you want to create your model from scratch you do your own model but I don't see the point. You also have QTableModel with an example.

You don't need to create a model for each of your table, because it is always a tablemodel. The model mostly defines how you can add and remove rows with your specific data.

Concerning the view, you will have to inherit QTableView to add a custom behavior for you rows and cols, such as drag events for instance.

The only element of customization that you need is a delegate for your view or just for a column. It will basically convert a boolean value in your model into a checkbox.

I suggest you look at SpinBox delegate for more precision.

Hope this helps.

Edit:

In the case of a PostgreSQL you can add it in a QsqlDatabase:

 QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
 db.setHostName("acidalia");
 db.setDatabaseName("customdb");
 db.setUserName("mojito");
 db.setPassword("J0a1m8");
 bool ok = db.open();

Then pass the db to the QSqlTableModel. If you need more relational operation, such as fetching fields from a foreign key, you can use:

QSqlRelationalTableModel
QSqlRelationalDelegate
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top