QSortFilterProxyModel скрывает QWidget

У меня есть QStandardItemModel, в котором хранятся данные. В одну из колонок я хотел бы добавить несколько QWidget (кликабельные картинки). Однако после добавления QSortFilterProxyModel для очистки/фильтрации QSortFilterProxyModel скрывает мои желаемые QWidget.

Я искал в Интернете, но не смог найти, как сохранить QWidget и QSortFilterProxyModel одновременно. Было бы очень признательно, если бы кто-то мог направить меня по этому вопросу. Спасибо.

Минимальный пример использования QPushButton в качестве желаемого QWidget:

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class Buttons(QWidget):
    def __init__(self):
        super().__init__()
        layout = QHBoxLayout(self)
        layout.addWidget(QPushButton('btn1'))
        layout.addWidget(QPushButton('btn2'))
        self.setLayout(layout)

class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        tab = QTableView()
        sti = QStandardItemModel()
        if True:    # This shows the buttons in a cell
            tab.setModel(sti)
        else:       # This does not show the buttons
            proxy = QSortFilterProxyModel()
            proxy.setSourceModel(sti)
            tab.setModel(proxy)
        sti.appendRow([QStandardItem(str(i)) for i in range(5)])
        tab.setIndexWidget(sti.index(0, 0), QPushButton("hi"))
        sti.appendRow([])
        tab.setIndexWidget(sti.index(1, 2), Buttons())
        self.setCentralWidget(tab)

app = QApplication([])
window = MainWindow()
window.resize(800, 600)
window.show()
app.exec_()

person Boba S.    schedule 21.11.2020    source источник


Ответы (1)


Виджеты, добавленные с помощью seyIndexWidget, добавляются в представление, а не в модель. Индекс, переданный функции, является только ссылкой, которую представление использует, чтобы узнать, где будут размещены эти виджеты, и эта ссылка должна быть ссылкой на фактическую модель, используемую в представлении.

Если вы используете прокси-модель в представлении, вы должны указать индекс прокси, а не источник.

tab.setIndexWidget(proxy.index(0, 0), QPushButton("hi"))

Или лучше:

tab.setIndexWidget(tab.model().index(0, 0), QPushButton("hi"))

Обратите внимание, что это, очевидно, означает, что вы можете столкнуться с некоторой несогласованностью всякий раз, когда модель изменяется из-за фильтрации или сортировки, и это еще одна причина, по которой индексные виджеты следует использовать только для статических и простых моделей, а делегаты являются предпочтительным решением.

person musicamante    schedule 21.11.2020