我怎样才能得到一个覆盖整个Tkinter画布的绘图?

2024-06-26 08:33:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个TKinter画布,在那里我显示一个绘图。问题是,我希望绘图适合整个画布,占据尽可能多的区域,但无法改变大小。关于如何实现这一点,有什么建议吗?下面是我正在显示绘图的窗口的类


import numpy as np
import cv2
from PIL import Image, ImageTk
import matplotlib.pyplot as plt
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


""" 
See if can draw new window on exteral screen
"""

#Define the target, source and output arrays. Source has to be completely white otherwise it kills everything
def initialize(x,y):
    xarr = np.zeros(x)
    yarr = np.zeros(y)
    target = np.meshgrid(xarr,yarr)
    target = target[0]
    source = np.meshgrid(xarr,yarr)
    source = source[0]
    output = np.meshgrid(xarr,yarr)
    output = output[0]
    for i in range(x):
        for n in range(y):
            source[n][i] = 1
    return target, source, output

# creates trap between XTrapMin-XTrapMax and YTrapMin-YTrapMax on Array
def trap(xtmi,xtma,xs,ytmi,ytma,ys,array):
    for i in range(xs):
        if xtmi < i < xtma:
            for n in range(ys):
                if ytmi < n < ytma:
                    array[n][i] = 255
    return

#Returns the amplitude of a complex number
def Amplitude(x):
    if isinstance(x, complex):
        return np.sqrt(x.real**2+x.imag**2)
    else:
        return np.abs(x)

#Returns the phase of a complex number
def Phase(z):
        return np.angle(z)

#Main GS algorithm implementation using numpy FFT package
#performs the GS algorithm to obtain a phase distribution for the plane, Source
#such that its Fourier transform would have the amplitude distribution of the plane, Target.
def GS(target,source):
    A = np.fft.ifft2(target)
    for i in range(5):
        B = Amplitude(source) * np.exp(1j * Phase(A))
        C = np.fft.fft2(B)
        D = Amplitude(target) * np.exp(1j * Phase(C))
        A = np.fft.ifft2(D)
    output = Phase(A)
    return output

#Make array into PIL Image
def mkPIL(array):
    im = Image.fromarray(np.uint8(array))
    return im

def up():
    global ytmi
    global ytma
    ytmi += 10
    ytma += 10
    return 

def down():
    global ytmi
    global ytma
    ytmi -= 10
    ytma -= 10
    return

def right():
    global xtmi
    global xtma
    xtmi += 10
    xtma += 10
    return

def left():
    global xtmi
    global xtma
    xtmi -= 10
    xtma -= 10
    return

xtmi = 127
xtma = 129
xs = 256
ytmi = 127
ytma = 129
ys = 256


root = tk.Tk()
root.attributes('-fullscreen', True)
def main():
    app = Lower(root)
    root.mainloop()

class Lower:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master).pack()
        self.displayimg = tk.Button(self.frame, text = 'Display', width = 25, command = self.plot)
        self.displayimg.pack()
        self.makewidg()
    def makewidg(self):
        fig = plt.figure(figsize=(100,100), frameon=False)  #changing figsize doesnt cange the size of the plot display
        fig.tight_layout()
        self.ax = fig.add_subplot(111)
        self.ax.set_yticklabels([])                        
        self.ax.set_xticklabels([])
        self.canvas = FigureCanvasTkAgg(fig, master=self.master)
        self.canvas.get_tk_widget().pack(expand=True)
        self.canvas.draw()
        self.new_window()
    def new_window(self):
        self.newWindow = tk.Toplevel()
        self.app = Display(self.newWindow)
    def plot(self): 
        global xtmi, xtma, xs, ytmi, ytma, ys, i
        target,source,output=initialize(xs,ys)
        trap(xtmi,xtma,xs,ytmi,ytma,ys,target)
        output = GS(target,source)
        self.ax.imshow(output, cmap='gray')
        self.ax.set_yticklabels([])                        
        self.ax.set_xticklabels([])
        self.canvas.draw()
        self.ax.clear()

    def kill(self): 
        root.destroy()

class Display:

    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        self.frame.pack()
        self.up = tk.Button(self.frame, text = 'Up', width = 25, command = up)
        self.up.pack()
        self.down = tk.Button(self.frame, text = 'Down', width = 25, command = down)
        self.down.pack()
        self.right = tk.Button(self.frame, text =  'Right', width = 25, command = right)
        self.right.pack()
        self.left = tk.Button(self.frame, text = 'Left', width = 25, command = left)
        self.left.pack()
        self.kill = tk.Button(self.frame, text = 'Kill', width = 25, command = self.kill)
        self.kill.pack()
    def kill(self): 
        root.destroy()
main()

编辑:我添加了我的代码,这样你就可以自己运行了。情节相当大,但改变figsize不允许我让它覆盖整个画布


Tags: theselfmastersourcetargetoutputreturndef
2条回答

在方法makewidg中添加fig.subplots_adjust(left=0, right=1, top=1, bottom=0)代替fig.tight_layout(),这样会将所有边距压缩为零。它会将轴标签等推到视图之外,因此您可以使用接近0和1的数字以较小的边距重新添加

您可以使用绘图控件根据自己的喜好调整边距,然后在脚本中使用这些数字,只要它看起来符合您的需要: matplotlib margin adjustment dialog

我添加了一行:self.canvas.figure.tight_layout()def makewidg(self):,如下所示:

class Lower:
def __init__(self, master):
    self.master = master
    self.frame = tk.Frame(self.master).pack()
    self.displayimg = tk.Button(self.frame, text = 'Display', width = 25, command = self.plot)
    self.displayimg.pack()
    self.makewidg()
def makewidg(self):
    fig = plt.figure(figsize=(100,100), frameon=False)  #changing figsize doesnt cange the size of the plot display
    fig.tight_layout()
    self.ax = fig.add_subplot(111)
    self.ax.set_yticklabels([])
    self.ax.set_xticklabels([])
    self.canvas = FigureCanvasTkAgg(fig, master=self.master)
    self.canvas.get_tk_widget().pack(expand=True)
    self.canvas.figure.tight_layout()
    self.canvas.draw()
    self.new_window()
def new_window(self):
    self.newWindow = tk.Toplevel()
    self.app = Display(self.newWindow)
def plot(self):
    global xtmi, xtma, xs, ytmi, ytma, ys, i
    target,source,output=initialize(xs,ys)
    trap(xtmi,xtma,xs,ytmi,ytma,ys,target)
    output = GS(target,source)
    self.ax.imshow(output, cmap='gray')
    self.ax.set_yticklabels([])
    self.ax.set_xticklabels([])
    self.canvas.draw()
    self.ax.clear()

def kill(self):
    root.destroy()

你能核实一下这是否解决了你的问题吗

相关问题 更多 >