При подключении виджета QRubberBand нет доступа к дочерним виджетам

Создаю полосу прокрутки, график через класс MainWindow и дополнительные графики ниже кнопкой Open, удаляю кнопкой Close. Так же в этом классе подключается класс _RubberBand кнопкой handleButton для рисования поверх всех виджетов.

Как мне сделать полосу прокрутки и кнопки активными при включенном QtWidgets.QRubberBand? Я пробовал сам, через setDisabled, но не получается. Область где находятся кнопки и полоса прокрутки не нужно отрисовывать

self._band = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Line, self)

который помещаю в класс _RubberBand.

И еще хотелось бы автоматически определить координаты, где находятся кнопки, чтобы не рисовать на них и полосах прокрутки. К примеру:

def mouseMoveEvent(self, event):
    if event.pos().y() > 50:
       print(event.pos().x(), event.pos().y())

Весь код:

from PyQt5 import QtCore, QtGui, QtWidgets, QtChart
import numpy as np
import math

mas =[1.33, 1.15, 1.55, 1.65, 1.64, 1.91, 1.33, 2.3, 1.5, 1.35, 2.52, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1,
              1.33, 1.15, 1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77, 1.7, 1.87, 2.7, 1.55, 1.73, 2.1,
              1.33, 1.15, 1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1]
x = len(mas)
x_ = x - 1

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

        self.setMouseTracking(True)
        self.resize(self.window().size())  # +++ <<<-----
        self.mouseMovePos = None

    def mouseMoveEvent(self, event):
        if event.pos().y() > 50:
           print(event.pos().x(), event.pos().y())

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, start = 0, parent=None):
        super().__init__(parent)
        self.setMouseTracking(True)

        self.start = start
        self.step = 30

        self.scrollbar = QtWidgets.QScrollBar(
            QtCore.Qt.Horizontal,
            sliderMoved=self.onAxisSliderMoved,
            pageStep=self.step,
        )

        self.central_widget = QtWidgets.QWidget()
        self.setCentralWidget(self.central_widget)

        self.open_btn = QtWidgets.QPushButton("Open")
        self.open_btn.clicked.connect(self.add_chartview)
        self.close_btn = QtWidgets.QPushButton("Close")
        self.close_btn.clicked.connect(self.remove_chartview)

        self.button = QtWidgets.QPushButton('Show Rubber Band')
        self.button.clicked.connect(self.handleButton)

        self.label = QtWidgets.QLabel()
        self.label.setScaledContents(True)
        self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)

        self.hbox = QtWidgets.QHBoxLayout()
        self.hbox.addWidget(self.open_btn)
        self.hbox.addWidget(self.close_btn)
        self.hbox.addWidget(self.button)
        self.hbox.addWidget(self.label)

        self.splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)

        self.lay = QtWidgets.QVBoxLayout(self.central_widget)
        self.lay.addLayout(self.hbox)
        self.lay.addWidget(self.splitter, stretch=1)
        self.lay.addWidget(self.scrollbar)

        self.onAxisSliderMoved(self.scrollbar.value())
        self.add_chartview()
        self.adjust_axes(self.start, 31)


    def add_chartview(self):
        print("добавляем график")
        chart_view = QtChart.QChartView()
        chart = QtChart.QChart()
        line_serie = QtChart.QLineSeries()
        for i, value in enumerate(mas):
            line_serie.append(QtCore.QPointF(i, value))
        chart.addSeries(line_serie)
        chart.createDefaultAxes()
        chart_view.setChart(chart)
        self.splitter.addWidget(chart_view)

    def remove_chartview(self):
        print("удаляем график")
        count = self.splitter.count()
        if count > 1:
            w = self.splitter.widget(count - 1)
            if w is not None:
                w.deleteLater()

    def handleButton(self):
        #        self.band = ResizableRubberBand(self.label)                     # - self.label
        self.band = _RubberBand(self.central_widget)  # + self.central_widget
        self.band.show()  # +
        print("handleButton")

    def adjust_axes(self, value_min, value_max):
        if value_min >= 0 and value_max >= 0 and value_max <= x_ and value_max > value_min:
            for i in range(0, self.splitter.count()):
                chart_view = self.splitter.widget(i)
                if isinstance(chart_view, QtChart.QChartView):
                    chart = chart_view.chart()
                    for serie in chart.series():
                        chart.axisX(serie).setRange(value_min, value_max)


    @QtCore.pyqtSlot(int)
    def onAxisSliderMoved(self, value):
        value2 = value + self.step
        value1 = value
        if value2 >= x_:
            value2 = x_
            value1 = value2 - self.step
        self.adjust_axes(math.floor(value1), math.ceil(value2))


if __name__ == "__main__":
    import sys

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

Ответы (1 шт):

Автор решения: S. Nick

Как вариант.

Обратите внимание, что кнопка self.button работает как переключатель Show / Hide.

from PyQt5 import QtCore, QtGui, QtWidgets, QtChart
#? import numpy as np
import math

mas =[1.33, 1.15, 1.55, 1.65, 1.64, 1.91, 1.33, 2.3, 1.5, 1.35, 2.52, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1,
      1.33, 1.15, 1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77, 1.7, 1.87, 2.7, 1.55, 1.73, 2.1,
      1.33, 1.15, 1.55, 1.92, 1.64, 1.91, 1.33, 1.71, 1.5, 1.35, 1.22, 1.77, 1.7, 1.87, 2.0, 1.55, 1.73, 2.1]
x = len(mas)
x_ = x - 1

class _RubberBand(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(_RubberBand, self).__init__(parent)
        self.setMouseTracking(True)

        self.resize(self.window().widget2.size())                            # +++ 

    def mouseMoveEvent(self, event):
#?            if event.pos().y() > 50:
        print(event.pos().x(), event.pos().y())
        

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, start = 0, parent=None):
        super().__init__(parent)
        self.setMouseTracking(True)

        self.start = start
        self.step = 30

        self.scrollbar = QtWidgets.QScrollBar(
            QtCore.Qt.Horizontal,
            sliderMoved=self.onAxisSliderMoved,
            pageStep=self.step,
        )

        self.central_widget = QtWidgets.QWidget()
        self.setCentralWidget(self.central_widget)

        self.open_btn = QtWidgets.QPushButton("Open")
        self.open_btn.clicked.connect(self.add_chartview)
        self.close_btn = QtWidgets.QPushButton("Close")
        self.close_btn.clicked.connect(self.remove_chartview)

        self.button = QtWidgets.QPushButton('Show Rubber Band')
        self.button.clicked.connect(self.handleButton)

        self.label = QtWidgets.QLabel("Это Label")
        self.label.setScaledContents(True)
        self.label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)

        self.hbox = QtWidgets.QHBoxLayout()
        self.hbox.addWidget(self.open_btn)
        self.hbox.addWidget(self.close_btn)
        self.hbox.addWidget(self.button)
        self.hbox.addWidget(self.label)

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        self.widget2 = QtWidgets.QWidget() 
        self.widget2.setStyleSheet("background-color: #ff48ff;")
        self.layV = QtWidgets.QVBoxLayout(self.widget2)

        self.splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)              # !!! 
        self.layV.addWidget(self.splitter)                                   # !!!
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
        self.lay = QtWidgets.QVBoxLayout(self.central_widget)
        self.lay.addLayout(self.hbox)
#        self.lay.addWidget(self.splitter, stretch=1)
        self.lay.addWidget(self.widget2)                                     # !!! 
        self.lay.addWidget(self.scrollbar)

        self.onAxisSliderMoved(self.scrollbar.value())
        self.add_chartview()
        self.adjust_axes(self.start, 31)
        
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        self.band = _RubberBand(self.widget2)                                # !!!      
        self.band.setStyleSheet("background-color: #ff4848;")         
        self.band.setVisible(False)                                          # !!!
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        

    def add_chartview(self):
        print("добавляем график")
        chart_view = QtChart.QChartView()
        chart = QtChart.QChart()
        line_serie = QtChart.QLineSeries()
        for i, value in enumerate(mas):
            line_serie.append(QtCore.QPointF(i, value))
        chart.addSeries(line_serie)
        chart.createDefaultAxes()
        chart_view.setChart(chart)
        self.splitter.addWidget(chart_view)

    def remove_chartview(self):
        print("удаляем график")
        count = self.splitter.count()
        if count > 1:
            w = self.splitter.widget(count - 1)
            if w is not None:
                w.deleteLater()


    def handleButton(self):
#        self.band = _RubberBand(self.central_widget)  

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        if not self.band.isVisible(): #self.band:
            self.band.show()  
            self.button.setText('Hide Rubber Band')
        else:
            self.band.hide()
            self.button.setText('Show Rubber Band')
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    def adjust_axes(self, value_min, value_max):
        if value_min >= 0 and value_max >= 0 and value_max <= x_ and value_max > value_min:
            for i in range(0, self.splitter.count()):
                chart_view = self.splitter.widget(i)
                if isinstance(chart_view, QtChart.QChartView):
                    chart = chart_view.chart()
                    for serie in chart.series():
                        chart.axisX(serie).setRange(value_min, value_max)

    @QtCore.pyqtSlot(int)
    def onAxisSliderMoved(self, value):
        value2 = value + self.step
        value1 = value
        if value2 >= x_:
            value2 = x_
            value1 = value2 - self.step
        self.adjust_axes(math.floor(value1), math.ceil(value2))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка