QtWdgets how to make a line dependent on the mouse

Question:

I want to achieve the follwing in QtWidjets. I have a line that moves with the mouse but I want it to move only when clicking (and holding the click) on the actual line; when there is no left click on the mouse nothing should happen. so far I only managed to make it move automatically with the mouse. I am new to QtWidgets and I am having trouble finding a solution.

Thank you if you have any tip.

Here is the code snippet:

import numpy as np
from PySide2 import QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

class SnaptoCursor(object):
    def __init__(self, ax, x):
        self.ax = ax
        self.ly = ax.axvline(color='k')
        self.x = x
        self.txt = ax.text(0.7, 0.9, '', transform=ax.transAxes)


    def mouse_move(self, event):
        if event.inaxes:
            indx = np.searchsorted(self.x, [event.xdata])[0]
            x = self.x[indx]
            self.ly.set_xdata(x)
            self.txt.set_text('x=%1.2f' % x)
            self.ax.figure.canvas.draw()
        else:
            pass

class App(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        self.figure = Figure(figsize=(10, 6.9))
        self.canvas = FigureCanvas(self.figure)
        self.canvas_ax = self.canvas.figure.subplots()

        x = np.arange(0,40)
        self.cursor = SnaptoCursor(self.canvas_ax, x)
        self.cid = self.canvas.mpl_connect('motion_notify_event', self.cursor.mouse_move)
        self.canvas_ax.plot(x, np.random.rand(40))

        # Layout
        layout = QtWidgets.QVBoxLayout(self._main)
        layout.addWidget(self.canvas)
        self.showMaximized()



if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    ex = App()
    ex.show()
    app.exec_()
Asked By: Josh.h

||

Answers:

I used the button_press_event and button_release_event events documented here to get the button state into SnaptoCursor:

import numpy as np
from PySide2 import QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

class SnaptoCursor(object):
    def __init__(self, ax, x):
        self.ax = ax
        self.ly = ax.axvline(color='k')
        self.x = x
        self.txt = ax.text(0.7, 0.9, '', transform=ax.transAxes)
        self.mouse_down = False

    def mouse_move(self, event):
        if event.inaxes and self.mouse_down:
            indx = np.searchsorted(self.x, [event.xdata])[0]
            x = self.x[indx]
            self.ly.set_xdata(x)
            self.txt.set_text('x=%1.2f' % x)
            self.ax.figure.canvas.draw()
        else:
            pass

    def mouse_press(self, event):
        # is left click
        if event.button == 1:
            self.mouse_down = True

    def mouse_release(self, event):
        # is left click
        if event.button == 1:
            self.mouse_down = False

class App(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        self.figure = Figure(figsize=(10, 6.9))
        self.canvas = FigureCanvas(self.figure)
        self.canvas_ax = self.canvas.figure.subplots()

        x = np.arange(0,40)
        self.cursor = SnaptoCursor(self.canvas_ax, x)
        self.cid = self.canvas.mpl_connect('motion_notify_event', self.cursor.mouse_move)
        self.cid = self.canvas.mpl_connect('button_press_event', self.cursor.mouse_press)
        self.cid = self.canvas.mpl_connect('button_release_event', self.cursor.mouse_release)
        self.canvas_ax.plot(x, np.random.rand(40))

        # Layout
        layout = QtWidgets.QVBoxLayout(self._main)
        layout.addWidget(self.canvas)
        self.showMaximized()



if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    ex = App()
    ex.show()
    app.exec_()
Answered By: Runinho
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.