Search code examples
pythonpyqt4

What kind of signal is emitted when QScrollArea entry is selected/clicked?


I'm having though time figuring out what kind of signal is emitted in following situation:

enter image description here

Basicly that's QScrollArea that holds multiple QTableWidgets:

class ScrollArea(QtGui.QScrollArea):
    def __init__(self):
        super(ScrollArea, self).__init__()
        self.scroll_widget = QtGui.QWidget()
        self.scroll_layout = QtGui.QVBoxLayout()
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setWidgetResizable(True)
        self.__create_content()
        self.setWidget(self._content_widget)
        self.scroll_layout.addWidget(self)
        self.scroll_widget.setLayout(self.scroll_layout)

    def __create_content(self):
        self._content_widget = QtGui.QWidget()
        self._content_widget_layout = QtGui.QVBoxLayout()
        self._content_widget.setLayout(self._content_widget_layout)

    def add_item(self, item):
        self._content_widget_layout.addWidget(item)

I'm using Plastique style for QApplication. As it can be seen from the above picture, when an item is clicked inside QScrollArea, blue border appears. What I would like to know is which signal is emitted when the border is drawn? I need this information so I can append a row to the selected QTableWidget whenever a button (on the left side) is clicked.

Also you can see that there is a 'x' inside each table, when 'x' is pressed that QTableWidget gets removed from QScrollArea. If there is a solution for previous problem, I could also remove QTableWidget depending on user selection rather than user clicking the 'x'.


Solution

  • To get the widget that has the focus you can use the focusChanged signal of QApplication:

    from PyQt4 import QtCore, QtGui
    
    
    class HorizontalHeader(QtGui.QHeaderView):
        def __init__(self, parent=None):
            super(HorizontalHeader, self).__init__(QtCore.Qt.Horizontal, parent)
            self.button = QtGui.QToolButton(self, text="x")
            self.sectionResized.connect(self.handleSectionResized)
    
        def handleSectionResized(self):
            last_ix = self.count() - 1
            pos = QtCore.QPoint(self.sectionViewportPosition(last_ix) + self.sectionSize(last_ix) , 0)
            self.button.move(pos)
    
        def showEvent(self, event):
            self.handleSectionResized()
            super(HorizontalHeader, self).showEvent(event)
    
    
    class TableView(QtGui.QTableView):
        def __init__(self, *args, **kwargs):
            super(TableView, self).__init__(*args, **kwargs)
            header = HorizontalHeader(self)
            header.button.clicked.connect(self.deleteLater)
            self.setHorizontalHeader(header)
            QtGui.qApp.focusChanged.connect(self.onFocusChanged)
    
        def onFocusChanged(self, old, new):
            if new == self:
                self.deleteLater()
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        scrollArea = QtGui.QScrollArea()
        scrollArea.setWidgetResizable(True)
        widget = QtGui.QWidget()
        scrollArea.setWidget(widget)
        lay = QtGui.QVBoxLayout(widget)
    
        for i in range(10):
            w = TableView()
            model = QtGui.QStandardItemModel(4, 2, w)
            w.setModel(model)
            lay.addWidget(w)
    
        scrollArea.show()
        sys.exit(app.exec_())