I am trying to create a python script that will trigger a tkinter window every time a certain event happens. The python script will have a while true loop and during the loop the tkinter event may or may not happen (if-else block). Right now the actual loop part isn't done, so I am currently testing the tkinter part but I can't seem to open more than tkinter window.
Below is the test script I am using.
from tkinter import *
from sys import exit
import os
onetwo = "C:/Users/I/Downloads/Transfer_Out_1016_Outlook.txt"
def popupError(s):
popupRoot = Tk()
##popupRoot.after(20000, exit)
popupButton = Button(popupRoot, text = s, font = ("Verdana", 12), bg = "yellow", command = lambda: os.system(onetwo))
popupButton.pack()
popupRoot.geometry('400x50+700+500')
popupRoot.mainloop()
popupError("HelloWORLD")
def popupTwo(s):
popupRoot = Tk()
##popupRoot.after(20000, exit)
popupButton = Button(popupRoot, text = s, font = ("Verdana", 12), bg = "yellow", command = lambda: os.system(onetwo))
popupButton.pack()
popupRoot.geometry('400x50+700+500')
popupRoot.mainloop()
popupTwo("HEWWWWWEWEWKOO")
I apologize for the lack of an actual piece of code but this is the best I can do right now given the dev status of the other parts of the overall python script.
Note that the tkinter window may be triggered more than once in a single loop session.
If any other details are needed, I'll try my best to add more in.
Here’s what you can do:
from tkinter import *
def popup(winName):
newWin = Toplevel()
btn2 = Button(newWin, text=winName)
btn2.pack()
root = Tk()
btn = Button(root, text=“Popup”, command=lambda: popup(“text”))
btn.pack()
root.mainloop()
Related
when I click the button it call's cpuTemp function and it has a after loop init which causes my not responding window and it is show values of cpu percent in my python console so the question is why it is not working
'''
from tkinter import *
import psutil
import statistics
window = Tk()
# window size
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
# window
window.attributes('-transparentcolor', 'blue')
window.resizable(True, True)
window.attributes('-alpha', 0.96)
window.config(cursor='crosshair')
window.attributes('-topmost', 0)
window.geometry(f"{screen_width}x{screen_height}+20+20")
window.state('zoomed')
window.title('Hello Python')
# windTemp
def cpuTemp(event):
#gettin temps
cpuTemps = [psutil.cpu_percent(0.5), psutil.cpu_percent(0.5), psutil.cpu_percent(0.5),
psutil.cpu_percent(0.5), psutil.cpu_percent(0.5)]
meanVal = statistics.mean(cpuTemps)
print(meanVal)
lbl.configure(text=f'{meanVal}%')
window.after(1000 , cpuTemp(event))
#button
btn = Button(window, text="This is Button widget", fg='blue')
btn.place(x=80, y=100)
btn.bind('<Button-1>', cpuTemp)
#label
lbl = Label(window , text='hi' , fg = "#0009ff0fc")
lblPlace = [ screen_width/2 , screen_height/2]
lbl.place(x=f'{lblPlace[0]}', y=f'{lblPlace[1]}')
window.mainloop()
# temp
this is not working can anyone fix this for me I would appreciate that.
it stills print in my pycharm consloe so why is my window not responding.
i am using pycharm as you might know now.
and I want to make this code working .
i am a python newbie so pls help it would mean a lot to me...
window.after(1000 , cpuTemp(event)) immediately runs cpuTemp(event) and passes the result to window.after. This creates an infinite loop since each call results in another call to the function.
The code needs to look something like this:
window.after(1000, cpuTemp, None)
The reason for None is that the function doesn't use the event, and the current event is relatively useless except for when the original event is being processed.
I was trying to create a program inside tkinter that draws different patterns based on user input. I want a 'clear' button on my window that can clear everything on the window. I tried 'turtle.clear" and 'turtle.reset', they work but they open a new turtle window which I dont want and also that I am using tut = turtle.RawTurtle(). What can I do to try to fix this problem?
I use the following sample code:
from tkinter import *
from turtle import *
root = Tk()
tut = None
def reset_button():
tut.reset()
tut.hideturtle()
def draw_again():
tut.speed('fastest')
tut.color('blue', 'yellow')
tut.begin_fill()
while True:
tut.forward(200)
tut.left(170)
if abs(tut.pos()) < 1:
break
tut.end_fill()
button1 = Button(text = 'Reset', command = reset_button)
button1.pack()
button2 = Button(text = 'Draw', command = draw_again)
button2.pack()
canvas_Main = Canvas(root, bg='#ffffff', width = 500, height = 500)
canvas_Main.pack()
tut = RawTurtle(canvas_Main)
tut.speed('fastest')
tut.color('red', 'yellow')
tut.begin_fill()
while True:
tut.forward(200)
tut.left(170)
if abs(tut.pos()) < 1:
break
tut.end_fill()
root.mainloop()
The purpose is that input fn takes string input and pass it into GUI fn which runs the condition and ammend tkinter window accordingly.
#*********************************** IMPORTING MODULES*****************
import tkinter
from tkinter import*
import tkinter.messagebox
import sqlite3
import os
import threading
from time import sleep
from input import*
conn = sqlite3.connect('portal.db')
c = conn.cursor()
global a
#*************** TKINTER GUI CODE******************
def gui(a):
window = tkinter.Tk()
window.title("Smart Notice Board")
#********************** FRAMES OF MAIN WINDOW(HOME)******************
top = Canvas(window,width=1024,height=184)
top.pack(fill=X)
middle = Canvas(window, width=1024, height=450, bg='steelblue')
middle.pack(fill=X)
main_left = Canvas(middle, width=275, height=450, bg='lightgreen')
main_left.pack(side=LEFT)
main_right = Canvas(middle, width=800, height=450, bg='steelblue')
main_right.pack(side=RIGHT)
bottom = Canvas(window, width=1024, height=70, bg='black')
bottom.pack(fill=X)
#************************** IMAGES********************
i_top = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\BG.png')
top.create_image(0,10, anchor=tkinter.NW,image = i_top)
i_right = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\aus1.png')
main_right.create_image(0,0, anchor=tkinter.NW,image = i_right)
#i_left = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\widget1.png')
#main_left.create_image(0,0, anchor=tkinter.NW,image = i_left)
t1 = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\first.png')
t2 = tkinter.PhotoImage(file='F:\\C_backup\\fyp\\5 jan 2k19\\BG.png')
#***************** TIMETABLE IMAGE VIEWING FN***********************
def home():
main_right.create_image(0,0, anchor=tkinter.NW,image = t2)
#*********************** TIMETABLE BUTTON PRESS FN*************************
def timetable():
main_right.create_image(0,0, anchor=tkinter.NW,image = t1)
#******************************* CONDITIONS**********************
if a == "NULL":
timetable()
if a == "HOME":
home()
#*********************** MAIN MENU BUTTONS****************
button_1 = Button(text = ' HOME', anchor = 'w', height = 2, width = 8,activebackground = '#33B5e5',bg = 'brown',fg = 'white',command = home)
top.create_window(2,150,anchor = 'nw', window = button_1)
button_2 = Button(text='TIMETABLE', height = 2, width=12, activebackground = '#33B5e5', bg = 'brown', fg = 'white',command = timetable)
top.create_window(75,150, anchor='nw', window = button_2)
window.mainloop()
#************************** MAIN LOOP************************
if __name__ == "__main__":
#print(valuea())
a=valuea()
gui(a)
Now what I want is continuously run that thing and update Tkinter window; but the 2btn fn only takes it one time and pass it into GUI fn which runs tkinter and it stucks on window.mainloop as tkinter is infinity loop.
Please suggest me a solution also u can run this code by only setting pictures from your computer
The standard method to run code regularly in the mainloop is to register a timeout function using the after method of the root window.
But, whatever you do in such a timeout function (and indeed in all other callbacks), it should not block, because that would lock up the mainloop! So you cannot use input. But you could read from sys.stdin, which is a io.TextIOWrapper instance.
You could use input in a second thread. But since Tkinter isn't thread-safe, that second thread should not use Tkinter functions or methods. So you should not simply update a label from the second thread. You could save/append the input to a global variable, but you'd have to protect that with a lock or mutex. And you'd need to use a timeout function in the main Tkinter thread to test if the lock or mutex is released by the second thread so the Tkinter thread can claim it and access the data. As you can see this is really complicated. So mixing Tkinter and threads is generally not recommended.
In order to ammend tkinter window and show the text and open picture.I did slight change in the input.py file;and coded as below
def vala():
a=speech()
if a == "HOME":
home()
if a == "NULL":
timetable()
window.after(1000,vala)
what I have done is I convert it into recursive fn that call itself after 1000ms. In this way, it can be done.
Basically, I have done it with Pocketsphinx as Input (i.e. my project takes speech input and open file/image in tkinter screen and it runs continuously)
In this code i am trying to finger users from a domain to return their credentials, but when i actually call the finger command in variable pep and have it displayed in the variable results which gets packed into a tkinter window. When i run it the only thing that is displayed is a '0' and i can see the finger command run properly and return the correct info the background Debug I/O but it does not display it in the tkinter window, i have no idea why. Any help? (P.S. for anyone running the code, entering a blank string on the finger_target returns a list on all users online)
import tkinter,subprocesses,time
from tkinter import *
root=Tk()
finger_target,fingerlabel=Entry(root),Label(root, text="TARGET: ")
finger_confirm=Button(root, text="FINGER", command=lambda: TheActualfinger(finger_target.get()))
finger_target.grid(row=0, column=1)
fingerlabel.grid(row=0,column=0)
finger_confirm.grid(row=0, column=2)
def TheActualfinger(user):
pep=subprocess.call(("finger",finger_target.get()+"#telehack.com"))
outfinger= Tk()
def windowCalsDEFAULT():
w,h =500, 500
ws, hs=outfinger.winfo_screenwidth(),outfinger.winfo_screenheight()
x, y=(ws/2) - (w/2),(hs/2) - (h/2)
outfinger.geometry('%dx%d+%d+%d' % (w, h, x, y))
results= Label(outfinger, text=pep).pack(fill="x")
outfinger.mainloop()
root.mainloop()
subprocess.call returns only status code - error code returned by finger - and 0 means OK.
Use subprocess.check_output to get text.
BTW: tkinter should have only one Tk() window (main window). To create other windows use Toplevel(). And tkinter should have only one mainloop (it is its "engine")
BTW: you can use tkinter.messagebox.showinfo to display window with message.
import tkinter as tk
import tkinter.messagebox
import subprocess
# --- functions ---
def window_with_result(text):
win = tk.Toplevel()
w = 500
h = 500
ws = win.winfo_screenwidth()
hs = win.winfo_screenheight()
x = (ws-w)/2
y = (hs-h)/2
win.geometry('%dx%d+%d+%d' % (w, h, x, y))
tk.Label(win, text=text, justify='left').pack(fill="x")
def actual_finger(user):
result = subprocess.check_output(["finger", user+"#telehack.com"])
print('[DEBUG]:', result)
# message window
tkinter.messagebox.showinfo(user, result)
# or own window
window_with_result(result)
# --- main ---
root = tk.Tk()
target = tk.Entry(root)
label = tk.Label(root, text="TARGET: ")
confirm = tk.Button(root, text="FINGER", command=lambda:actual_finger(target.get()))
target.grid(row=0, column=1)
label.grid(row=0, column=0)
confirm.grid(row=0, column=2)
root.mainloop()
BTW: I use lower_case names to make code more readable.
See PEP 8 -- Style Guide for Python Code
Im trying to make a little program that endlessly prints out numbers inside GUI window, I can not find a way to print the out put of the function in a text box inside the GUI window instead of the python shell, please help, here is my code so far...
import sys
from tkinter import *
root = Tk()
def number(event):
x = 420
while True:
x +=420
print(x^70)
button_1 = Button(root, text="Start...")
button_1.bind("<Button-1>", number)
button_1.pack()
root.mainloop()
Thanks Harvey
You'll find it hard to constantly insert a value into a widget. The widget does not update with each insert. You can think of it has having a temporary variable for it. It can be accessed during the loop (as shown with print). However you'll notice that the widget itself doesn't update until the loop is over. So if you have while True then your widget will never update, and so you won't have the numbers streaming into the widget.
import sys
from tkinter import *
root = Tk()
def number():
x = 420
while x < 8400: # Limit for example
x +=420
textbox.insert(END, str(x^70)+'\n')
print(textbox.get(1.0, END)) # Print current contents
button_1 = Button(root, text="Start...", command=number) #Changed bind to command, bind is not really needed with a button
button_1.pack()
textbox = Text(root)
textbox.pack()
root.mainloop()