【问题标题】:setData is very slowsetData 很慢
【发布时间】:2015-06-22 14:42:42
【问题描述】:

我正在尝试从我开发的程序中优化一种方法。

基本上,它是一个显示信息的 GUI(我使用 PyQt 库)。信息存储在 sqlite 数据库中。我使用 QSqlTableModel 和 QTableview 来显示这些信息。这是一个很常见的组合。

数据库中的一个字段是一个布尔值,称为“new”。我要优化的方法的目的是将此布尔值设置为 0。

方法如下:

def markOneRead(self, element):

    """Slot to mark an article read"""

    print("\n")
    print("start markoneread")
    start_time = datetime.datetime.now()

    # Get the QTableView object (I have several)
    table = self.liste_tables_in_tabs[self.onglets.currentIndex()]

    # Save the current selected line
    line = table.selectionModel().currentIndex().row()

    print("before bdd change")
    elapsed_time = datetime.datetime.now() - start_time
    print(elapsed_time)

    # Change the data in the model
    # The 12th column is the field "new". I write 0
    # !!!!! Very long action
    table.model().setData(table.model().index(line, 12), 0)

    print("before searchbutton")
    elapsed_time = datetime.datetime.now() - start_time

输出是这样的:

before bdd change
0:00:00.000141
before searchbutton
0:00:03.064438

所以基本上,这一行:

table.model().setData(table.model().index(line, 12), 0)

执行需要 3 秒。那很长,我只是在更新数据库中的一个项目,它不应该那么长。我的数据库有 25000 个项目,但我认为它不会改变什么。

编辑: 也许是因为模型立即执行更改,并尝试重新加载所有数据?

你知道如何解决这个问题吗?

编辑 2:

其实问题出在数据的重载上。如果我改变模型的editStrategy:

model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)

现在不再需要 3 秒,但视图没有更新,new 仍然设置为 1,在调用方法之后。

所以我想知道是否有办法在模型更改后“重新加载”一个项目、一个索引?

【问题讨论】:

  • 在数据库上执行更新语句更新项目需要多长时间?

标签: python pyqt qtableview qsqltablemodel


【解决方案1】:

也许这会有所帮助:

与:

index = table.model().index(line, 12)
table.model().dataChanged.emit(index,index)

或:

table.model().dataChanged.emit(table.model().index(line, 12),table.model().index(line, 12))

您可以定义受更改影响的项目 见documentation

通过table.model().dataChanged-signal,table.model.setData() 之后的自动更新或重绘应限制在由代表左上角和右下角的两个索引定义的区域内。如果两个索引相同,则只有一项受到影响。

【讨论】:

  • 我想我不明白。您基本上制作了包含“新”布尔值的索引的副本,然后在其上发出信号?
  • @Rififi:他发出dataChanged 信号,范围为单个单元格,告诉Qt 只刷新这个单元格(而不是整个表格)。
  • 最后一个问题:如果不执行重绘我该怎么办?我该如何强制它?
  • 找到了解决方案。对于未来的我:table.viewport().update()
  • 好奇:我想,dataChanged-signal 会启动视图的更新。使用 table.update(index) 你只能更新一个单元格。
【解决方案2】:

QSqlTableModel 非常方便,但它并不神奇。我的猜测是执行更新语句需要大部分时间。尝试手动更新几行,看看会持续多久。

如果这也很慢,那么您可能需要在表上建立一个索引,以便 sqlite 可以更快地定位行。

【讨论】:

  • 实际上不,更新数据库中的项目非常快。但是,重新加载数据非常慢。因为我没有告诉你的是我修改了模型的默认行为,一次加载所有数据(对于排序等更实用)。所以每次对数据库进行更改时,我都必须重新加载所有数据库。 @a_manthey_67 的解决方案很棒,因为我只更新了视图中的一项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-22
  • 2011-03-08
  • 2013-02-23
  • 2015-12-24
  • 2020-10-23
  • 1970-01-01
相关资源
最近更新 更多