Home > OS >  Import class into another file's class to print in a textbox?
Import class into another file's class to print in a textbox?

Time:01-14

WHAT DO I WANT TO GET? If the condition of the second.py file is true then "ok" will be printed in the textbox of the main.py file. If the confition is False, then "No" will be printed in the same textbox.

main.py is a file that is opened by the Home.py file. So initially there is the Home.py file which opens the main.py file inside it. The main.py file executes the second.py file. I only posted the main and second file, because the main file opens correctly in the home file

Home.py > main.py > second.py

In the main.py file I have a textobox and a button. To be precise, they are both in a class of the main file, but in the code I carry only the minimum necessary for the example.By clicking on the button, I would like to import the code located in another class of another file (second.py file). The code of the secondary.py file is used to generate text (with conditions) to be printed in the textobox of the main.py file. It's a simple case, but something is wrong.

The error is:

TypeError: __init__() missing 1 required positional argument: 'master'

Main.py

from tkinter import *
from tkinter import ttk
import tkinter as tk


class Home(tk.Frame): #update
    def __init__(self, master): #update
        super().__init__(master, **kw) #update

        #class import from other file
        from Folder.Folder2 import second
        k = second.Print

        #i want to print the output here  
        self.textobox = tk.Text(master, width=33, height=10, font=('helvetic', 12))
        self.textobox.place(x=30, y=40)

        self.button = Button(master, text="Ok", command= lambda: [one_function(), two_function()])
        self.button.pack()

second.py

import sqlite3
    
class Print:
    def __init__(self, master, **kw):
        super().__init__(master, **kw)
    
    
        self.conn = sqlite3.connect('...')
        self.cursor = conn.cursor()
    
        self.cursor.execute('SELECT x, y FROM Table')
        self.element = cursor.fetchone()
         
        self.cursor.execute("SELECT day FROM quantity")
        self.day = cursor.fetchone()

        #condition to print text in the textbox of the main.py file    
        if self.day == "Monday" and (self.element[0]) >= (self.element[1]):
            textobox.insert(tk.END, "ok")
    
        else:
            textobox.insert(tk.END, "no")

The database is very simple:

CREATE TABLE "Table" (
    "id"    INTEGER,
    "x" INTEGER, #for example 23
    "y" INTEGER, #for example 12
    PRIMARY KEY("id")
);


CREATE TABLE "quantity" (
    "id"    INTEGER,
    "day"   INTEGER, #for example Monday
    PRIMARY KEY("id")
);

CodePudding user response:

There are many typos in second.py:

  • conn.cursor() should be self.conn.cursor()
  • cursor.execute(...) should be self.cursor.execute(...)

Other than typos:

  • super().__init__(...) should not be called
  • Table is a keyword in SQLite3, so if it is used as table name, you need to put it inside quotes, e.g. "Table". Suggest to use another name instead.
  • textobox is undefined (it is an instance variable inside Home class in main.py
  • tk.END is undefined
  • master and **kw arguments are not necessary as it is not used
  • self.day is either a tuple (if record returned) or None

Also Suggest to pass self.textobox in Home class to Print class instead.

Below is a modified second.py:

import sqlite3

class Print:
    def __init__(self, textbox):  # added textbox argument

        self.conn = sqlite3.connect('...')
        self.cursor = self.conn.cursor()

        self.cursor.execute('SELECT x, y FROM "Table"')
        self.element = self.cursor.fetchone()

        self.cursor.execute("SELECT day FROM quantity")
        self.day = self.cursor.fetchone()

        #condition to print text in the textbox of the main.py file
        if (self.day and self.day[0] == "Monday") and (self.element and self.element[0] >= self.element[1]):
            textbox.insert("end", "ok")
        else:
            textbox.insert("end", "no")

For main.py:

  • super().__init__() should not be called as well
  • k = second.Print should be k = second.Print(...) and it should be called after self.textobox() is created
  • one_function() and two_function() are undefined. (Are they defined elsewhere?)

Below is the modified main.py:

import tkinter as tk
from Folder.Folder2 import second

class Home:
    def __init__(self, master):

        #i want to print the output here
        self.textobox = tk.Text(master, width=33, height=10, font=('helvetic', 12))
        self.textobox.place(x=30, y=40)

        self.button = tk.Button(master, text="Ok", command= lambda: [one_function(), two_function()])
        self.button.pack()

        k = second.Print(self.textobox) # pass self.textobox to Print class

main = tk.Tk()
main.geometry("400x300")
my_gui = Home(main)
main.mainloop()

Note that it is bad practice to import module as below:

from tkinter import *
import tkinter as tk

because wildcard import is not recommended and tkinter module has been import twice. Use the second import is recommended.


Updated main.py based on changes in question:

import tkinter as tk
from Folder.Folder2 import second

class Home(tk.Frame):
    def __init__(self, master, **kw):
        super().__init__(master, **kw)

        #i want to print the output here
        self.textobox = tk.Text(self, width=33, height=10, font=('helvetic', 12))
        self.textobox.place(x=30, y=40)

        self.button = tk.Button(self, text="Ok", command= lambda: [one_function(), two_function()])
        self.button.pack()

        k = second.Print(self.textobox)

main = tk.Tk()
main.geometry("400x300")
my_gui = Home(main)
my_gui.pack(fill="both", expand=1)
main.mainloop()

Note that I have used self instead of master when creating the button and the textbox.

  •  Tags:  
  • Related