Foussy
Foussy

Reputation: 287

Focus on multiple widgets

I have a GUI with several widgets inside my main window. I have more specifically one QTableWidget and one QTableView which contain selectable rows. If I select one row in the first table, and then select one another in the 2nd table, I loose the focus on the 1st table, thus I don't have the blue background on the selected row.

What I have for the moment is this :

enter image description here Or this: enter image description here

What I would like is this :

enter image description here

How can I do this ?

Upvotes: 2

Views: 927

Answers (2)

eyllanesc
eyllanesc

Reputation: 243927

You have to use a QProxyStyle to establish that the painting of the selected items is the same when the view is focused or not.

from PyQt5 import QtGui, QtWidgets


class ProxyStyle(QtWidgets.QProxyStyle):
    def drawPrimitive(self, element, option, painter, widget=None):
        if element == QtWidgets.QStyle.PE_PanelItemViewRow:
            if option.state & QtWidgets.QStyle.State_Selected:
                option.state |= QtWidgets.QStyle.State_Active
        super().drawPrimitive(element, option, painter, widget)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    tablewidget = QtWidgets.QTableWidget(10, 6)

    model = QtGui.QStandardItemModel(10, 6)
    tableview = QtWidgets.QTableView()
    tableview.setModel(model)

    for table in (
        tablewidget,
        tableview,
    ):
        table.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        table.setStyle(ProxyStyle(table.style()))

    w = QtWidgets.QWidget()
    lay = QtWidgets.QHBoxLayout(w)
    lay.addWidget(tablewidget)
    lay.addWidget(tableview)
    w.show()

    sys.exit(app.exec_())

You can also use a delegate:

from PyQt5 import QtGui, QtWidgets


class Delegate(QtWidgets.QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)
        if option.state & QtWidgets.QStyle.State_Selected:
            option.state |= QtWidgets.QStyle.State_Active


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    tablewidget = QtWidgets.QTableWidget(10, 6)

    model = QtGui.QStandardItemModel(10, 6)
    tableview = QtWidgets.QTableView()
    tableview.setModel(model)

    for table in (
        tablewidget,
        tableview,
    ):
        table.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        delegate = Delegate(table)
        table.setItemDelegate(delegate)

    w = QtWidgets.QWidget()
    lay = QtWidgets.QHBoxLayout(w)
    lay.addWidget(tablewidget)
    lay.addWidget(tableview)
    w.show()

    sys.exit(app.exec_())

Upvotes: 3

abhilb
abhilb

Reputation: 5757

You need to connect the itemSelectionChanged signal of the qtablewidget to a slot where you have the logic to select the row in the other widget.

something like

tblwidget.itemSelectionChanged.connect(handleSelection)

And in define a slot called handleSelection

def handleSelection(self):
    .... logic for selecting the current row
    .. of the other widget

Upvotes: 0

Related Questions