Как правильно управлять активными виджетами, не теряя их фокус или запоминать фокус в переменной - PullRequest
1 голос
/ 26 октября 2019

У меня есть 4 виджета QListView с моделями (не подходит для использования QListView или QTableView). И мне нужно удалить выбранный элемент из модели и просмотра. И мне нужна одна кнопка, связанная с функцией удаления. Таким образом, вы нажимаете кнопку, и последний выбранный элемент исчезает. Но затем вы выбираете элемент в одном списке, он остается выбранным, поэтому, если я нажимаю кнопку, выбранные элементы в 4 QListView исчезают. Отменить выбор элементов автоматически не вариант, потому что у меня есть одна функция, которая не будет работать. Если я пытаюсь использовать .hasFocus (): после нажатия кнопки, кнопка получает фокус, поэтому ничего не происходит. Я могу добавить еще одну кнопку, чтобы отменить выбор по желанию или использовать ярлыки, но для меня это немного неуклюже.

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

1 Ответ

2 голосов
/ 26 октября 2019

Вы должны отслеживать виджеты, которые получают фокус, используя сигнал focusChanged от QApplication и проверять, является ли он одним из QListView.

from PySide2 import QtCore, QtGui, QtWidgets


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        button = QtWidgets.QPushButton("Delete")
        button.clicked.connect(self.on_clicked)

        lay = QtWidgets.QHBoxLayout()

        self.listviews = []
        # create QListView
        for i in range(4):
            lv = QtWidgets.QListView()
            model = QtGui.QStandardItemModel()
            lv.setModel(model)
            lay.addWidget(lv)
            self.listviews.append(lv)
            for j in range(10):
                it = QtGui.QStandardItem("{}-{}".format(i, j))
                model.appendRow(it)

        vlay = QtWidgets.QVBoxLayout(self)
        vlay.addWidget(button)
        vlay.addLayout(lay)

        self._last_listview = None

        QtWidgets.qApp.focusChanged.connect(self.on_focusChanged)

    @QtCore.Slot()
    def on_clicked(self):
        if self._last_listview is not None:
            for index in reversed(sorted(self._last_listview.selectedIndexes())):
                self._last_listview.model().removeRow(index.row())

    @QtCore.Slot("QWidget*", "QWidget*")
    def on_focusChanged(self, old, now):
        if now in self.listviews:
            self._last_listview = now


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
...