【问题标题】:How can I get a plot to cover an entire Tkinter canvas? [duplicate]如何获得覆盖整个 Tkinter 画布的绘图? [复制]
【发布时间】:2020-02-13 22:37:31
【问题描述】:

我有一个 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 并不能让它覆盖整个画布

【问题讨论】:

  • 你能提供一个最小的工作示例吗?
  • 抱歉,已经提供了我写的出现问题的类
  • 我们越来越近了,但最小的工作示例是一个和平的代码,我可以从这里复制并在我自己的 IDE 上运行,即。它是可重现的。您能否提供更多代码,以便我们尝试一下?
  • 对不起,我已经添加了我的工作代码,以便您可以复制粘贴并运行。
  • 谢谢,我贴了一个答案,希望对你有帮助。

标签: python python-3.x tkinter tkinter-canvas


【解决方案1】:

我添加了以下行: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()

您能否验证一下这是否解决了您的问题?

【讨论】:

  • 您的解决方案使情节变大,但对我来说,屏幕左右两侧仍有一大块空白。不过谢谢
  • 是的,因为一旦画布到达上下边界,它就会停止横向扩展。
【解决方案2】:

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

您可以使用绘图控件根据自己的喜好调整页边距,然后在脚本看起来像您想要的方式时使用这些数字:

【讨论】:

    猜你喜欢
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多