Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Importing classes?
#1
I have created 2 python programs. One is a GUI and the other is the fuctions that should be done when a button is pressed in the gui. I got it working by using import XXXX when the button is pressed,seems ok but not pythonic. The teacher asked me to change the code. Can i import the a class to an other file? I am tweaking the code a bit and then i will edit the post to add more details!
Reply
#2
Python style is generally to do all imports at the top of the file. If you do that they are accessible anywhere in the file. I only violate that in two cases: dynamic imports (where you don't know ahead of time what is going to be imported), and if __main__ blocks that need something that isn't needed when the file is imported.

You can import the functions into the file with the GUI, or you can import them both into a third file. The main problem would be if you created an cycle in your imports (foo.py imports bar, when bar.py is trying to import foo).
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Object oriented coding in python is a huge mountain for me.I need to study it a lot more to fully understand it.
GUI.py
import tkinter as tk
from tkinter import messagebox

from sys import exit
import os

class GUI:
    def __init__(self,root):
       
####### Gets the requested values of the height and widht.
        windowWidth = root.winfo_reqwidth()
        windowHeight = root.winfo_reqheight()
        
        # Gets both half the screen width/height and window width/height
        positionRight = int(root.winfo_screenwidth()/2 - windowWidth/2)
        positionDown = int(root.winfo_screenheight()/2 - windowHeight/2)
        # Positions the window in the center of the page.
        root.geometry("+{}+{}".format(positionRight, positionDown))
##########----------------------

        
        root.title("Αρχική είσοδος")
        self.maingui=tk.Frame(root)
        self.maingui.pack()
        self.Label1=tk.Label(self.maingui,text="Καλώς ορίσατε στο βοήθημα γραμμικής άλγεβρας")
        self.Label1.pack()
        self.Label2=tk.Label(self.maingui,text="Παρακαλώ,διάλεξε μία από τις επιλογές")
        self.Label2.pack()
                ##
        self.sum_button=tk.Button(self.maingui,text="Πρόσθεση",command=self.sum_py)
        self.sum_button.pack(fill="both",expand=1)
                ##
        self.afairesh_button=tk.Button(self.maingui,text="Αφαίρεση",command=self.afairesi_py)
        self.afairesh_button.pack(fill="both",expand=1)
                ##
        self.pollaplasiasmos_button=tk.Button(self.maingui,text="Πολλαπλασιαμός Πίνακα",command=self.pollaplasiamos_py)
        self.pollaplasiasmos_button.pack(fill="both",expand=1)
                ##
        self.quit_button=tk.Button(self.maingui,text="Έξοδος",command=self.popupmsg)
        self.quit_button.pack(fill="both",expand=1)
        
    def centered(self):
        # Gets the requested values of the height and widht.
        windowWidth = root.winfo_reqwidth()
        windowHeight = root.winfo_reqheight()
        print("Width",windowWidth,"Height",windowHeight)
        # Gets both half the screen width/height and window width/height
        positionRight = int(root.winfo_screenwidth()/2 - windowWidth/2)
        positionDown = int(root.winfo_screenheight()/2 - windowHeight/2)
        # Positions the window in the center of the page.
        root.geometry("+{}+{}".format(positionRight, positionDown))
            
    def kill(self):
        self.centered()
        root.destroy()
        popup.destroy()
        exit(0)
           
    def sum_py(self):
        root.withdraw()
        import prosthesi
        
    def afairesi_py(self):
        root.withdraw()
        import afairesh
        
    def pollaplasiamos_py(self):
        root.withdraw()
        import pollaplasiasmos
        
    def popupmsg(self):
        global popup
        root.withdraw()
        popup = tk.Tk()
        popup.title("Εξοδος")
        popup.iconbitmap('warn_img.ico')
        popup.geometry("200x100")
        warn = tk.Label(popup, text="Έξοδος?",)
        warn.pack()
        Yes= tk.Button(popup,text="Ναί",command =self.kill)
        Yes.pack()
        No= tk.Button(popup,text="Όχι",command = self.switch)
        No.pack()
        popup.resizable(0,0)
        popup.mainloop()
        
    def switch(self):
        popup.destroy()  
        root.deiconify()  
        
        
    
#--------------

if __name__ == '__main__':
    root=tk.Tk()
    guitest=GUI(root)
    root.mainloop()
Module that must be imported

from tkinter import *
import numpy as np
import os
import sys
import GUI
import subprocess 
import importlib


class MyApp:
    def __init__(self,root):
####### Gets the requested values of the height and widht.
        windowWidth = root.winfo_reqwidth()
        windowHeight = root.winfo_reqheight()
        
        # Gets both half the screen width/height and window width/height
        positionRight = int(root.winfo_screenwidth()/2 - windowWidth/2)
        positionDown = int(root.winfo_screenheight()/2 - windowHeight/2)
        # Positions the window in the center of the page.
        root.geometry("+{}+{}".format(positionRight, positionDown))
          #### there is a lot more but there are just more functions
The thing that is concerning me is the bottom of the module file
root=Tk()
myapp=MyApp(root)
root.mainloop()
Should i add
if __name__ == "__main__"
??
If i just straight up import them,the code will run before the gui,because i have imported it on the top.
Reply
#4
You need to put your code into functions and classes, so that it doesn't run automatically when you import it. So your afairesh module would have a function in it, call it do_something. You would import afairesh at the top of the GUI module, and all it would do is define the afairesh.do_something function. Then, when the correct button is pushed, you would call afairesh.do_something(), and that would run the code.

And on line 72 you use global popup. There is no reason to use global within a class. Or at least no good reason, there are lots of bad reasons. Either pass popup to the method directly as a parameter, or make popup an attribute of the class, and use self.popup to refer to it.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
My module named "afairesh",(lets call it "imported" just for you), has

class MyApp:
    def __init__(self,root):
and everything is under __init__. The only thing that is not under __init__ is
root=Tk()
myapp=MyApp(root)
root.mainloop()
Reply
#6
Then you could put everything that is not under the init into a function, and call that function as I suggested.

I think there are probably better ways to do a GUI than this, but I'm not a serious GUI programmer. Did your professor give you any advice on how to rewrite your program?
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#7
Nop,we have to do it all by our selves. I will try your solution now!
Reply
#8
From "imported" i removed the class and sticked all the functions to the __init__ method.

IMPORTED.py

from tkinter import *
import numpy as np
import os
import sys
import GUI
import subprocess 
        
def __init__(self,root):
    root=Tk()
####### Gets the requested values of the height and widht.
    windowWidth = root.winfo_reqwidth()
    windowHeight = root.winfo_reqheight()
    # Gets both half the screen width/height and window width/height
    positionRight = int(root.winfo_screenwidth()/2 - windowWidth/2)
    positionDown = int(root.winfo_screenheight()/2 - windowHeight/2)
    # Positions the window in the center of the page.
    root.geometry("+{}+{}".format(positionRight, positionDown))
##########----------------------
    root.title("Αφαίρεση πινάκων")
    root.iconbitmap("minus_ico.ico")
    root.resizable(False, False)
    self.root=Frame(root)
    self.root.pack()
    self.start()
    self.entries1=[]
    self.entries2=[]
    self.entry_list1=[]
    self.entry_list2=[]
    self.entry_list1_2=[]
    self.entry_list2_2=[]
    self.entr1=[]
    self.entr2=[]
    self.res=[]
    root.mainloop()
    
    def start(self):
        self.label1=Label(self.root,text="Αφαίρεση πινάκων παραδείγματα",font="Arial 12")
        self.label1.grid(row=1,column=1)
        self.label2=Label(self.root,text="Διάλεξε τις διαστάσεις του πρώτου πίνακα",font="Arial 12")
        self.label2.grid(row=2,column=1)
        self.s1=Label(self.root,text="X:",font="Arial 10")
        self.entry1=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
        self.entry1.grid(row=3,column=1)
        self.s2=Label(self.root,text="Y:",font="Arial 10")
        self.s2.grid(row=4,column=1)
        self.entry2=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
        self.entry2.grid(row=4,column=1)
        self.w2=Label(self.root,text="Διάλεξε τις διαστάσεις του δεύτερου πίνακα",font="Arial 12")
        self.w2.grid(row=5,column=1)
        self.s3=Label(self.root,text="X:",font="Arial 10")
        self.s3.grid(row=6,column=1)
        self.entry3=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
        self.entry3.grid(row=6,column=1)
        self.s4=Label(self.root,text="Y:",font="Arial 10")
        self.s4.grid(row=7,column=1)
        self.entry4=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
        self.entry4.grid(row=7,column=1)
        self.w3=Button(self.root,text="Σχηματισμός πινάκων ",font="Arial 12",bg="#d9d9d9",command=self.multi)
        self.w3.grid(row=8,column=1)
        self.returnbutton=Button(self.root,text="Αρχική",bg="#d9d9d9",command=self.hide_and_return)
        self.returnbutton.grid(ipadx=0,ipady=0,row=8)
    def check(self):
        num="0123456789"
        self.entry1_value=self.entry1.get()
        self.entry2_value=self.entry2.get()
        self.entry3_value=self.entry3.get()
        self.entry4_value=self.entry4.get()
        if self.entry1_value not in num or self.entry2_value not in num or self.entry3_value not in num or self.entry4_value not in num:
            root.withdraw()
            alertwindow=Toplevel()
            alertwindow.title("Προσοχή")
            alertlabel=Label(alertwindow,text="Παρακαλώ,βάλε μόνο ακαίρεους αριθμούς!")
            alertlabel.pack()
            alertbutton=Button(alertwindow,text="Ξαναπροσπάθησε",command=self.restart)
            alertbutton.pack()				
        elif self.entry1_value=="" or self.entry2_value=="" or self.entry3_value=="" or self.entry4_value=="":
            root.withdraw()
            empty_alertwindow=Toplevel()
            empty_alertwindow.title("Προσοχή")
            empty_alertlabel=Label(empty_alertwindow,text="Παρακαλω,συμπλήρωσε ολα τα πεδία")
            empty_alertlabel.pack()
            empty_alertbutton=Button(empty_alertwindow,text="Ξαναπροσπάθησε",command=self.restart)
            empty_alertbutton.pack()
        if self.entry1_value!=self.entry3_value or self.entry2_value!=self.entry4_value:
            self.answer=Label(self.root,text="Δεν μπορείς να προσθέσεις πίνακες διαφορετικών διαστάσεων",font="Arial 15")
            self.answer.grid(row=9,column=1)
            self.clear=Button(self.root,text="Ξαναπροσπάθησε",font="Arial 12",command=self.restart)
            self.clear.grid(row=11,column=1)     
        else:
            self.creation()
    def creation(self):
        global q
        entry1_value=self.entry1.get()
        entry2_value=self.entry2.get()
        entry3_value=self.entry3.get()
        entry4_value=self.entry4.get()
        entry1_value=int(entry1_value)
        entry2_value=int(entry2_value)
        
        d=entry1_value*entry2_value
        s=Label(self.root,text="1ος πίνακας:",font="Arial 15")
        s.grid(row=12,column=1)
        for i in range(entry1_value):
            for w in range(entry2_value):
                entry=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
                entry.grid(row=12+i,column=2+w)
                self.entries1.append(entry)
        s=Label(self.root,text="2ος πίνακας:",font="Arial 15")
        s.grid(row=15+entry1_value,column=1)
        for i in range(entry1_value):
            for w in range(entry2_value):
                entry=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
                entry.grid(row=15+entry1_value+i,column=2+w)
                self.entries2.append(entry)
                
        q=Button(self.root,text="Αποτέλεσμα",font="Arial 14",state='active',command=self.result_lock)
        q.grid(row=16+2*entry1_value,column=1)
        
        false_button=Button(self.root,text="Έκανα λάθος",font="Arial 14",command=self.refresh)
        false_button.grid(row=16+2*entry1_value,ipadx=0,ipady=0)
    def result(self):
        entry1_value=self.entry1.get()
        entry2_value=self.entry2.get()
        entry3_value=self.entry3.get()
        entry4_value=self.entry4.get()
        entry1_value=int(entry1_value)
        entry2_value=int(entry2_value)
        d=entry1_value*entry2_value
        for x in self.entries1:
            res1=x.get()
            res1=int(res1)
            self.entry_list1.append(res1)
        for t in self.entries2:
            res2=t.get()
            res2=int(res2)
            self.entry_list2.append(res2)
        entry_count1=0
        for i in range(entry1_value):
            self.entry_list1_2.append(list(self.entry_list1[entry_count1:entry_count1+entry2_value]))
            self.entry_list2_2.append(list(self.entry_list2[entry_count1:entry_count1+entry2_value]))
            entry_count1+=entry2_value
        for x in self.entry_list1_2:
            for i in range(entry2_value):
                self.entr1.append(x[i])
        for y in self.entry_list2_2:
            for i in range(entry2_value):
                self.entr2.append(y[i])
        r=Label(self.root,text="Εδώ είναι αναλυτικά οι πράξεις:",font="Arial 12")
        r.grid(row=20+2*entry1_value,column=1)
        for c in range(d):
            self.res.append(self.entr1[c]-self.entr2[c])
        entry_count2=0   
        for t in range(entry1_value):
            for i in range(entry2_value):
                f=Label(self.root,text="{}-{}={}".format(self.entr1[entry_count2],self.entr2[entry_count2],self.res[entry_count2]),font="Arial 12")
                f.grid(row=20+2*entry1_value+t,column=2+i)
                entry_count2+=1       
        e=Label(self.root,text="Ο πίνακας που προκύπτει είναι:",font="Arial 12")
        e.grid(row=25+2*entry1_value+d,column=1)
        entry_count3=0
        for t in range(entry1_value):
            for i in range(entry2_value):
                e=Label(self.root,text="{}".format(self.res[entry_count3]),font="Arial 12")
                e.grid(row=25+2*entry1_value+d+t,column=2+i)
                entry_count3+=1
        g=Button(self.root,text="Ξαναπροσπάθησε",font="Arial 12",command=self.refresh)
        g.grid(row=28+2*entry1_value+d+entry1_value,column=1)
        
    def refresh(self):
        self.root.destroy()
        myapp=MyApp(root)
        
    def restart(self,):
        python = sys.executable
        os.execl(python, python, * sys.argv)
        
    def multi(self):
        self.check()
        self.w3['state']=DISABLED
        
    def result_lock(self):
         self.result()
         q.configure(state="disabled")
         
    def hide_and_return(self):
        root.withdraw()
        subprocess.Popen('GUI.py', shell=True)
        


         
#-----------------------------------------------------------------------------------------
It there any python error? I mean any def placement. Then, from the GUI code,i must use
import IMPORTED
then IMPORTED.start()
Reply
#9
I would keep the class. Generally in a GUI you have a main event loop. Import the file at the top of your other file, and when needed make an instance of it, and call that instance's main loop method. And don't call it IMPORTED. That limits you to one file you can import, or confusing names like IMPORTED1, IMPORTED2, and so on. It's there to do something. Name it after what it is there to do.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#10
Thank you for your response.Made me think better for my future projects!
I think i am making progress.The only error i get now is
NameError: name 'root' is not defined
from my "afairesh" file( the module that i must import).I will keep digging until i find it !!!!!!!!!!!!!!!!!!!!!!!!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Pygame importing classes Padalinkiller1 2 3,794 Nov-15-2017, 02:08 PM
Last Post: Padalinkiller1
  Problems with importing classes in different folder Xeraphim 3 3,396 Nov-08-2017, 03:20 PM
Last Post: Larz60+
  Using classes? Can I just use classes to structure code? muteboy 5 5,080 Nov-01-2017, 04:20 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020