【问题标题】:How to load image in ttk notebook with Python3如何使用 Python3 在 ttk 笔记本中加载图像
【发布时间】:2016-03-10 10:47:03
【问题描述】:

使用 lm-fit 包,我可以将各种数据放入笔记本中。 然而,我无法在笔记本选项卡上获得图表。

我已经剥离了大部分代码,所以这是一个小例子。: 我在 Ubuntu 14.04LTS 下的 linux 机器上运行 Python 3 和 ttk。

点击两次运行按钮后,我的 Python 窗口中出现以下错误消息:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.4/tkinter/__init__.py", line 1536, in __call__
    return self.func(*args)
  File "/home/peterk/python3_files/demo_noytebook4.py", line 59, in <lambda>
    command=lambda uu=run4Var: self._run4(uu))
  File "/home/peterk/python3_files/demo_noytebook4.py", line 101, in _run4
    im = Image.open('based_on_'+method_pk+'.svg')
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2028, in open
    raise IOError("cannot identify image file")
OSError: cannot identify image file

代码如下:

# -*- coding: utf-8 -*-
"""
Created on Sat Jan 16 18:56:16 2016

"""
from __future__ import print_function



import numpy as np

import matplotlib 
from matplotlib import pyplot as plt

from tkinter import *
import tkinter as tk
from PIL import ImageTk, Image
import tkinter.font as tkFont
import tkinter.ttk as ttk
from tkinter import filedialog



class CreepNotebook(ttk.Frame):

    def __init__(self, isapp=True, name='notebookdemo'):
        ttk.Frame.__init__(self, name=name)
        self.pack(expand=True, fill="both")
        self.master.title('Creep fit')
        self.isapp = isapp
        self._create_widgets()
        self.master.minsize(1920,1000)
    def _create_widgets(self):      
        self._create_main_panel()         
    def _create_main_panel(self):
        mainPanel = ttk.Frame(self, name='demo')
        mainPanel.pack( expand=True, side="top", fill="both")                 
        # create the notebook
        nb = ttk.Notebook(mainPanel, name='notebook')
        # extend bindings to top level window allowing
        #   CTRL+TAB - cycles thru tabs
        #   SHIFT+CTRL+TAB - previous tab
        #   ALT+K - select tab using mnemonic (K = underlined letter)
        nb.enable_traversal()
        nb.pack(fill="both", padx=2, pady=3,expand=True)

        self._create_graph_tab(nb)                      

#============================================================================== 

# =============================================================================
    def _create_graph_tab(self, nb):
        # populate the third frame with a text widget
        frame = ttk.Frame(nb, name="graphs")
#        frame.grid(column=0, row=0, rowspan=4, columnspan=5,sticky=(N,S,E,W))
        lbl6=ttk.Label(frame, text='Plot the fits and save them to .jpg')      
        run4Var = tk.StringVar
        btn6 = ttk.Button(frame, text='Run', underline=0,
                         command=lambda uu=run4Var: self._run4(uu))
        btn6l = ttk.Label(frame, textvariable=run4Var, name='run4')
        btn7 = ttk.Button(frame, text="Quit",underline=0,
                            command=nb.destroy)
        canvas = Canvas(frame, width=400, height=300)
        canvas.pack()
        lbl6.pack()
        btn6.pack()
        btn6l.pack()
        btn7.pack()
        nb.add(frame, text='Graphs', underline=0, padding=2)

    def _run4(self, uu):        
        global canvas
        global im
        method_pk='lbg'
        f1, axarr = plt.subplots(2, 3)
        f1.suptitle("tiltle all "+method_pk )
        rows_4=5        
        time2=np.array([1,2,3,4,5,6,7,8,9,10])
        color1=['red', 'green','blue','cyan', 'black']
        for i in range(0,rows_4+1):
             for j in range(0,rows_4):
                 if i < 3:
                     axarr[0,i].semilogx(time2, time2*j, color=color1[j], linestyle='solid')
                     axarr[0, i].semilogx(time2,time2*(j+1), color=color1[j], linestyle='dotted')
                     axarr[0, i].set_title('curve'+str(i+1))
                 else:
                     axarr[1,i-3].semilogx(time2, time2*j, color=color1[j], linestyle='solid')
                     axarr[1, i-3].semilogx(time2, time2*(j+1), color=color1[j], linestyle='dotted')            
                     if i==rows_4:
                        axarr[1, i-3].set_title( ' all curves')
                     else:
                        axarr[1, i-3].set_title('curve'+str(i+1))
         # Fine-tune figure; hide x ticks for top plots and y ticks for right plots
        plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False)
        plt.setp([a.get_yticklabels() for a in axarr[0, :]],fontsize=6)
        plt.setp([a.get_yticklabels() for a in axarr[1, :]],fontsize=6)
        plt.setp([a.get_xticklabels() for a in axarr[1, :]], fontsize=6, rotation='vertical')
        plt.savefig('based_on_'+method_pk+'.svg')

    # Load the image file
        im = Image.open('based_on_'+method_pk+'.svg')
# Put the image into a canvas compatible class, and stick in an
# arbitrary variable to the garbage collector doesn't destroy it
        canvas.image = ImageTk.PhotoImage(im)
# Add the image to the canvas, and set the anchor to the top left / north west corner
        canvas.create_image(0, 0, image=canvas.image, anchor='nw')
#============================================================================
if __name__ == '__main__':
    app = CreepNotebook()
    app.mainloop()

【问题讨论】:

  • 您检查过 PIL.Image 是否支持 SVG 格式吗?您可能应该使用其他格式保存或使用 matplotlib 提供的小部件,请参阅for example
  • 谢谢,你是对的,当我选择 eps 格式时,我不再收到该错误消息,但我无法在笔记本选项卡的画布上显示图表。我的印象是它要么与主页的扩展有关,要么与按钮函数 lambda 链接到字符串而不是图像的事实有关。

标签: python-3.x tkinter ttk


【解决方案1】:

将画布放入变量 self 就可以了,请参见下面的代码

    # -*- coding: utf-8 -*-
"""
Created on Sat Jan 16 18:56:16 2016

"""
from __future__ import print_function



import numpy as np

import matplotlib 
matplotlib.use('TkAgg')
from matplotlib import pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import sys
from tkinter import *
import tkinter as tk
from PIL import ImageTk, Image
import tkinter.font as tkFont
import tkinter.ttk as ttk
from tkinter import filedialog



class CreepNotebook(ttk.Frame):

    def __init__(self, isapp=True, name='notebookdemo'):
        ttk.Frame.__init__(self, name=name)
        self.pack(expand=True, fill="both")
        self.master.title('Creep fit')
        self.isapp = isapp
        self._create_widgets()
#        self.master.minsize(1920,1000)
        self.master.minsize(1920,1000)
    def _create_widgets(self):      
        self._create_main_panel()         
    def _create_main_panel(self):
        mainPanel = ttk.Frame(self, name='demo')
        mainPanel.pack( expand=True, side="top", fill="both") 
#        mainPanel.pack( expand=True, side="top")                          
        # create the notebook
        nb = ttk.Notebook(mainPanel, name='notebook')
        # extend bindings to top level window allowing
        #   CTRL+TAB - cycles thru tabs
        #   SHIFT+CTRL+TAB - previous tab
        #   ALT+K - select tab using mnemonic (K = underlined letter)
        nb.enable_traversal()
        nb.pack(fill="both", padx=2, pady=3,expand=True)

        self._create_graph_tab(nb)                      

#============================================================================== 

# =============================================================================
    def _create_graph_tab(self, nb):
        # populate the third frame with a text widget
        frame = ttk.Frame(nb, name="graphs")
#        frame.grid(column=0, row=0, rowspan=4, columnspan=5,sticky=(N,S,E,W))
        lbl6=ttk.Label(frame, text='Plot the fits and save them to .eps')      
        run4Var = tk.StringVar
        btn6 = ttk.Button(frame, text='Run', underline=0,
                         command=lambda uu=run4Var: self._run4(uu,frame))
        btn6l = ttk.Label(frame, textvariable=run4Var, name='run4')
#        btn7 = ttk.Button(frame, text="Quit",underline=0,
#                            command=sys.exit)
#        canvas = Canvas(frame, width=400, height=300)
#        canvas.pack()
        f1=Figure(figsize=(5,4), dpi=100)
        self.canvas=FigureCanvasTkAgg(f1,master=frame)
#        self.canvas.show()
#        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
#        self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        lbl6.pack()
        btn6.pack()
        btn6l.pack()
#        btn7.pack()
        nb.add(frame, text='Graphs', underline=0, padding=2)
    def destroy(e): sys.exit()    
    def _run4(self, uu,frame):  

#==============================================================================
#         global canvas
#         global im
#         global f1
         method_pk='lbg'
         f1, axarr = plt.subplots(2, 3)
         f1.suptitle("tiltle all "+method_pk )
         rows_4=5        
         time2=np.array([1,2,3,4,5,6,7,8,9,10])
         color1=['red', 'green','blue','cyan', 'black']
         for i in range(0,rows_4+1):
              for j in range(0,rows_4):
                  if i < 3:
                      axarr[0,i].semilogx(time2, time2*(j+1), color=color1[j], linestyle='solid')
                      axarr[0, i].semilogx(time2,time2*(j+1.1), color=color1[j], linestyle='dashed')
                      axarr[0, i].set_title('curve'+str(i+1))
                  else:
                      axarr[1,i-3].semilogx(time2, time2*(j+1), color=color1[j], linestyle='solid')
                      axarr[1, i-3].semilogx(time2, time2*(j+1.1), color=color1[j], linestyle='dashed')            
                      if i==rows_4:
                         axarr[1, i-3].set_title( ' all curves')
                      else:
                         axarr[1, i-3].set_title('curve'+str(i+1))
          # Fine-tune figure; hide x ticks for top plots and y ticks for right plots
         plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False)
         plt.setp([a.get_yticklabels() for a in axarr[0, :]],fontsize=6)
         plt.setp([a.get_yticklabels() for a in axarr[1, :]],fontsize=6)
         plt.setp([a.get_xticklabels() for a in axarr[1, :]], fontsize=6, rotation='vertical')
         plt.savefig('based_on_'+method_pk+'.eps', format='eps', dpi=1000)
         self.canvas=FigureCanvasTkAgg(f1,master=frame)
         self.canvas.show()
         self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
         self.toolbar = NavigationToolbar2TkAgg( self.canvas,frame)
         toolbar.update()
         self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)        
#==============================================================================
         self.update()
    # Load the image file
#        im = Image.open('based_on_'+method_pk+'.eps')
# Put the image into a canvas compatible class, and stick in an
# arbitrary variable to the garbage collector doesn't destroy it
#        canvas.image = ImageTk.PhotoImage(im)
# Add the image to the canvas, and set the anchor to the top left / north west corner
#        canvas.create_image(0, 0, image=canvas.image, anchor='nw')
#============================================================================
if __name__ == '__main__':
    app = CreepNotebook()
    app.mainloop()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 2022-06-23
    • 2020-11-27
    • 2018-08-19
    相关资源
    最近更新 更多