且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 matplotlib 在 wxpython 面板中组合键和鼠标按钮事件

更新时间:2023-11-30 16:23:22

我不完全确定您做错了什么,因为您的代码看起来不完整.我认为您的总体想法是正确的,但您似乎一直在混淆类并试图从错误的类或其他东西访问属性 shift_is_held.

I'm not entirely sure what you're doing wrong because your code looks incomplete. I think your general idea was correct, but you seem to have been mixing up classes and trying to access the property shift_is_held from the wrong class or something.

我使用 matplotlib 示例中的 lasso_example.py 代码编写了这个简单的示例.我在尝试使用 control 键时确实遇到了一些复杂情况.当我尝试使用控制键用鼠标拖动时,套索管理器变得无响应(包括来自 matplotlib 的原始代码).我不知道为什么,所以我在当前代码中使用 shiftalt 键作为修饰符.

I wrote this simple example using the lasso_example.py code from matplotlib examples. I did run into some complications trying to use the control key. When I try to drag with the mouse using the control key, the Lasso manager becomes unresponsive (including in the original code from matplotlib). I could not figure out why, so I used the shift and alt keys as modifiers in the present code.

你会看到,在释放套索的那一刻,执行什么动作的逻辑是在LassoManager.callback()

You'll see that the logic of what action to perform depending on which key is held down at the moment when you release the lasso is performed in LassoManager.callback()

import logging
import matplotlib
from matplotlib.widgets import Lasso
from matplotlib.colors import colorConverter
from matplotlib.collections import RegularPolyCollection
from matplotlib import path

import matplotlib.pyplot as plt
from numpy.random import rand

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)


class Datum(object):
    colorin = colorConverter.to_rgba('red')
    colorShift = colorConverter.to_rgba('cyan')
    colorCtrl = colorConverter.to_rgba('pink')
    colorout = colorConverter.to_rgba('blue')

    def __init__(self, x, y, include=False):
        self.x = x
        self.y = y
        if include:
            self.color = self.colorin
        else:
            self.color = self.colorout


class LassoManager(object):
    def __init__(self, ax, data):
        self.axes = ax
        self.canvas = ax.figure.canvas
        self.data = data

        self.Nxy = len(data)

        facecolors = [d.color for d in data]
        self.xys = [(d.x, d.y) for d in data]
        fig = ax.figure
        self.collection = RegularPolyCollection(
            fig.dpi, 6, sizes=(100,),
            facecolors=facecolors,
            offsets = self.xys,
            transOffset = ax.transData)

        ax.add_collection(self.collection)

        self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
        self.keyPress = self.canvas.mpl_connect('key_press_event', self.onKeyPress)
        self.keyRelease = self.canvas.mpl_connect('key_release_event', self.onKeyRelease)
        self.lasso = None
        self.shiftKey = False
        self.ctrlKey = False

    def callback(self, verts):
        logging.debug('in LassoManager.callback(). Shift: %s, Ctrl: %s' % (self.shiftKey, self.ctrlKey))
        facecolors = self.collection.get_facecolors()
        p = path.Path(verts)
        ind = p.contains_points(self.xys)
        for i in range(len(self.xys)):
            if ind[i]:
                if self.shiftKey:
                    facecolors[i] = Datum.colorShift
                elif self.ctrlKey:
                    facecolors[i] = Datum.colorCtrl
                else:
                    facecolors[i] = Datum.colorin
            else:
                facecolors[i] = Datum.colorout

        self.canvas.draw_idle()
        self.canvas.widgetlock.release(self.lasso)
        del self.lasso

    def onpress(self, event):
        if self.canvas.widgetlock.locked():
            return
        if event.inaxes is None:
            return
        self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
        # acquire a lock on the widget drawing
        self.canvas.widgetlock(self.lasso)

    def onKeyPress(self, event):
        logging.debug('in LassoManager.onKeyPress(). Event received: %s (key: %s)' % (event, event.key))
        if event.key == 'alt+alt':
            self.ctrlKey = True
        if event.key == 'shift':
            self.shiftKey = True

    def onKeyRelease(self, event):
        logging.debug('in LassoManager.onKeyRelease(). Event received: %s (key: %s)' % (event, event.key))
        if event.key == 'alt':
            self.ctrlKey = False
        if event.key == 'shift':
            self.shiftKey = False

if __name__ == '__main__':

    data = [Datum(*xy) for xy in rand(100, 2)]

    ax = plt.axes(xlim=(0,1), ylim=(0,1), autoscale_on=False)
    lman = LassoManager(ax, data)

    plt.show()