Python Forum

Full Version: Tkinter window minimize,appear
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,
I am making a GUI for my code. Take a look:

import tkinter as tk
from sys import exit
class GUI:
    def __init__(self,root):
        root.title("Αρχική είσοδος")
        self.maingui=tk.Frame(root)
        root.update_idletasks()
        self.maingui.pack()
        self.Label1=tk.Label(self.maingui,text="welcome")
        self.Label1.pack()
        self.Label2=tk.Label(self.maingui,text="Choose")
        self.Label2.pack()
                ##
        self.sum_button=tk.Button(self.maingui,text="sum",command=self.sum_py)
        self.sum_button.pack(fill="both",expand=1)
                ##
        self.afairesh_button=tk.Button(self.maingui,text="remove",command=self.afairesi_py)
        self.afairesh_button.pack(fill="both",expand=1)
                ##
        self.pollaplasiasmos_button=tk.Button(self.maingui,text="multiply",command=self.pollaplasiamos_py)
        self.pollaplasiasmos_button.pack(fill="both",expand=1)
                ##
        self.quit_button=tk.Button(self.maingui,text="quit",command=self.kill)
        self.quit_button.pack(fill="both",expand=1)
        
    def kill(self):
        self.maingui.destroy()
        root.withdraw()
        exit(0)
        
    def show_me():
        root.update()
        root.deiconify()

    def sum_py(self):
        root.withdraw()
        import file1

    def afairesi_py(self):
        root.withdraw()
        import file2

    def pollaplasiamos_py(self):
        root.withdraw()
        import file3
        
#--------------
root=tk.Tk()
guitest=GUI(root)
root.mainloop()

Each def is called by a button. Each one imports a file.It will successfully do it for the first time.Launch the file,work,and then the GUI will come back,you try to click the buttons again but nothing will appear. I have in mind it its because of the import command. I do it everytime,and it is once imported in the start. Take a look at this code.

from tkinter import *
import numpy as np
import os
import sys
class MyApp:
    def __init__(self,root):
        root.title("Πολλαπλασιασμός πινάκων")
        root.resizable(FALSE,FALSE)
        root.update_idletasks()
        self.root=Frame(root)
        self.root.pack()
        self.start()
        self.entries1=[]
        self.entry_list=[]
        self.entry_list2=[]
        self.entr=[]
        self.res=[]
        
    def start(self):
        self.w=Label(self.root,text="Πολλαπλασιασμός πινάκων με αριθμό παραδείγματα",font="Arial 12")
        self.w.grid(row=1,column=1)
        self.w1=Label(self.root,text="Διάλεξε τις διαστάσεις του πίνακα",font="Arial 12")
        self.w1.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.entry3=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
        self.entry3.grid(row=6,column=1)
        self.w3=Button(self.root,text="Σχηματισμός πίνακα ",font="Arial 12",bg="#d9d9d9",command=self.multi)
        self.w3.grid(row=10,column=1)

        self.returnbutton=Button(self.root,text="Χ",bg="#d9d9d9",command=self.hide_and_return) #####THIS IS THE BUTTON WHICH GOES TO THE GUI
        self.returnbutton.grid(ipadx=0,ipady=0,row=10)
        
    def creation(self):
        global q
        num="012345678910"
        entry_value1=self.entry1.get()
        entry_value2=self.entry2.get()
        entry_value3=self.entry3.get()
        
        if entry_value1 not in num or entry_value2 not in num or entry_value3 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 entry_value1=="" or entry_value2=="" or entry_value3=="":
            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()
        
        
        entry_value1=int(entry_value1)
        entry_value2=int(entry_value2)
        d=entry_value1*entry_value2
        s=Label(self.root,text=" Πίνακας:",font="Arial 15")
        s.grid(row=12,column=1)
        for i in range(entry_value1):
            for w in range(entry_value2):
                entry=Entry(self.root,font="Arial 12",bg="#d9d9d9",width=5)
                entry.grid(row=12+i,column=2+w)
                self.entries1.append(entry)
        
        q=Button(self.root,text="Αποτέλεσμα",font="Arial 14",state='active',command=self.result_lock)
        q.grid(row=14+entry_value1,column=1)
       
    def result(self):
        entry_value1=self.entry1.get()
        entry_value2=self.entry2.get()
        entry_value3=self.entry3.get()
        entry_value1=int(entry_value1)
        entry_value2=int(entry_value2)
        entry_value3=int(entry_value3)
        d=entry_value1*entry_value2
        for x in self.entries1:
            res1=x.get()
            res1=int(res1)
            self.entry_list.append(res1)
        entry_count1=0
        for i in range(entry_value1):
            self.entry_list2.append(list(self.entry_list[entry_count1:entry_count1+entry_value2]))
            entry_count1+=entry_value2
        for x in self.entry_list2:
            for i in range(entry_value2):
                self.entr.append(x[i])
        r=Label(self.root,text="Εδώ είναι αναλυτικά οι πράξεις:",font="Arial 12")
        r.grid(row=18+entry_value1,column=1)
        for c in range(d):
            self.res.append(self.entr[c]*entry_value3)
        entry_count2=0   
        for t in range(entry_value1):
            for i in range(entry_value2):
                f=Label(self.root,text="{}*{}={}".format(self.entr[entry_count2],entry_value3,self.res[entry_count2]),font="Arial 12")
                f.grid(row=18+entry_value1+t,column=2+i)
                entry_count2+=1
        e=Label(self.root,text="Ο πίνακας που προκύπτει είναι:",font="Arial 12")
        e.grid(row=20+entry_value1+d,column=1)
        entry_count3=0
        for t in range(entry_value1):
            for i in range(entry_value2):
                e=Label(self.root,text="{}".format(self.res[entry_count3]),font="Arial 12")
                e.grid(row=20+entry_value1+d+t,column=2+i)
                entry_count3+=1
        g=Button(self.root,text="Ξαναπροσπάθησε",font="Arial 12",command=self.refresh)
        g.grid(row=28+2*entry_value1+d,column=1)
        
    def refresh(self):
        self.root.destroy()
        myapp=MyApp(root)
        
    def result_lock(self):
        self.result()
        q['state']=DISABLED
        
    def restart(self): 
        os.execl(sys.executable, sys.executable, *sys.argv)
        
    def multi(self):
        self.creation()
        self.w3['state']=DISABLED
        
    def hide_and_return(self):
        root.withdraw()
        from GUI import show_me
        

#-----------------------------------------------
root=Tk()
myapp=MyApp(root)
root.mainloop()

self.returnbutton=Button(self.root,text="Χ",bg="#d9d9d9",command=self.hide_and_return) 
This button calls the hide_and_return function.Which hides the root window and imports the show_me def from GUI.This is where i must find a way to do this once!
Files are only supposed to be imported once. You can get around that, but because that's not the best way to do that, I'll show how after showing how it "should" be done. Your initialization code, which opens the window, should be in it's own function, such as a main() or show_me(). Importing the file should do nothing at all, but you might have a block at the end that will call that function if the file is called directly:
if __name__ == "__main__":
    main()
    # ...or
    show_me()
Then, your other module would import the GUI at the top, with the other imports. The event handler would then look like:
    def hide_and_return(self):
        root.withdraw()
        GUI.show_me()
Because it's just a function call, calling it will work any number of times.

If, for whatever reason, you do want to just keep the initialization in the root of the file, you can instead reload the module, using importlib.reload(): https://docs.python.org/3/library/import...lib.reload

The reload function only works if the module already exists, though. So you'll need to keep track of whether or not you've imported it already. In your code, I'd suggest a variable defined in __init__:
def __init__(self):
    self.external_gui_created = False

def hide_and_return(self):
    root.withdraw()
    if self.external_gui_created:
        importlib.reload(GUI)
    else:
        import GUI
        self.external_gui_created = True
But I highly suggest going with the first route. importlib.reload() doesn't work with all modules (unpredictable things happen if you try reloading sys, for example), and according to the docs, it doesn't re-import anything that the module you're reloading imported. In addition, I'd consider it bad style, kind of ugly, and not obvious what you're trying to achieve.
Thanks.I went with your 1st way. Now I added to my GUI
if __name__ == '__main__':
    root=tk.Tk()
    guitest=GUI(root)
    root.mainloop()
      
But if i try to use
import GUI
i will get NameError: name 'show_me' is not defined
i tried
 from GUI import show_me
did not work either.The only time i got no error,was with
from GUI import *
Hm.
show_me function in GUI is:
def show_me(self):
        root.update()
        root.deiconify()
Lastly,module has the fuction hide_and_return(self).
def hide_and_return(self):
        root.withdraw()
        show_me()
It is driving me nuts,with
 from GUI import *
will work but do the exact same think. HIDE!

import GUI
Calling show_me from GUI.py from my second file
GUI.show_me()
Error on my secondary file
AttributeError: module 'GUI' has no attribute 'show_me'
I MADE IT WORK!
i used
import subprocess
Then i edited hide_and_return function and added
subprocess.Popen('GUI.py', shell=True)
This command runs the script with the help of OS and i used the arg shell=True to hide the windows CMD from the screen.Saved me ton of work. Thank you for your help!
(Dec-27-2018, 01:37 AM)frequency Wrote: [ -> ]def show_me(self):
If show_me is a method of a class, it doesn't make sense to import it anyway. You'd want to import the class (or instance, if you make one automatically) and call that class/instance's show_me method. For your code, it kinda looks like you called the file GUI.py, the class GUI[/icode], and the instance guitest.

So in the file with hide_and_return, you'd have from GUI import guitest. And then in hide_and_return(): guitest.show_me().

Using subprocess to spawn a new instance of python certainly works, but it's also a pretty ugly hack.
Its kinda sloppy to use subprocess,but it wont go to waste.I will try to do the normal way by using the imports in a copy version just to test and see. Thanks