Tkinter Text closes but ipython console keeps running indefinetly - python

I am trying to print some rows of a pandas dataframe for the user of my tkinter GUI. However, in this test, the tk window is showed, but when closed, the code stop running.
import pandas as pd
import numpy as np
import sys
from tkinter import *
dates = pd.date_range('20160101', periods=6)
df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=list('ABCD'))
root = Tk()
t1 = Text(root)
t1.pack()
class PrintToT1(object):
def write(self, s):
t1.insert(END, s)
sys.stdout = PrintToT1()
print ('Hello, world!')
print (df)
mainloop()
root.destroy()
print(2)
I am running the script in Spyder, and when I close the window, the ipython console continues processing something, but it never reaches the last line to print the number 2, and I have to restart the console manually.
I want it to close the tk window and continues the script, since in the GUI, after closing the tk window, the code will have to do some calculations for the user. How could I do this?

picture
I am new here (page) but the error is that the mainloop is a loop itself If you close the window the program closes.
root_window.mainloop()
#destroy()use in ithems or daughters windows
test add:
def date_name(self):
t3 = Toplevel(root)
t3.geometry('240x100+20+20')
t3.title("...")
t3.destroy()#use valid
The sample of the data in that window and the function destroy ().
Find how to use the Canvas and the Frame if you want to request the data from the same window but the fields of texts and buttons belong to the cambas ... well I work like that in tkinter.
canvas_menu = Canvas(root, width=200, height=200)
canvas_menu.destroy()#this use valid
root.destroy not valid Tk()is a funcion.
test:
from tkinter import *
from tkinter import ttk
root=Tk()
def new_window():
t3 = Toplevel(root)
t3.geometry('240x100+20+20')
t3.title("...")
Label(t3,text="I hope to help you").pack()
Button(t3,text="destroy() in t3 ",command=t3.destroy).pack()
canvas_c=Canvas(root, width=400, height=400)
canvas_c.pack()
canvas_c.config(bg="blue")
Label(canvas_c,text="info").place(x=100,y=250)
ba=Button(root,text="new_window",command=new_window).pack()
bb=Button(root,text="destroy() in canvas",command=canvas_c.destroy).pack()
root.mainloop()
and run run.jpg

Related

Always ask for user input while tkinter gui is running in fullscreen mode

My program needs to track the user input at all times. For that i think the input() command is the easiest solution. The problem is: At the same time there should be a Tkinter GUI in fullscreen mode running. I've tried a few things, but nothing really worked out. Here is a simplified program, which shows the problems:
from tkinter import *
import tkinter as tk
from threading import Thread
def GUI():
root=tk.Tk()
Text = Label(master=root, text="Test").pack(side="top")
Button = Button(master=root, text="Button").pack(side="top")
root.mainloop()
def input_loop():
x = input()
print(x)
t1 = Thread(target=GUI)
t2 = Thread(target=input_loop)
t1.start()
t2.start()
Even though now both loops work, i still can't type into the console unless I manually select the console window. Other solutions like the entry widget in tkinter won't work because there is no place for them in my actual program. Please let me know if you find something which works reliably.
i didn't get your problem clearly but i will try to help .
so you are saying the program running on full screen but you want to run it on some resolution?
from tkinter import *
import tkinter as tk
from threading import Thread
def GUI():
root=tk.Tk()
# Program title
root.title("Title")
# Preventing user from fullscreen/resize the window
root.resizable(0, 0)
# Resolution of the windows in pixles
root.geometry(f"{820}x{460}")
Text = Label(master=root, text="Test").pack(side="top")
Btn = Button(master=root, text="Button").pack(side="top")
root.mainloop()
def input_loop():
x = input()
print(x)
t1 = Thread(target=GUI)
t2 = Thread(target=input_loop)
t1.start()
t2.start()
also i changed button function to btn because i faced an error with it , and you can now complete the program and play with the resolution of the buttons and windows so on .

Tkinter program runs function but the window pops up after it ends

Ok so I'm pretty new to tkinter and I can not solve this problem that I am having.
When I run the program, it runs the function and after it ends the window with the photo pops up, but the loop does not start the program again.
import tkinter as tk
from tkinter import*
from PIL import ImageTk,Image
from tkinter import messagebox
import YuaChanMainFunc
import time
def on_click(event=None):
# `command=` calls function without argument
# `bind` calls function with one argument
print("Hey Yua!")
YuaChanMainFunc.statement="hey yua"
class Window(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
master.title("Yua-chan AI")
self.img = ImageTk.PhotoImage(Image.open("YuaChanAI/Yua Chan Artwork/YuaChan2.png"))
MainLB = tk.Label(master, image=self.img)
MainLB.bind('<Button-1>', on_click)
MainLB.pack()
b = tk.Button(root, text="Close", command=root.destroy)
b.pack()
#YuaChanMainFunc.YuaChanAIMainFunc()
root = tk.Tk()
#instance of the class
app = Window(root)
root.resizable(0,0)
root.geometry("310x500+1600+510")
YuaChanMainFunc.YuaChanAIMainFunc()
#Runs the application until we close
root.mainloop()
From what I understand you want "YuaChanMainFunc.YuaChanAIMainFunc()"
to run in the background while UI runs the foreground. For that you can start the "YuaChanMainFunc.YuaChanAIMainFunc()" in a different thread and run UI in the main thread itself. Now you can make "YuaChanMainFunc.YuaChanAIMainFunc()" an infinite loop and it wont block root.mainloop(). Also keep in mind root.mainloop() is also an infinite loop. SO anything you write after that will not execute until you close the program.
import threading
backend_thread = threading.Thread(target=YuaChanMainFunc.YuaChanAIMainFunc, args=())
backend_thread.daemon = True #This will make sure backend thread closes when you close ui
backend_thread.start()
root.mainloop()

How to see code in the console [Python, Tkinter, Atom]

I am using Atom to do this, I am asking how to view a variable in the console while also having the TKinter GUI loaded.
My code is as follows:
import random
import tkinter as tk
root = tk.Tk()
rd1 = random.randint(1, 20)
root.mainloop()
Running the program only shows the tk window but I am wondering how I can view the outcome of rd1 from the console, without having to display it in the GUI.
The console becomes a black ver and will only display text when closing the GUI.
Text as follows:
Process returned 0 (0x0) execution time : 1.298 s
Press any key to continue . . .
printing it will show it in the console; sometime it is buffered, so you can add the optional argument flush=True to the print statement.
import random
import tkinter as tk
root = tk.Tk()
rd1 = random.randint(1, 20)
print(rd1, flush=True) # flush will output immediately
root.mainloop()

Python running clock in separate window

I thought I would make a running clock program. I have this code which works for what I want it to do, but I want it to be fancy and output it to a new window. I thought of a message box but that would need constant closing.
Is there way around this, or should I just stick to using the console?
x=0
import datetime
import time
while x<10:
currentTime=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
time.sleep(1)
print(str(currentTime))
EDIT:
This is what i have now but the window goes all over the place.
try:
from Tkinter import *
except ImportError:
from tkinter import *
import datetime
import time
x=0
while x<10:
root = Tk()
prompt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
label1 = Label(root, text=prompt, width=len(prompt))
label1.pack()
def close_after_1s():
root.destroy()
root.after(1000, close_after_1s)
root.mainloop()
You're missing the point of Tk. The entire thing is a loop(hence the mainloop) and you keep destroying and creating a new window, hence the all over the place.
I think you just want something to update every sec:
from Tkinter import Tk,StringVar,Label
import datetime
def update():
global prompt,root
prompt.set(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
root.after(1000, update)
root = Tk()
prompt = StringVar()
label1 = Label(root, textvar=prompt, width=len(prompt.get()))
label1.pack()
update()
root.mainloop()
and my suggestion is to put all of this in a class. Google some Tk examples.

Python: tkinter askyesno method opens an empty window

I use this to get yes/no from user but it opens an empty window:
from Tkinter import *
from tkMessageBox import *
if askyesno('Verify', 'Really quit?'):
print "ok"
And this empty window doesnt go away. How can I prevent this?
This won't work:
Tk().withdraw()
showinfo('OK', 'Select month')
print "line 677"
root = Tk()
root.title("Report month")
months = ["Jan","Feb","Mar"]
sel_list = []
print "line 682"
def get_sel():
sel_list.append(Lb1.curselection())
root.destroy()
def cancel():
root.destroy()
B = Button(root, text ="OK", command = get_sel)
C = Button(root, text ="Cancel", command = cancel)
Lb1 = Listbox(root, selectmode=SINGLE)
for i,j in enumerate(months):
Lb1.insert(i,j)
Lb1.pack()
B.pack()
C.pack()
print "line 702"
root.mainloop()
for i in sel_list[0]:
print months[int(i)]
return months[int(sel_list[0][0])]
Tkinter requires that a root window exist before you can create any other widgets, windows or dialogs. If you try to create a dialog before creating a root window, tkinter will automatically create the root window for you.
The solution is to explicitly create a root window, then withdraw it if you don't want it to be visible.
You should always create exactly one instance of Tk, and your program should be designed to exit when that window is destroyed.
Create root window explicitly, then withdraw.
from Tkinter import *
from tkMessageBox import *
Tk().withdraw()
askyesno('Verify', 'Really quit?')
Not beautiful solution, but it works.
UPDATE
Do not create the second Tk window.
from Tkinter import *
from tkMessageBox import *
root = Tk()
root.withdraw()
showinfo('OK', 'Please choose')
root.deiconify()
# Do not create another Tk window. reuse root.
root.title("Report month")
...

Categories