【问题标题】:Basic concept of Qt model/view and QTableViewQt模型/视图和QTableView的基本概念
【发布时间】:2013-03-20 13:00:43
【问题描述】:

我想创建一个软件来浏览一些数据库表并且用户将能够编辑这些表。在阅读了link 之后,我认为模型/视图是满足我需要的好方法。看看下面的模型:

知道了这一点,我有一些问题要确保我理解了这个概念。请告诉我我的方向是否正确:

  1. 我想我需要为我的每个表创建一个模型类? (子类化 QAbstractModel)。它看起来像这样:

    class citiesTableModel : public QAbstractItemModel
     {
         Q_OBJECT
     }
    
  2. citiesTableModel 构造函数将从表中获取数据 在数据库中?

    QAbstractItemModel *model = new citiesTableModel(); //model will contain 2 rows, New York and Seattle
    
  3. 我需要为每个不同的模型子类化 QTableView 吗?

    class citiesTableView : public QTableView{}
    
  4. Finnaly,我猜 view.setData 和 view.setModel 需要 重新实现? setModel 将遍历每个模型行以构建 QTableView 和 setData 将进行适当的查询以在 型号?

非常感谢。

【问题讨论】:

    标签: qt model-view-controller qtableview qabstractitemmodel


    【解决方案1】:

    基本上你有不同的选择:

    您的数据库是 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
    

    【讨论】:

      【解决方案2】:

      您可以为此使用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 本身进行修改,只能使用表单 (bellow tableview)。它会让事情变得更容易吗? Finnaly,你确定我不需要继承 QTableView 吗?如果我想将布尔值转换为复选框?谢谢
      • 是的,如果你有合适的 qt sql 插件,它可以与任何数据库一起使用。是的,可以通过表格编辑数据。要将布尔值显示为复选框,您应该使用delegate classes
      • 再次感谢您的回答。我不够清楚的东西。实际上,这是一个设计决定。我们想要什么:用户将无法编辑表格视图本身。用户必须先选择一行,然后相应地填写表格,然后用户将修改表格。
      • submitAll 是否应该是 QTableView 的成员,因为我找不到它?
      • bool QSqlTableModel::submitAll () [slot]
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-15
      • 1970-01-01
      • 2017-04-29
      • 1970-01-01
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多