Qt模型/视图和QTableView的基本概念

3
我希望创建一个软件,能够浏览一些数据库表格,用户可以编辑这些表格。阅读了链接后,我认为模型/视图是我需要的好方法。请看下面的模拟图: enter image description here 了解这些后,我有问题想确保我理解这个概念。请告诉我是否正确:
  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?
非常感谢。
2个回答

3

基本上你有不同的选择:

要么你的数据库是SQL数据库。你可以使用一个子类 QSqlTableModel。 否则,如果你想从头开始创建你自己的模型,你可以创建自己的模型,但我不认为这有什么意义。你也可以使用 QTableModel 并查看示例。

你不需要为每个表格创建一个模型,因为它始终是一个表格模型。该模型主要定义了如何添加和删除具有特定数据的行。

关于视图,你将需要继承 QTableView 来为你的行和列添加自定义行为,例如拖动事件。

你唯一需要自定义的元素是你视图或者只是一个列的代理。它基本上将模型中的布尔值转换为复选框。

我建议你查看 SpinBox delegate 获取更多精确信息。

希望这可以帮助你。

编辑:

在使用PostgreSQL时,您可以将其添加到QsqlDatabase中:
 QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
 db.setHostName("acidalia");
 db.setDatabaseName("customdb");
 db.setUserName("mojito");
 db.setPassword("J0a1m8");
 bool ok = db.open();

然后将db传递给QSqlTableModel。如果您需要更多的关系操作,例如从外键获取字段,则可以使用:

QSqlRelationalTableModel
QSqlRelationalDelegate

1
你可以使用 QSqlTableModel来做到这一点。
正如文档所说,它可以很容易地使用:
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();

我猜我需要为每个表创建一个模型类?

是的,一个模型代表一个SQL表。

citiesTableModel构造函数将从数据库中获取表中的数据吗?

QSqlTableModel将为您完成:

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

我需要为每个不同的模型创建一个子类 QTableView 吗?

不需要,单个 QTableview 可以使用 setModel 设置任何模型。

最后,我猜 view.setData 和 view.setModel 需要重新实现?setModel 将循环遍历每个模型行以构建 QTableView,并且 setData 将执行适当的查询以在模型中添加新数据?

根据您使用 setEditStrategy 设置的编辑策略,更改将在您编辑表格单元格时提交,或在使用 submitAll 提交它们之后进行提交。

此外,您可能还想查看 QDataWidgetMapper。它可以将模型数据映射到不同的小部件并跟踪您正在编辑这些小部件的更改。


谢谢您的回答。实际上看起来比我想象的要简单一些。问题:我们的数据库是PostgreSQL。您知道QSqlTableModel是否适用于此数据库吗?另外,对于编辑策略,它实际上不可能通过tableview本身进行修改,只能通过表格视图下方的表单进行修改。这会让事情变得更加容易吗?最后,您确定我不需要子类化QTableView吗?如果我想将布尔值转换为复选框?谢谢。 - peterphonic
1
是的,如果您有适当的qt sql插件,它可以与任何数据库一起使用。是的,通过表格编辑数据是可行的。要将布尔值显示为复选框,您应该使用委托类 - hank
谢谢您的回答。有一些我没有表述清楚的地方。实际上,这是一个设计决策。我们想要的是:用户将无法编辑表格视图本身。用户必须先选择一行,然后表单将相应地填充,用户将修改表单。 - peterphonic
submitAll 应该是 QTableView 的成员吗?因为我找不到它。 - Paul-Sebastian Manole
bool QSqlTableModel::submitAll () [slot] - hank

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接