使用“ <b1-motion>”时的Python tkinter mpl_connect事件

时间:2019-02-27 09:17:54

标签: python tkinter

我正在尝试创建拖放功能,您可以从列表框中选择要绘制的“信号”并将其拖动(单击鼠标左键并拖动)到Matplotlib图(包含一个或多个子图)。如果您引用拖动到某些数据的项目,则随附的代码可以做到这一点,并且在释放任何子图(轴)顶部的鼠标按钮时都可以完成此操作。

我要添加的内容无法解决(如果有)的解决方案,是将鼠标悬停在上方的坐标轴从列表框拖动到项目上方时,使其高亮,以使其更清楚地显示所拖动数据的位置被绘制。

我想问题是mpl_connect在按下鼠标按钮进入图形时没有“看到”来自鼠标的任何事件。有人对实现这一目标有任何想法吗?

最好的问候,丹尼尔

import tkinter as tk
import tkinter.filedialog
# import math

from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk


class App(tk.Tk):
    def __init__(self):

        self.master = tk.Tk()  # This is the main canvas

        self.f1 = tk.Frame(self.master, bg='lightgreen')
        self.f1.grid(row = 0, column = 0, sticky= 'NSEW')

        self.f2 = tk.Frame(self.f1, bg='blue')
        self.f2.grid(row = 1, column = 0)


        self.l1 = tk.Listbox(self.master, selectmode="extended", font = 12)
        self.l1.grid(row=0, column=0, columnspan = 2, sticky='NSEW')

        for item in ["one", "two", "three", "four"]:
            self.l1.insert(tk.END, item)

        self.master.grid_rowconfigure(0, weight=0)
        self.master.grid_rowconfigure(1, weight=1)
        self.master.grid_columnconfigure(0, weight=1)
        self.master.grid_columnconfigure(1, weight=1)

        self.canvas = tk.Canvas(self.master, bg = 'pink')
        self.canvas.grid(row=1, column=0, columnspan = 2, sticky='NSEW')

        self.figure = plt.figure(dpi=100, figsize=(8, 5.8))
        self.figure.patch.set_facecolor('lightblue')
        self.figAgg = FigureCanvasTkAgg(self.figure, self.canvas)
        self.mplCanvas = self.figAgg.get_tk_widget()

        self.toolbar = NavigationToolbar2Tk(self.figAgg,self.canvas)
        self.toolbar.update()

        self.cwid = self.canvas.create_window(0, 0, window=self.mplCanvas, anchor='nw')

        self.axes = self.figure.subplots(2, 1, squeeze=True)
        self.figure.tight_layout()


        self.l1.bind("<ButtonPress-1>", self.StartMove, add = '+')
        self.l1.bind("<ButtonPress-1>", self.showtip, add = '+')

        self.l1.bind("<ButtonRelease>", self.hidetip, add = '+')
        self.l1.bind("<B1-Motion>", self.OnMotion, add = '+')

        self.d2 = self.figAgg.mpl_connect('axes_enter_event', self.enter_axes)
        self.d3 = self.figAgg.mpl_connect('axes_leave_event', self.leave_axes)
        # self.d4 = self.figAgg.mpl_connect('motion_notify_event', self.on_drop)

        self.current_widget = None

        self.master.bind_all("<B1-Motion>", self.show_info, add = '+')

        self.mplCanvas.bind("<<B1-Enter>>", self.on_enter)
        self.mplCanvas.bind("<<B1-Leave>>", self.on_leave)
        self.figAgg.mpl_connect('button_release_event', self.on_drop)

    def on_drop(self, event):
        print('DROPPING')

    def show_info(self, event):
        widget = event.widget.winfo_containing(event.x_root, event.y_root)

        if self.current_widget != widget:
            if self.current_widget:

                if widget.bindtags()[1] == 'Canvas':
                    print('YES A CANVAS')
                self.current_widget.event_generate("<<B1-Leave>>")
            self.current_widget = widget
            self.current_widget.event_generate("<<B1-Enter>>")

    def on_enter(self, event):
        print('ENTERING')

    def on_leave(self, event):
        print('LEAVING')

    def enter_axes(self, event):
        print('enter_axes', event.inaxes)
        event.inaxes.patch.set_facecolor('pink')
        event.canvas.draw()

    def leave_axes(self, event):
        print('leave_axes', event.inaxes)
        event.inaxes.patch.set_facecolor('white')
        event.canvas.draw()

    def StartMove(self, event):
        self.x = event.widget.winfo_rootx()
        self.y = event.widget.winfo_rooty()

    def on_drop(self, event):
        print('DROPPING')

    def showtip(self, event):
        self.curIndex = event.widget.nearest(event.y)
        self.curIndex = event.widget.nearest(event.y)
        i = event.widget.nearest(event.y)
        self.curState = event.widget.selection_includes(i)
        x, y, cx, cy = event.widget.bbox('active')
        x += event.widget.winfo_rootx() + 25
        y += event.widget.winfo_rooty() + 20
        # creates a toplevel window
        self.tw = tk.Toplevel(event.widget)
        # Leaves only the label and removes the app window
        self.tw.wm_overrideredirect(True)
        self.tw.wm_geometry("+%d+%d" % (x, y))
        text = '\n'.join([str(case) for case in event.widget.curselection()])
        print(text)
        label = tk.Label(self.tw, text=text, justify='left',
                       background="#ffffe0", relief='solid', borderwidth=1,
                       font=("tahoma", "12", "normal"),
                       wraplength = 180)
        label.pack(ipadx=1)

    def hidetip(self, event):
        tw = self.tw
        self.tw= None
        if tw:
            tw.destroy()

    def OnMotion(self, event):
        deltax = event.x + self.x + 25
        deltay = event.y + self.y + 20
        self.tw.geometry("+%d+%d" % (deltax, deltay))

app=App()
app.master.wm_geometry("800x800")
app.master.resizable(width=False, height=False)
app.master.mainloop()

0 个答案:

没有答案