Qt: QSqlTableModel + QTableView 与 PostgreSQL 同步

发布于 2024-12-23 14:49:17 字数 1113 浏览 2 评论 0原文

我正在编写一个数据库访问应用程序来存储一些数据,并想问一些有关模型/视图架构的问题。

(使用:Qt 4.7.4,自己构建;PostgreSQL 9.0;目标:WinXP、Win7(32/64 位)) 首先让我解释一下我想要实现的目标以及我目前的处境。

我有两个页面(插入 QStackedWidget 中的子类 QWidget),其中 QTableView 绑定到模型。每个视图都绑定到 PostgreSQL 服务器中的一个表。您可以添加/编辑/删除/排序/过滤项目。 每个页面只能由一种类型的用户看到,我们将角色称为 Role1 和 Role2。

与模型相关的所有内容的提交策略都是OnManualSubmit。

  1. (事务隔离级别=可序列化。)当两个用户想要编辑(例如)同一行时,我想做一个“SELECT ... FOR UPDATE”查询 - 以确保当有人编辑某些内容时,他会将他的更改与较新的更改合并(如果有的话,就像在 SVN 中一样)。但我只看到QSqlTableModel 的submitAll() 方法。 也许捕获 beforeUpdate()、beforeDelete()、beforeInsert() 信号并手动执行“SELECT ... FOR UPDATE”是一种选择。 我认为的另一种方法是子类化 QSqlTableModel。实现此目的的干净且良好的方法是什么?

  2. 我想定期更新每个页面的QSqlTableView(最多看到一个页面,Role1用户只能访问Page1,Role2 => Page2也是如此)。 我想到的第一件事是使用 QTimer 并手动调用 QSqlTableModel 的 select() ,但是...不确定这是否很酷。

  3. 我也想定期检查与数据库的连接是否正常,但我认为 QTimer + QSqlDatabase::isOpen() 就可以了。

  4. 现在,这两个表具有相同的主键,并且某些列是相同的。我希望当具有 Role1 的用户更改 Table1 中的行时,自动更改 Table2 的相应列,反之亦然。我应该在 Postgres 中创建触发器吗?

顺便说一句,数据库很小 - 两个表中的每一个大约有 3-4000 行,大约 10 列(主要是 varchar,1 个文本和 2 个日期列)。

感谢您的阅读,新年快乐! :)

I'm writing a database access app for storing some data and want to ask a few questions about the model/view architecture.

(Using: Qt 4.7.4, own build; PostgreSQL 9.0; Targets: WinXP, Win7 (32/64 bit))
Let me first explain what I am trying to achieve and where I am currently.

I have two pages (subclassed QWidgets inserted in a QStackedWidget) with a QTableView bound to a model. Each view is bound to a table in the PostgreSQL server. You can add/edit/delete/sort/filter items.
Each page can be seen by only one type of users, lets call the roles Role1 and Role2.

The submit strategies of everything connected to the model are OnManualSubmit.

  1. (Transaction isolation level = Serializable.) When two users want to edit(for example) the same row, I want to do a "SELECT ... FOR UPDATE" query - to make sure that when someone edits something, he will merge his changes with newer ones (if any, just like in SVN for example). But I see only a submitAll() method the QSqlTableModel.
    Maybe catching the signals beforeUpdate(), beforeDelete(), beforeInsert() and performing manually "SELECT ... FOR UPDATE" is one option.
    The other way I think is to subclass QSqlTableModel. What is the clean and nice way to achieve this?

  2. I want to periodically update the QSqlTableView for each of the pages (one page is seen at most, Role1 users have access only to Page1 and the same for Role2 => Page2).
    The first thing that came to my mind is to use a QTimer and manually call select() of the QSqlTableModel, but... not sure if this is the cool way.

  3. I also want to periodically check if the connection to the database is ok, but I think that a QTimer + QSqlDatabase::isOpen () will do.

  4. Now, the 2 tables have the same primary keys and some columns are the same. I want when a user with Role1 changes a row in Table1 to automatically change corresponding columns of Table2 and vice versa. Should I create a trigger in Postgres?

BTW, the database is small - each of the two tables is around 3-4000 rows with ~10 columns (varchars mostly, 1 text and 2 date colunms).

Thanks for reading and Happy New Year! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

饮惑 2024-12-30 14:49:17

我认为您应该考虑执行以下操作:

我不是使用 QSqlTableModel 作为模型,而是将自己的模型实现为 QAbstractTableModel 的子类。这将使您能够更好地控制数据操作方面的操作。

这需要的一件事是,对于表中的某些字段,您需要实现 QAbstractItemDelegate 的子类,该子类将允许修改表中的数据,因为我相当确定您不想允许用户更新表中的任何字段,例如主键可能必须单独保留。

对于问题 2,我建议为每一行实现一个名为 transaction_counter 的字段,这样您就不必 select 表中的每一行,只需更新 transaction_counter 的行即可 将在每一行更新时更新,并且新行将在新行插入时插入。需要做的一件事是,整个桌子上的计数器是唯一的。例如,如果表的初始状态为:row1 的 counter = 0,row2 的 counter = 0。如果 row1 已更新,则将 counter 设置为 1。当 row1 再次更新时,其上的 counter 将设置为 2。当 row2 现在更新时,其上的 counter 设置为 3 等。您现在当然可以使用 QTimer< 进行数据刷新/code> 这对于检查数据来说更加有利,因为一个用户可能会与具有相同角色的另一用户更新同一个表。

对于问题 3。我看不出有什么理由不使用自定义模型,特别是如果您决定将数据与模型分离,则可以将数据与显示分开操作。 Data->Model->View->Controller 实现的排序。只要您有针对代表的反馈机制,每一项都可以单独维护。

对于问题 4。答案是肯定的,或者您可以在应用程序中实现触发器。

希望这有帮助。祝你新年快乐!

I think you should consider doing something of the following:

Instead of using QSqlTableModel as a model I'd implement my own model as a subclass of QAbstractTableModel. This will allow you a lot of control over what you can do in terms of data manipulation.

One thing that this will require is for certain fields in the table you would need to implement subclass of QAbstractItemDelegate that will allow for modification of data in the table as I am fairly sure you don't want to allow users updating any field in the table as for example primary key is likely have to be left alone.

For question 2 I would suggest implementing a field called transaction_counter for every row so you don't have to select every row in the table just the updated ones the transaction_counter will be updated on every row update and the new one will be inserted on the new row insert. One thing that will be required is that the counter is unique across the table. For example if initial state of the table is: row1 has counter = 0 and row2 has counter = 0. If row1 is updated counter set to 1. When row1 is then updated again counter on it is set to 2. When row2 is now updated counter on it is set to 3, etc. You can certainly do the data refreshes now using QTimer and this will be much more advantageous to for example checking the data as one user may be updating the same table as another user with the same Role.

For Question 3. I don't see any reason why not custom models and especially if you decide to separate data from the model you can manipulate data separately from it's display. Sort of Data->Model->View->Controller implementation. Each one can be maintained separately as long as you have a feedback mechanism for your delegates.

For Question 4. The answer is sure or you can implement the trigger in your application.

Hope this helps. Have a great New Year!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文