Skip to main content
 首页 » 编程设计

python之如何从 SQL 模型中为连接到它的 QListView 选择行

2025年05月04日10exmyth

我正在 PyQt4 中尝试以下操作,使用 SQLAlchemy 作为 QListView 模型的后端。

我的第一个版本是这样的:

class Model(QAbstractListModel): 
     def __init__(self,  parent=None,  *args): 
        super(Model,  self).__init__(parent,  *args) 
 
     def data(self,  index,  role): 
        if not index.isValid(): 
            return None 
 
        if role == QtCore.Qt.DisplayRole: 
            d = sqlmodel.q.get(index.row()+1) 
            if d: 
                return d.data 
        return None 

问题是,一旦我开始删除行,id 就不再连续了。 所以我当前的解决方案如下所示:

class Model(QAbstractListModel): 
     def __init__(self,  parent=None,  *args): 
        super(Model,  self).__init__(parent,  *args) 
 
     def data(self,  index,  role): 
        if not index.isValid(): 
            return None 
 
        if role == QtCore.Qt.DisplayRole: 
            dives = Dive.q.all() 
            if index.row() >= len(dives) or index.row() < 0: 
                return None 
            return dives[index.row()].location 

但我想这样一来,我以后可能会在从数据库中选择正确的条目时遇到麻烦。

有什么优雅的方法可以做到这一点吗? 我的第一个想法是从数据库返回最大 id 作为 row_count,然后用虚假数据填充不存在的行并将它们隐藏在 View 中。由于应用程序最多必须处理大约 10k 的数据,而这已经非常不可能,我认为这可能是可行的。

请您参考如下方法:

将行 ID 存储在模型的列表中,并将其用作检索数据库行的索引。如果您想在模型 View 系统中实现排序,只需根据需要对列表进行排序即可。

如果您直接从数据库中删除一行,模型不会知道,因此它不会更新 View 。它们将显示陈旧的数据,并且当用户试图编辑不再存在于底层数据库中的行时,它们也可能会破坏事物,这可能会变得非常糟糕。每当您执行此操作以刷新所有 View 时,您都可以通过在模型上调用 reset() 来解决此问题。

class Model(QAbstractListModel): 
     def __init__(self,  parent=None,  *args): 
        super(Model,  self).__init__(parent,  *args) 
        self.id_list = [] 
 
     def data(self,  index,  role): 
        if not index.isValid(): 
            return None 
 
        row_id = self.id_list[index.row()] 
 
        if role == QtCore.Qt.DisplayRole: 
            # query database to retrieve the row with the given row_id