释放 NavigationToolbar2QT 中的平移功能

Releasing pan function in NavigationToolbar2QT

我想取消其他按钮的平移功能。到目前为止,我的理解是当我想要平移和缩放图像时,我将单击 'Pan' 按钮。如果我想做其他功能,例如'Mark' 功能(在我的例子中),我必须再次单击 'Pan' 按钮,然后单击我想执行的任何按钮。

我已经搜索解决这个问题并找到类似 'release_pan'、'button_release_event' 的东西,但我不明白如何正确实施它们。

明确地说,我想取消 'Mark' 按钮的平移功能,这是我的代码。

import sys
import time

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor

from matplotlib.backends.qt_compat import QtCore, QtWidgets
if QtCore.qVersion() >= "5.":
    from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
    from matplotlib.backends.backend_qt4agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.coor = [0,0]               #temporary user selection
        self.cid = None
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)
        butt = QtWidgets.QHBoxLayout()
        self.static_canvas = FigureCanvas(Figure(figsize=(5, 5), dpi=100))
        self.addToolBar = NavigationToolbar(self.static_canvas, self)
        self.addToolBar.hide()
   
        self.home = QtWidgets.QPushButton('Home')
        self.pan = QtWidgets.QPushButton('Pan')
        self.mark = QtWidgets.QPushButton('Mark')
   
        butt.addWidget(self.home)
        butt.addWidget(self.pan)
        butt.addWidget(self.mark)
   
        layout.addLayout(butt)
        layout.addWidget(self.static_canvas)
        self._static_ax = self.static_canvas.figure.subplots()
        self.tar = plt.imread(r'my_image.tif').copy()
        self._static_ax.imshow(self.tar)
   
        # Set cursor        
        self.cursor = Cursor(self._static_ax, horizOn=True, vertOn=True, useblit=True,
           color = 'r', linewidth = 1)
        #trigger zone
        self.home.clicked.connect(self.Home)
        self.pan.clicked.connect(self.Pan)
        self.mark.clicked.connect(self.Mark)
   
   
    def coor_onclick(self, event):
        """
        This function will get coordination from click and plot it on canvas
        """
   
        #check out-figure click
        if event.xdata == None or event.ydata == None:
            pass
        else:
            self.coor[0] = int(event.xdata)
            self.coor[1] = int(event.ydata)
   
        # print(self.coor)
   
        #show line marking on canvas
        tar = self.tar.copy()
   
        #NOTE:: self.coor = [x,y] = [col, row]
        # x = self.coor[0]
        # y = self.coor[1]
   
        #marking line
        for r in range(tar.shape[1]):   
            for c in range(tar.shape[0]):
                tar[self.coor[1], c] = [255, 0, 0]
                tar[r, self.coor[0]] = [255, 0, 0]
        #set final mark on canvas
        self._static_ax.clear()
        self._static_ax.imshow(tar)
        self._static_ax.axis('off')
   
        # Set cursor        
        self.cursor = Cursor(self._static_ax, horizOn=True, vertOn=True, useblit=True,
                         color = 'r', linewidth = 1)
        self.static_canvas.draw()


    def Home(self):        
        self.cid = self.static_canvas.mpl_connect('button_press_event', self.coor_onclick)
        
        self.addToolBar.home()

    def Pan(self):
        if self.cid is None:
            pass
        else:
            #disconnect to self.coor_onclick
            self.static_canvas.mpl_disconnect(self.cid)
         
        self.addToolBar.pan()


    def Mark(self):
        self.cid = self.static_canvas.mpl_connect('button_press_event', self.coor_onclick)
   
if __name__ == "__main__":
    # Check whether there is already a running QApplication (e.g., if running
    # from an IDE).
    qapp = QtWidgets.QApplication.instance()
    if not qapp:
        qapp = QtWidgets.QApplication(sys.argv)
    app = ApplicationWindow()
    app.show()
    app.activateWindow()
    app.raise_()
    qapp.exec_()

我已经根据 matplotlib 文档进行了修改。

检查 NavigationToolbar 的当前模式,如果模式是“PAN”,再次调用 pan() 关闭模式(这将取消选中操作(查看源代码了解更多详情。)).

仅供参考: 您可以使用NavigationToolbar.mode.name查看NavigationToolbar的当前模式,目前有两种模式:“ZOOM”和“PAN”。

在您的代码中,像这样更改函数标记:

def Mark(self):
    # if the current mode is Pan, set the mode off by unchecking it.
    if self.nav_toolbar.mode.name == "PAN":
        self.nav_toolbar.pan()
        
    self.cid = self.static_canvas.mpl_connect(
            'button_press_event', self.coor_onclick)