-2

I am creating a GUI with Python's tkinter. I have encountered an issue while trying to place an image read by OpenCV onto a tkinter canvas.

The error is as follows:

AttributeError: 'NoneType' object has no attribute 'create_image'

I am working with two files, features_ex.py and main.py, using classes, and it seems the issue lies with the class. This is because everything works fine when working within a single file.

features_ex.py:

  from tkinter import *
  from tkinter import Canvas
  from tkinter import Button
  from tkinter import ALL
  from tkinter import filedialog
  import os
  import sys
  import cv2 as cv
  import tkinter as tk
  from PIL import ImageTk
  from PIL import Image    

  class features():

      def __init__(self, root) :
          self.path = ''
          self.root = root 
          self.canvas = ''


      def LoadImage(self): 
          self.path = filedialog.askopenfilename()
          print(self.path)
          self.origin=cv.imread(str(self.path), cv.COLOR_BGR2RGB)
          self.origin = cv.resize(self.origin, (500, 500))
          features.show_image(self)
        

      def Canvas(self):
          self.canvas = Canvas(self.root, width=500, height=500, bg='gray91', border=1.25, relief='solid')
          self.canvas.pack(anchor='nw')

      def btn(self):
          self.btn = Button(self.root, text='Load', font='SimSun 15', border=1.25, command=lambda:features.LoadImage(self))
          self.btn.place(relx=0.015, rely=0.75)

      def show_image(self):
          print(str(self.path))
          self.img = Image.fromarray(self.origin)
          self.img = ImageTk.PhotoImage(image=self.img)
          self.canvas.create_image(0, 0, image=self.img, anchor='nw' )
    

main_ex.py:

from tkinter import *
from Features_ex import * 


class app:   
    def __init__ (self, interactive = False):

        ### Title Bar
        self.root=Tk() 
        self.root.title("Example")
        self.root.geometry('1280x720')
        self.root.resizable(1,1)

        ### Create button
        self.btn_load = features.btn(self)
        self.canvas = features.Canvas(self)

        self.root.mainloop()

if __name__ == '__main__' :
    app()

`

I researched the error and most sources point out issues with Canvas.pack(), suggesting to modify it as below.

self.canvas = Canvas()
self.canvas.pack()

However, I already meet this condition. So, I am unsure what the cause is. The error occurs with images in .jpg, .png, and .jpeg formats.

My versions are:

Python 3.11.8
Windows 11
Visual Studio Code

9
  • 1
    Please provide code that reproduces the error. This throws "self is not defined." Commented May 29, 2024 at 13:01
  • @matszwecja Sorry, it's because I am using a class. I will update and post the corrected version. Commented May 29, 2024 at 13:03
  • Please still edit to provide the full traceback. Also, What did you search for, and what did you find? What did you try, and how did it fail? This seems like yet another duplicate of stackoverflow.com/questions/8949252/… Please review the help center and in particular How to ask as well as the guidance for providing a minimal reproducible example. Commented May 29, 2024 at 13:20
  • @tripleee Got it, sorry for the delay in making the corrections. It should work now. I corrected " self.canvas = Canvas().place() " to "self.canvas = Canvas()" and "self.canvas.pack()", but the same error persists. Additionally, I tried loading the image without using OpenCV, but the same error occurs. Commented May 29, 2024 at 13:23
  • Ignoring the fact that you are misusing how classes work in python, image=self.img should be image=self.img_. Also add return self.canvas to the end of the Canvas method Commented May 29, 2024 at 13:31

1 Answer 1

0

I have encountered an issue while trying to place an image read by OpenCV onto a tkinter canvas

Your problem can be fixed.

In features_ex.py

Comment out self.canvas = '':

def __init__(self, root) :
    :
    : 
    #self.canvas = ''

In main_ex.py

You don't need to assign variables. Just called functions.

Change this:

### Create button
self.btn_load = features.btn(self)
self.canvas = features.Canvas(self)

To:

### Create button
features.btn(self)
features.Canvas(self)

Screenshot:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.