mouseMoveEvent срабатывает вне пределов графика
Есть основной класс "MainWindow", в нем подключаю событие через кнопку "gross_", которое отрабатывает движение мыши в классе "MyFilter" все это работает, как нужно.
Теперь нужно использовать функцию "QRubberBand". Нашел пример в интернете и скопировал: подключаю события посредством кнопки "handleButton" через класс "ResizableRubberBand", срабатывает только вне пределов графика(справа верхний угол). Как сделать, чтобы захватывались график и области вне пределов графика. Планирую добавлять дополнительные графики и рисовать вертикальную линию, с помощью "QRubberBand" поверх всех графиков.
Все это, если можно сделать в классе "MyFilter", так как для этой цели его и создавал, но не получилось подключить в него класс "ResizableRubberBand".
from PyQt5 import QtGui, QtCore, QtWidgets, QtChart
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 MyFilter(QtCore.QObject):
def __init__(self, parent=None):
QtCore.QObject.__init__(self, parent)
self.parent = parent
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.HoverMove:
chart_view = self.parent.splitter.widget(0)
if isinstance(chart_view, QtChart.QChartView):
chart = chart_view.chart()
s = chart.series()
return False
class ResizableRubberBand(QtWidgets.QWidget):
def __init__(self, parent=None):
print("ResizableRubberBand")
super(ResizableRubberBand, self).__init__(parent)
self.draggable = False
self.mousePressPos = None
self.mouseMovePos = None
self._band = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
self._band.setGeometry(550, 550, 550, 550)
self._band.show()
self.show()
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.RightButton:
self.mousePressPos = event.globalPos() # global
self.mouseMovePos = event.globalPos() - self.pos() # local
self.draggable = True
elif event.button() == QtCore.Qt.LeftButton:
self.position = QtCore.QPoint(event.pos())
self.upper_left = self.position
self.lower_right = self.position
self.mode = "drag_lower_right"
self._band.show()
print("mousePressEvent")
def mouseMoveEvent(self, event):
if self.draggable and event.buttons() & QtCore.Qt.RightButton:
globalPos = event.globalPos()
print(globalPos)
diff = globalPos - self.mouseMovePos
self.move(diff)
self.mouseMovePos = globalPos - self.pos()
elif self._band.isVisible():
# visible selection
if self.mode is "drag_lower_right":
self.lower_right = QtCore.QPoint(event.pos())
# print(str(self.lower_right))
elif self.mode is "drag_upper_left":
self.upper_left = QtCore.QPoint(event.pos())
# print(str(self.upper_left))
# update geometry
self._band.setGeometry(QtCore.QRect(self.upper_left, self.lower_right).normalized())
print("mouseMoveEvent")
def mouseReleaseEvent(self, event):
self.draggable = False
print("mouseReleaseEvent")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, start = 1, parent=None):
self.start = start
super().__init__(parent)
self.setMouseTracking(True)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.gross = QtWidgets.QPushButton()
self.gross.setText("Gross")
self.gross.clicked.connect(self.gross_)
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.label.setPixmap(QtGui.QPixmap('image.png'))
self.hbox = QtWidgets.QHBoxLayout()
self.hbox.addWidget(self.gross)
self.hbox.addWidget(self.button)
self.hbox.addWidget(self.label)
self.splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
self.lay = QtWidgets.QVBoxLayout(central_widget)
self.lay.insertLayout(0, self.hbox)
self.lay.addWidget(self.splitter, stretch=1)
self.chart_view = QtChart.QChartView()
self.chart = QtChart.QChart()
self.line_serie = QtChart.QLineSeries()
for i, value in enumerate(mas):
self.line_serie.append(QtCore.QPointF(i, value))
self.chart.addSeries(self.line_serie)
self.chart.createDefaultAxes()
self.chart_view.setChart(self.chart)
self.splitter.addWidget(self.chart_view)
def gross_(self):
self.filter = MyFilter(self)
self.installEventFilter(self.filter)
def handleButton(self):
self.band = ResizableRubberBand(self.label)
print("handleButton")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow(start = 0)
w.show()
sys.exit(app.exec_())
Ответы (1 шт):
Как сделать, чтобы захватывались график и области вне пределов графика.
Вам надо передать родителя self.central_widget
self.band = ResizableRubberBand(self.central_widget)
и установить размер для класса ResizableRubberBand
self.resize(self.window().size())
from PyQt5 import QtGui, QtCore, QtWidgets, QtChart
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 MyFilter(QtCore.QObject):
def __init__(self, parent=None):
QtCore.QObject.__init__(self, parent)
self.parent = parent
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.HoverMove:
chart_view = self.parent.splitter.widget(0)
if isinstance(chart_view, QtChart.QChartView):
chart = chart_view.chart()
s = chart.series()
return False
class ResizableRubberBand(QtWidgets.QWidget):
def __init__(self, parent=None):
print("ResizableRubberBand")
super(ResizableRubberBand, self).__init__(parent)
self.resize(self.window().size()) # +++ <<<-----
self.draggable = False
self.mousePressPos = None
self.mouseMovePos = None
self._band = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
self._band.setGeometry(550, 550, 550, 550)
self._band.show()
self.show()
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.RightButton:
self.mousePressPos = event.globalPos() # global
self.mouseMovePos = event.globalPos() - self.pos() # local
self.draggable = True
elif event.button() == QtCore.Qt.LeftButton:
self.position = QtCore.QPoint(event.pos())
self.upper_left = self.position
self.lower_right = self.position
self.mode = "drag_lower_right"
self._band.show()
print("mousePressEvent")
def mouseMoveEvent(self, event):
if self.draggable and event.buttons() & QtCore.Qt.RightButton:
globalPos = event.globalPos()
print(globalPos)
diff = globalPos - self.mouseMovePos
self.move(diff)
self.mouseMovePos = globalPos - self.pos()
elif self._band.isVisible():
# visible selection
if self.mode is "drag_lower_right":
self.lower_right = QtCore.QPoint(event.pos())
# print(str(self.lower_right))
elif self.mode is "drag_upper_left":
self.upper_left = QtCore.QPoint(event.pos())
# print(str(self.upper_left))
# update geometry
self._band.setGeometry(QtCore.QRect(self.upper_left, self.lower_right).normalized())
print("mouseMoveEvent")
def mouseReleaseEvent(self, event):
self.draggable = False
print("mouseReleaseEvent")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, start = 1, parent=None):
self.start = start
super().__init__(parent)
self.setMouseTracking(True)
# vvvv <-------------------------------------------------------<!
self.central_widget = QtWidgets.QWidget() # ^ self.
self.setCentralWidget(self.central_widget)
self.gross = QtWidgets.QPushButton()
self.gross.setText("Gross")
self.gross.clicked.connect(self.gross_)
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.label.setPixmap(QtGui.QPixmap('Ok.png')) # 'image.png' установите свое !!!
self.hbox = QtWidgets.QHBoxLayout()
self.hbox.addWidget(self.gross)
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.insertLayout(0, self.hbox)
self.lay.addWidget(self.splitter, stretch=1)
self.chart_view = QtChart.QChartView()
self.chart = QtChart.QChart()
self.line_serie = QtChart.QLineSeries()
for i, value in enumerate(mas):
self.line_serie.append(QtCore.QPointF(i, value))
self.chart.addSeries(self.line_serie)
self.chart.createDefaultAxes()
self.chart_view.setChart(self.chart)
self.splitter.addWidget(self.chart_view)
def gross_(self):
self.filter = MyFilter(self)
self.installEventFilter(self.filter)
def handleButton(self):
# self.band = ResizableRubberBand(self.label) # - self.label
self.band = ResizableRubberBand(self.central_widget) # + self.central_widget
self.band.show() # +
print("handleButton")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow(start = 0)
w.show()
sys.exit(app.exec_())
