在 NavigationToolbar2QT 中释放平移功能

Posted

技术标签:

【中文标题】在 NavigationToolbar2QT 中释放平移功能【英文标题】:Releasing pan function in NavigationToolbar2QT 【发布时间】:2021-08-23 03:36:29 【问题描述】:

我想从其他按钮取消平移功能。到目前为止,我的理解是当我想要平移和缩放图像时,我会点击“平移”按钮。如果我想做其他功能,例如“标记”功能(在我的情况下),我必须再次单击“平移”按钮,然后单击我想做的任何按钮。

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

为了清楚起见,我想从“标记”按钮取消平移功能,这是我的代码。

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 文档进行了修改。

【问题讨论】:

【参考方案1】:

检查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)

【讨论】:

以上是关于在 NavigationToolbar2QT 中释放平移功能的主要内容,如果未能解决你的问题,请参考以下文章

Matplotlib NavigationToolbar2QT 仅显示禁用的左右箭头。如何显示缩放和平移按钮?

Linux 升级后如何修复“TypeError:navigationToolbar2QT.message[str] 和 _show_message() 之间的连接()失败”?

matlab中怎么注释

[linux] 进程五状态模型

如何正确销毁 pthread 互斥锁

曼瑜天雅传销售员必备的心理学