2

我的目标是为数据库创建一个胖客户端。基本上都是关于管理三个数据列表。

我想将我的应用程序分割成解耦层,因此使用 Qt 的模型/视图框架对我来说似乎很自然。

  • 我应该什么时候创建 QSql*Model 实例?

我需要能够多次连接/断开与数据库的连接(我有相应的菜单项)。我不满意删除一堆模型并在每次连接/断开时再次创建它们。

有没有替代方法?

  • 我应该在哪里创建 QSql*Model 实例?

我不认为 MainWindow 或任何其他与 GUI 相关的类应该包含这样的代码:

m_goodsModel->setRelation(1, QSqlRelation("Level", "LevelId", "Name"));

我想将 GUI 与数据结构分离。任何想法如何做到这一点?

  • 我应该何时何地将我的视图绑定到模型?

我需要以十几种方式表示我的三个列表。如果我每次连接/断开连接时都重新创建模型,我将需要再次将新创建的模型注入所有视图。

如果我只能这样做一次,那就太好了,但我不知道怎么做。

  • 讨厌的QSqlTableModel::select()方法怎么办?

这个让我发疯。与其他模型(例如QStringListModelQFileSystemModel等)相比,数据可以开箱即用,派生的模型QSqlTableModel在您手动调用它们的select()方法之前是无用的。在调用之前,模型是空的,因此使用该模型的视图;标题数据也没有填充,因此视图甚至不知道它必须呈现哪些列。

由于我无法避免select()调用,我想知道我应该把它放在哪里以便它适合?我不认为 MainWindow 或任何其他与 GUI 相关的类应该包含该代码。

  • 性能和稳健性

我不乐意在重新连接数据库时重新初始化所有内容。这样做需要很长时间(我的意思是在执行期间)。我还想避免在模型重新创建过程中发生崩溃,因为视图可能仍会引用它们。

没有其他方法可以只设置一次并优雅地处理重新连接吗?

4

1 回答 1

1

在我看来,所有这些问题的直接答案是将所有与数据库相关的操作包装在一个专用类中,并在 MainWindow/Dialog/whatever 中保存指向此类实例的指针。

一个可能的设计可能是这样的:

class DatabaseAccess : public QObject
{
       Q_OBJECT
    public:
       void connectToDatabase(const QString & hostname, const QString & db, const QString & user, const QString & password);
       void disconnectFromDatabse();

       QAbstractItemModel * getModelForX();
       QAbstractItemModel * getModelForY();

    private:
       QSqlTableModel * modelForX;
       QSqlRelationalTableModel * modelForY;
}

在这里,X 和 Y 只是应用程序中查询类型的占位符。

您可以在 getModelForX/Y 方法中创建模型connectToDatabase()并在需要新数据时调用。select()

据我所知,您不能继续使用具有不同数据库连接的相同模型实例,因为QSqlTableModel它的后代都绑定到一个QSqlDatabase实例。成功连接后,您需要刷新视图。

于 2010-08-19T20:32:13.880 回答