Tkinter 中 Matplotlib 图的滚动条 [英] Scrollbars for Matplotlib Figure in Tkinter

查看:120
本文介绍了Tkinter 中 Matplotlib 图的滚动条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使滚动条在 Matplotlib 图形的 Tkinter 中工作.滚动条无法适应加载图像的宽度和高度,我也不知道如何解决此问题.任何帮助将不胜感激.

I am trying to get scrollbars to work in Tkinter for matplotlib figures. The scrollbars don't adjust to the width and height of the loaded image and I don't know how to troubleshoot this. Any help would be appreciated.

图片:

最终结果:

代码:

import os

from PIL import Image

import tkinter as tk
from tkinter import ttk, filedialog

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

import numpy as np

from functools import partial

class AutoScrollbar(ttk.Scrollbar):

    def __init__(self,
                 parent,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent

        super().__init__(self.parent,
                         *args,
                         **kwargs)

    def set(self,
            low,
            high):
        '''
        '''
        if float(low) <= 0.0 and float(high) >= 1.0:
            self.tk.call('grid',
                         'remove',
                         self)
        else:
            self.grid()
        ttk.Scrollbar.set(self,
                          low,
                          high)

class DoubleScrollbarFrame(ttk.Frame):

    def __init__(self,
                 parent,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent

        super().__init__(self.parent,
                         *args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.canvas = tk.Canvas(self)
        self.frame = ttk.Frame(self.canvas)
        self.scroll_x = AutoScrollbar(self,
                                      orient = tk.HORIZONTAL)
        self.scroll_y = AutoScrollbar(self,
                                      orient = tk.VERTICAL)
        self.sizegrip = ttk.Sizegrip(self)
        
        self.canvas.config(xscrollcommand = self.scroll_x.set,
                           yscrollcommand = self.scroll_y.set)
        self.scroll_x.config(command = self.canvas.xview)
        self.scroll_y.config(command = self.canvas.yview)
        
        self.canvas.create_window((0,0),
                                  window = self.frame,
                                  anchor = 'nw')
        
        self.frame.bind('<Configure>',
                        self.set_scrollregion)

    def position_widgets(self,
                         **kwargs):
        '''
        '''
        self.scroll_x.grid(row = 1,
                           column = 0,
                           sticky = 'ew')

        self.scroll_y.grid(row = 0,
                           column = 1,
                           sticky = 'ns')

        self.canvas.grid(row = 0,
                         column = 0,
                         sticky = 'nsew')

        self.sizegrip.grid(row = 1,
                           column = 1,
                           sticky = 'se')

        #NOTE: Do not use geometry manager with `self.frame`. This will
        # pass control from the canvas to grid and the canvas will then
        # no longer know how much to grow.
        
    def set_scrollregion(self,
                         event):
        '''
        '''
        self.canvas.configure(scrollregion = self.canvas.bbox('all'))

class Graph(ttk.Frame):

    def __init__(self,
                 parent,
                 axis_off = True,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent
        self.axis_off = axis_off

        super().__init__(self.parent,
                         *args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.graph_container = DoubleScrollbarFrame(self)
        
        self.figure = plt.figure()
        self.figure.subplots_adjust(top = 1,
                                    right = 1,
                                    left= 0,
                                    bottom = 0,
                                    wspace = 0,
                                    hspace = 0)
            
        self.axis = self.figure.add_subplot(1,1,1)

        if self.axis_off:
            self.axis.set_axis_off()

        self.mpl_canvas = FigureCanvasTkAgg(self.figure,
                                            self.graph_container.frame)

        self.toolbar_frame = ttk.Frame(self)

        self.toolbar = NavigationToolbar2Tk(self.mpl_canvas,
                                            self.toolbar_frame)
        
    def position_widgets(self):
        '''
        '''
        self.toolbar.update()
        self.toolbar_frame.grid(row = 1,
                                column = 0,
                                sticky = 'sew')

        self.mpl_canvas.draw()
        self.mpl_canvas.get_tk_widget().grid(row = 0,
                                             column = 0,
                                             sticky = 'nsew')

        self.graph_container.grid(row = 0,
                                  column = 0,
                                  sticky = 'nsew')

    def load_image(self,
                   path):
        '''
        '''
        self.mpl_canvas.flush_events()
        self.axis.clear()
        
        self.image = Image.open(path)

        #NOTE: Dots per inch (dpi) in matplotlib should be used for
        # printing to paper media only. dpi is set at the time of
        # printing/scanning. Computer screen resolution is fixed by
        # the screen hardware and given in pixels per inch (ppi).
        # An image scanned at higher dpi will appear crisper on a
        # computer screen because of the difference in halftone/
        # dithering at each pixel, but the total size and number of
        # pixels in the image will be the same.
        # Matplotlib use 72 pixels per inch (ppi) for its figures by
        # default, and this cannot be changed. Thus, if you increase
        # dots per inch (dpi), the figure will appear bigger when
        # printed to screen (i.e. on the computer monitor) because
        # it will use more pixels to represent the same features.
        # When printed to paper media, however, the image will be
        # the same size regardless of dpi, but have finer halftoning/
        # dithering for an improved appearance.
        # Matplotlib sets sizes in terms of inches, so the scan dpi
        # must be known in order to get the physical size of the
        # image.
        if self.image.info.get('dpi'):
            self.scan_dpi, _ = self.image.info['dpi']
        else:
            self.scan_dpi = 100
        self.w_pel, self.h_pel = self.image.size

        self.graph_w_in = self.w_pel / self.scan_dpi
        self.graph_h_in = self.h_pel / self.scan_dpi
        self.graph_aspect_ratio = self.graph_h_in / self.graph_w_in

        self.zoom = 1
        
        self.figure.set_size_inches(self.graph_w_in * self.zoom,
                                    self.graph_h_in * self.zoom)
        
        self.image = np.array(self.image)
        
        self.axis.imshow(self.image)

        self.mpl_canvas.draw()

class FileBrowser(tk.Frame):

    def __init__(self,
                 parent,
                 path_type = 'file',
                 label_text = '',
                 file_types = (('*','All File Types...'),),
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent
        self.path_type = path_type
        self.label_text = label_text
        self.file_types = file_types
        
        super().__init__(parent,
                         *args,
                         **kwargs)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.label = tk.Label(self.parent,
                              text = self.label_text)

        self.path_entry = tk.Entry(self.parent,
                                   width = 50)

        self.button = ttk.Button(self.parent,
                                 text = 'Browse...',
                                 command = partial(self.open_file_dialog,
                                                   self.path_type,
                                                   self.file_types))

    def position_widgets(self):
        '''
        '''
        opts = {'padx': (5,5),
                'pady': (5,5)}
        
        self.label.grid(row = 0,
                        column = 0,
                        sticky = 'e',
                        **opts)
        self.path_entry.grid(row = 0,
                             column = 1,
                             sticky = 'w',
                             **opts)
        self.button.grid(row = 0,
                         column = 2,
                         sticky = 'w',
                         **opts)

    def open_file_dialog(self,
                         path_type,
                         file_types):
        '''
        '''
        init_dir = os.getcwd()

        if path_type == 'file':
             self.path = filedialog.askopenfilename(initialdir = init_dir,
                                                    title = 'Select file...',
                                                    filetypes = file_types)
        elif path_type == 'directory':
            self.path = filedialog.askdirectory(initialdir = init_dir,
                                                title = 'Select directory...')

        self.path_entry.delete(0,tk.END)
        self.path_entry.insert(0,self.path)

    def get_path(self):
        '''
        '''
        return self.path_entry.get()

class Loader(ttk.Frame):
    '''
    '''
    def __init__(self,
                 parent,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent

        super().__init__(self.parent,
                         *args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.input_label_frame = ttk.LabelFrame(self,
                                                text = 'Input')
        self.output_label_frame = ttk.LabelFrame(self,
                                                 text = 'Output')
        
        self.create_file_browser(self.input_label_frame)
        self.create_ok_button(self.input_label_frame)

        self.create_output_window(self.output_label_frame)

    def create_file_browser(self,
                            label_frame):
        '''
        '''
        self.browser_frame = ttk.LabelFrame(label_frame,
                                            text = 'Select File')
        self.file_browser = FileBrowser(self.browser_frame,
                                        path_type = 'file',
                                        label_text = 'File:',
                                        file_types = (('*.tif', 'TIF'),
                                                      ('*.png', 'PNG'),))

    def create_ok_button(self,
                         label_frame):
        '''
        '''
        self.input_ok_button = ttk.Button(label_frame,
                                          text = 'OK',
                                          command = self.calibrate)

    def calibrate(self):
        '''
        '''
        path = self.file_browser.get_path()

        if path == '':
            messagebox.showerror(title = 'No File Selected',
                                 message = 'No file chosen. Please select file.')
            return

        _, ext = os.path.splitext(path)

        if ext.lower() not in ('.tif', '.png'):
            messagebox.showerror(title = 'File Is Not \"*.tif\" or \"*.png\"',
                                 message = 'File must be a \"*.tif\" or \"*.png\" image file. Please reselect file and try again.')

        img = plt.imread(path)

        self.graph.load_image(path)
        
    def create_output_window(self,
                             label_frame):
        '''
        '''
        self.output_frame = ttk.Frame(label_frame)
        self.graph = Graph(self.output_frame)

    def position_widgets(self,
                         **kwargs):
        '''
        '''
        #OK Button
        self.input_ok_button.grid(row = 4,
                                  column = 0,
                                  sticky = 'e')
        
        #Frames
        self.input_label_frame.grid(row = 0,
                                    column = 0,
                                    sticky = 'nsew')
        
        self.browser_frame.grid(row = 1,
                                column = 0,
                                sticky = 'nw')

        self.file_browser.grid(row = 0,
                               column = 0,
                               sticky = 'nsew')

        self.output_label_frame.grid(row = 0,
                                     column = 1,
                                     sticky = 'nw')

        self.graph.grid(row = 0,
                        column = 0,
                        sticky = 'nsew')

        self.output_frame.grid(row = 0,
                               column = 0,
                               sticky = 'nsew')


class MainApp(tk.Tk):

    def __init__(self,
                 title,
                 *args,
                 **kwargs):
        '''
        '''
        self._title = title

        super().__init__(*args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        #Set window title
        self.title(self._title)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.loader = Loader(self)

    def position_widgets(self):
        '''
        '''
        self.loader.grid(row = 0,
                         column = 0,
                         sticky = 'nsew')

if __name__ == '__main__':

    #Create GUI
    root = MainApp('MainApp')

    #Run program
    root.mainloop()

推荐答案

matplotlib 图形是画布.因此,它的容器框架将无法调整大小,并且 bbox("all")将不起作用.相反,我们必须更新 matplotlib canvas 大小以匹配 figure 大小和顶层 canvas 滚动区域 figure 大小.

matplotlib figures are canvases. Therfore, its container frame won't resize to it, and bbox("all") won't work. Instead, we have to update the matplotlib canvas size to match the figure size and the toplevel canvas scrollregion to the figure size.

这是工作输出.

工作输出

这是工作代码.

代码

import os

from PIL import Image

import tkinter as tk
from tkinter import ttk, filedialog

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk

import numpy as np

from functools import partial

#Matplotlib Default DPI
DEFAULT_DPI = 100

#Matplotlib Default PPI
DEFAULT_PPI = 72

class AutoScrollbar(ttk.Scrollbar):

    def __init__(self,
                 parent,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent

        super().__init__(self.parent,
                         *args,
                         **kwargs)

    def set(self,
            low,
            high):
        '''
        '''
        if float(low) <= 0.0 and float(high) >= 1.0:
            self.tk.call('grid',
                         'remove',
                         self)
        else:
            self.grid()
        ttk.Scrollbar.set(self,
                          low,
                          high)

class DoubleScrollbarFrame(ttk.Frame):

    def __init__(self,
                 parent,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent

        super().__init__(self.parent,
                         *args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.canvas = tk.Canvas(self)
        self.frame = ttk.Frame(self.canvas)
        self.scroll_x = AutoScrollbar(self,
                                      orient = tk.HORIZONTAL)
        self.scroll_y = AutoScrollbar(self,
                                      orient = tk.VERTICAL)
        self.sizegrip = ttk.Sizegrip(self)
        
        self.canvas.config(xscrollcommand = self.scroll_x.set,
                           yscrollcommand = self.scroll_y.set)
        self.scroll_x.config(command = self.canvas.xview)
        self.scroll_y.config(command = self.canvas.yview)
        
        self.canvas.create_window((0,0),
                                  window = self.frame,
                                  anchor = 'nw')
        
        self.frame.bind('<Configure>',
                        self.set_scrollregion)

    def position_widgets(self,
                         **kwargs):
        '''
        '''
        self.scroll_x.grid(row = 1,
                           column = 0,
                           sticky = 'ew')

        self.scroll_y.grid(row = 0,
                           column = 1,
                           sticky = 'ns')

        self.canvas.grid(row = 0,
                         column = 0,
                         sticky = 'nsew')

        self.sizegrip.grid(row = 1,
                           column = 1,
                           sticky = 'se')

        #NOTE: Do not use geometry manager with `self.frame`. This will
        # pass control from the canvas to grid and the canvas will then
        # no longer know how much to grow.
        
    def set_scrollregion(self,
                         event):
        '''
        '''
        self.canvas.configure(scrollregion = self.canvas.bbox('all'))

class Graph(ttk.Frame):

    def __init__(self,
                 parent,
                 axis_off = True,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent
        self.axis_off = axis_off

        super().__init__(self.parent,
                         *args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.figure = plt.figure()
        self.figure.subplots_adjust(top = 1,
                                    right = 1,
                                    left= 0,
                                    bottom = 0,
                                    wspace = 0,
                                    hspace = 0)
            
        self.axis = self.figure.add_subplot(1,1,1)

        if self.axis_off:
            self.axis.set_axis_off()

        self.canvas = tk.Canvas(self)
        self.frame = ttk.Frame(self.canvas)

        self.mpl_canvas = FigureCanvasTkAgg(self.figure,
                                            self.frame)

        self.mpl_canvas.draw()

        self.scroll_x = AutoScrollbar(self,
                                      orient = tk.HORIZONTAL)
        self.scroll_y = AutoScrollbar(self,
                                      orient = tk.VERTICAL)
        self.sizegrip = ttk.Sizegrip(self)
        
        self.canvas.config(xscrollcommand = self.scroll_x.set,
                           yscrollcommand = self.scroll_y.set)
        self.scroll_x.config(command = self.canvas.xview)
        self.scroll_y.config(command = self.canvas.yview)
        
        self.cwid = self.canvas.create_window((0,0),
                                              window = self.frame,
                                              anchor = 'nw')

        self.frame.bind('<Configure>',
                        self.set_scrollregion)

        self.toolbar_frame = ttk.Frame(self)

        self.toolbar = NavigationToolbar2Tk(self.mpl_canvas,
                                            self.toolbar_frame)

    def set_scrollregion(self,
                         event):
        '''
        '''
        w, h = self.figure.get_size_inches()
        w = int(w * DEFAULT_DPI)
        h = int(h * DEFAULT_DPI)
        scrollregion = (0,0,w,h)
        
        self.canvas.configure(scrollregion = scrollregion)
        
    def position_widgets(self):
        '''
        '''
        self.scroll_x.grid(row = 1,
                           column = 0,
                           sticky = 'ew')

        self.scroll_y.grid(row = 0,
                           column = 1,
                           sticky = 'ns')

        self.canvas.grid(row = 0,
                         column = 0,
                         sticky = 'nsew')

        self.mpl_canvas.get_tk_widget().grid(row = 0,
                                             column = 0,
                                             sticky = 'nsew')

        self.sizegrip.grid(row = 1,
                           column = 1,
                           sticky = 'se')

        #NOTE: Do not use geometry manager with `self.frame`. This will
        # pass control from the canvas to grid and the canvas will then
        # no longer know how much to grow.

        self.toolbar.update()
        self.toolbar_frame.grid(row = 2,
                                column = 0,
                                sticky = 'sew')

    def load_image(self,
                   path):
        '''
        '''
        self.mpl_canvas.flush_events()
        self.axis.clear()
        
        self.image = Image.open(path)

        #NOTE: Dots per inch (dpi) in matplotlib should be used for
        # printing to paper media only. dpi is set at the time of
        # printing/scanning. Computer screen resolution is fixed by
        # the screen hardware and given in pixels per inch (ppi).
        # An image scanned at higher dpi will appear crisper on a
        # computer screen because of the difference in halftone/
        # dithering at each pixel, but the total size and number of
        # pixels in the image will be the same.
        # Matplotlib use 72 pixels per inch (ppi) for its figures by
        # default, and this cannot be changed. Thus, if you increase
        # dots per inch (dpi), the figure will appear bigger when
        # printed to screen (i.e. on the computer monitor) because
        # it will use more pixels to represent the same features.
        # When printed to paper media, however, the image will be
        # the same size regardless of dpi, but have finer halftoning/
        # dithering for an improved appearance.
        # Matplotlib sets sizes in terms of inches, so the scan dpi
        # must be known in order to get the physical size of the
        # image.
        if self.image.info.get('dpi'):
            self.scan_dpi, _ = self.image.info['dpi']
        else:
            self.scan_dpi = DEFAULT_DPI # matplotlib default
            
        self.w_pel, self.h_pel = self.image.size

        self.graph_w_in = self.w_pel / self.scan_dpi
        self.graph_h_in = self.h_pel / self.scan_dpi        
        
        self.figure.set_size_inches(self.graph_w_in,
                                    self.graph_h_in)
        
        self.image = np.array(self.image)
        
        self.axis.imshow(self.image)

        self.mpl_canvas.get_tk_widget().configure(
            width = self.graph_w_in * DEFAULT_DPI,
            height = self.graph_h_in * DEFAULT_DPI)
        
        self.mpl_canvas.draw()
        self.canvas.update()

class FileBrowser(tk.Frame):

    def __init__(self,
                 parent,
                 path_type = 'file',
                 label_text = '',
                 file_types = (('*','All File Types...'),),
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent
        self.path_type = path_type
        self.label_text = label_text
        self.file_types = file_types
        
        super().__init__(parent,
                         *args,
                         **kwargs)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.label = tk.Label(self.parent,
                              text = self.label_text)

        self.path_entry = tk.Entry(self.parent,
                                   width = 50)

        self.button = ttk.Button(self.parent,
                                 text = 'Browse...',
                                 command = partial(self.open_file_dialog,
                                                   self.path_type,
                                                   self.file_types))

    def position_widgets(self):
        '''
        '''
        opts = {'padx': (5,5),
                'pady': (5,5)}
        
        self.label.grid(row = 0,
                        column = 0,
                        sticky = 'e',
                        **opts)
        self.path_entry.grid(row = 0,
                             column = 1,
                             sticky = 'w',
                             **opts)
        self.button.grid(row = 0,
                         column = 2,
                         sticky = 'w',
                         **opts)

    def open_file_dialog(self,
                         path_type,
                         file_types):
        '''
        '''
        init_dir = os.getcwd()

        if path_type == 'file':
             self.path = filedialog.askopenfilename(initialdir = init_dir,
                                                    title = 'Select file...',
                                                    filetypes = file_types)
        elif path_type == 'directory':
            self.path = filedialog.askdirectory(initialdir = init_dir,
                                                title = 'Select directory...')

        self.path_entry.delete(0,tk.END)
        self.path_entry.insert(0,self.path)

    def get_path(self):
        '''
        '''
        return self.path_entry.get()

class Loader(ttk.Frame):
    '''
    '''
    def __init__(self,
                 parent,
                 *args,
                 **kwargs):
        '''
        '''
        self.parent = parent

        super().__init__(self.parent,
                         *args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.input_label_frame = ttk.LabelFrame(self,
                                                text = 'Input')
        self.output_label_frame = ttk.LabelFrame(self,
                                                 text = 'Output')
        
        self.create_file_browser(self.input_label_frame)
        self.create_ok_button(self.input_label_frame)

        self.create_output_window(self.output_label_frame)

    def create_file_browser(self,
                            label_frame):
        '''
        '''
        self.browser_frame = ttk.LabelFrame(label_frame,
                                            text = 'Select File')
        self.file_browser = FileBrowser(self.browser_frame,
                                        path_type = 'file',
                                        label_text = 'File:',
                                        file_types = (('*.tif', 'TIF'),
                                                      ('*.png', 'PNG'),))

    def create_ok_button(self,
                         label_frame):
        '''
        '''
        self.input_ok_button = ttk.Button(label_frame,
                                          text = 'OK',
                                          command = self.calibrate)

    def calibrate(self):
        '''
        '''
        path = self.file_browser.get_path()

        if path == '':
            messagebox.showerror(title = 'No File Selected',
                                 message = 'No file chosen. Please select file.')
            return

        _, ext = os.path.splitext(path)

        if ext.lower() not in ('.tif', '.png'):
            messagebox.showerror(title = 'File Is Not \"*.tif\" or \"*.png\"',
                                 message = 'File must be a \"*.tif\" or \"*.png\" image file. Please reselect file and try again.')

        img = plt.imread(path)

        self.graph.load_image(path)
        
    def create_output_window(self,
                             label_frame):
        '''
        '''
        self.output_frame = ttk.Frame(label_frame)
        self.graph = Graph(self.output_frame)

    def position_widgets(self,
                         **kwargs):
        '''
        '''
        #OK Button
        self.input_ok_button.grid(row = 4,
                                  column = 0,
                                  sticky = 'e')
        
        #Frames
        self.input_label_frame.grid(row = 0,
                                    column = 0,
                                    sticky = 'nsew')
        
        self.browser_frame.grid(row = 1,
                                column = 0,
                                sticky = 'nw')

        self.file_browser.grid(row = 0,
                               column = 0,
                               sticky = 'nsew')

        self.output_label_frame.grid(row = 0,
                                     column = 1,
                                     sticky = 'nw')

        self.graph.grid(row = 0,
                        column = 0,
                        sticky = 'nsew')

        self.output_frame.grid(row = 0,
                               column = 0,
                               sticky = 'nsew')


class MainApp(tk.Tk):

    def __init__(self,
                 title,
                 *args,
                 **kwargs):
        '''
        '''
        self._title = title

        super().__init__(*args,
                         **kwargs)

        #Set widgets to fill main window such that they are
        #all the same size
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        #Set window title
        self.title(self._title)

        self.create_widgets()
        self.position_widgets()

    def create_widgets(self):
        '''
        '''
        self.loader = Loader(self)

    def position_widgets(self):
        '''
        '''
        self.loader.grid(row = 0,
                         column = 0,
                         sticky = 'nsew')

if __name__ == '__main__':

    #Create GUI
    root = MainApp('MainApp')

    #Run program
    root.mainloop()

这篇关于Tkinter 中 Matplotlib 图的滚动条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆