首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QSortFilterProxyModel headerData

QSortFilterProxyModel headerData
EN

Stack Overflow用户
提问于 2021-07-07 21:11:02
回答 1查看 79关注 0票数 0

我有2个QTableViews连接到2个QSortFilterProxyModels,它们只连接到1个源模型(QSqlRelationalTableModel)。

在对任何代理模型进行排序或过滤时,它会反映在相应的表视图中。但是当我修改其中一个代理模型的头部数据(装饰角色)时,它出现在两个表视图上。

我的问题是,头数据是直接应用于源模型还是仅应用于代理?

我使用它创建了一个sqlite示例数据库:

代码语言:javascript
复制
conn = sqlite3.connect('customers.db')
c = conn.cursor()
c.execute("PRAGMA foreign_keys=on;")

c.execute("""CREATE TABLE IF NOT EXISTS provinces (
        ProvinceId TEXT PRIMARY KEY, 
        Name TEXT NOT NULL
        )""")

c.execute("""CREATE TABLE IF NOT EXISTS customers (
        CustomerId TEXT PRIMARY KEY, 
        Name TEXT NOT NULL,
        ProvinceId TEXT,
        FOREIGN KEY (ProvinceId) REFERENCES provinces (ProvinceId) 
                ON UPDATE CASCADE
                ON DELETE RESTRICT
        )""")

c.execute("INSERT INTO provinces VALUES ('N', 'Northern')")
c.execute("INSERT INTO provinces VALUES ('E', 'Eastern')")
c.execute("INSERT INTO provinces VALUES ('W', 'Western')")
c.execute("INSERT INTO provinces VALUES ('S', 'Southern')")
c.execute("INSERT INTO provinces VALUES ('C', 'Central')")

c.execute("INSERT INTO customers VALUES ('1', 'customer1', 'N')")
c.execute("INSERT INTO customers VALUES ('2', 'customer2', 'E')")
c.execute("INSERT INTO customers VALUES ('3', 'customer3', 'W')")
c.execute("INSERT INTO customers VALUES ('4', 'customer4', 'S')")
c.execute("INSERT INTO customers VALUES ('5', 'customer5', 'C')")

conn.commit()
conn.close()

这是在为代理模型应用装饰时显示问题的窗口:

代码语言:javascript
复制
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("customers.db")
        self.db.open()

        self.model = QSqlRelationalTableModel(self, self.db)
        self.model.setTable("customers")
        self.model.select()

        self.proxy1 = QSortFilterProxyModel()
        self.proxy1.setSourceModel(self.model)

        self.proxy2 = QSortFilterProxyModel()
        self.proxy2.setSourceModel(self.model)

        hBox = QHBoxLayout()

        self.tblView1 = QTableView()
        self.tblView1.setModel(self.proxy1)

        self.tblView2 = QTableView()
        self.tblView2.setModel(self.proxy2)

        hBox.addWidget(self.tblView1)
        hBox.addWidget(self.tblView2)

        icon = QIcon(QPixmap("Resources/icon.png"))

        self.proxy1.setHeaderData(
            1, Qt.Orientation.Horizontal, icon, Qt.ItemDataRole.DecorationRole)

        widget = QWidget()
        widget.setLayout(hBox)
        self.setLayout(hBox)
        self.show()


def main():
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec_())


if __name__ == '__main__':
    main()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-08 03:24:16

之所以会出现这个问题,是因为代理模型的setHeaderData方法调用了源模型的setHeaderData,也就是说,它等同于调用源模型的方法,导致它也传播到其他代理模型。一种可能的解决方案是覆盖代理模型的headerData方法,以便它只在该代理模型中返回所需的值。

代码语言:javascript
复制
import sys

from PyQt5.QtCore import QSortFilterProxyModel, Qt
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QTableView, QApplication
from PyQt5.QtSql import QSqlDatabase, QSqlRelationalTableModel


class SortFilterProxyModel(QSortFilterProxyModel):
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        if (
            section == 1
            and orientation == Qt.Horizontal
            and role == Qt.ItemDataRole.DecorationRole
        ):
            return QIcon(QPixmap("Resources/icon.png"))
        return super().headerData(section, orientation, role)


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName("customers.db")
        self.db.open()

        self.model = QSqlRelationalTableModel(self, self.db)
        self.model.setTable("customers")
        self.model.select()

        self.proxy1 = SortFilterProxyModel()
        self.proxy1.setSourceModel(self.model)

        self.proxy2 = QSortFilterProxyModel()
        self.proxy2.setSourceModel(self.model)

        hBox = QHBoxLayout(self)

        self.tblView1 = QTableView()
        self.tblView1.setModel(self.proxy1)

        self.tblView2 = QTableView()
        self.tblView2.setModel(self.proxy2)

        hBox.addWidget(self.tblView1)
        hBox.addWidget(self.tblView2)


def main():
    App = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(App.exec_())


if __name__ == "__main__":
    main()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68286708

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档