How to retain variable information in Tkinter? - python

I am trying to convert a text adventure originally made in vanilla Python to a Tkinter format. My attempt at this was to create a dictionary that would be updated whenever information was entered, but the dictionary information isn't saving and seems to revert back to an empty dict every time.
How would I do this ? Apologies if the question is unclear, I am very new to Tkinter and have been struggling with this for a long time.
Here is my code, all it needs to do is figure out if the player wants to activate the tutorial :
from tkinter import *
# Storage
game_text = {}
cmd = {}
root = Tk()
# Configuration
root.geometry ("1000x1000")
root.title("A New Dawn")
icon = PhotoImage(file = "C:/Users/gwynn/Desktop/wcnd_icon.png")
root.iconphoto(False, icon)
root.configure(bg="#006644")
# Parsers
def parse(tag, line):
game_text[tag] = Text(root, width = 200, height = 1)
game_text[tag].insert(INSERT, line)
game_text[tag].pack()
game_text[tag].tag_add(tag, '1.0', 'end')
game_text[tag].tag_config(tag, background = "#006644", foreground = "#8cd98c")
def cmd_parse(cmd_box):
cmd['cmd'] = cmd_box.widget.get()
cmd['cmd'] = cmd['cmd'].lower()
print(cmd['cmd'])
# The Game
parse('tutorial', "Welcome to WC : A New Dawn ! Before we begin - would you like to activate the tutorial ? [Y/N]")
cmd_box = Entry(root, background = '#096', foreground = "#b3e6b3", width = 200, border = 3)
cmd_box.pack()
cmd_box.bind("<Return>", cmd_parse)
print(cmd)
if 'cmd' in list(cmd):
if cmd['cmd'] == "y":
parse('tutorial_y', "Excellent ! The tutorial has been activated.")
elif cmd['cmd'] == "n":
parse('tutorial_n', "Excellent ! The tutorial has been deactivated.")
root.mainloop()

You are trying to manage cmd conditions before the user has even had the chance to type. You have to move your conditions (or call a function of your conditions) after you have actually retrieved the typed data.
def cmd_parse(event):
cmd = event.widget.get().lower()
if cmd == "y":
parse('tutorial_y', "Excellent ! The tutorial has been activated.")
elif cmd == "n":
parse('tutorial_n', "Excellent ! The tutorial has been deactivated.")

Related

How do I change the screen brightness in windows using python?

How do I change the screen brightness in windows using python, without using any extra python packages?
I'd also like a way of getting what the screen brightness is currently at.
I'm thinking that will need to be by using ctypes, but I can't find any information on how to do it.
It annoys me the way the screen brightness buttons on windows adjust the screen brightness in very large increments, so I made a python tkinter program to display the current screen brightness on the taskbar and when I scroll the mouse wheel on the tkinter window it changes the screen brightness:
import subprocess
from tkinter import Canvas, Tk
win = Tk()
win.overrideredirect(True)
canvas = Canvas(win, bg = "#101010", highlightthickness = 0)
canvas.pack(fill = "both", expand = True)
def trim(string, l = None, r = None, include = False, flip = False):
string = str(string)
if l and l in string:
string = string[(string.rindex(l) if flip else string.index(l)) + (0 if include else len(l)):]
if r and r in string:
string = string[:(string.index(r) if flip else string.rindex(r)) + (len(r) if include else 0)]
return string
def set_screen_brightness():
subprocess.run(
["powershell",
f"(Get-WmiObject -Namespace root/WMI -Class WmiMonitorBrightnessMethods).WmiSetBrightness(1,{current_brightness})"],
stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell = True)
def get_screen_brightness():
value = subprocess.check_output(
["powershell", f"Get-Ciminstance -Namespace root/WMI -ClassName WmiMonitorBrightness"],
shell = True)
return int(trim(value, l = "CurrentBrightness : ", r = r"\r\nInstanceName : "))
current_brightness = get_screen_brightness()
brightness_text = canvas.create_text(30, 25, text = current_brightness,
font = ("Segue ui", 14, "bold"), fill = "White", anchor = "w")
sw, sh = win.winfo_screenwidth(), win.winfo_screenheight()
win.geometry(f"69x50+{sw - 505}+{sh - 49}")
def mouse_wheel_screen_brightness(scroll):
global current_brightness, mouse_wheel_screen_brightness_wa
if "mouse_wheel_screen_brightness_wa" in globals():
win.after_cancel(mouse_wheel_screen_brightness_wa)
current_brightness += 2 if scroll else -2
if current_brightness < 0: current_brightness = 0
if current_brightness > 100: current_brightness = 100
canvas.itemconfig(brightness_text, text = current_brightness)
mouse_wheel_screen_brightness_wa = win.after(100, lambda: set_screen_brightness())
win.bind("<MouseWheel>", lambda e: mouse_wheel_screen_brightness(e.delta > 0))
def topmost():
win.attributes("-topmost", True)
win.after(100, topmost)
topmost()
win.mainloop()
I'm sure there must be a fast way of changing the screen brightness in ctypes, without any extra python packages. With using a subprocess call to Powershell the screen brightness text keeps freezing.
I want to do it without using any extra python packages because when I try to install a python package it says that there was a problem confirming the ssl certificate. I googled it and tried to fix it, but I can't get it to work.
The another way to do it without any library is:
import subprocess
def run(cmd):
completed = subprocess.run(["powershell", "-Command", cmd], capture_output=True)
return completed
if __name__ == '__main__':
take_brightness = input("Please enter the brightness level: ")
command = "(Get-WmiObject -Namespace root/WMI -Class WmiMonitorBrightnessMethods).WmiSetBrightness(1," + take_brightness + ")"
hello_command = f"Write-Host {command}"
hello_info = run(hello_command)
by the help of PowerShell commands we can easily increase or decrease the brightness of windows without any external packages
WmiSetBrightness(1,<brightness % goes here>)
import subprocess
subprocess.run(["powershell", "(Get-WmiObject -Namespace root/WMI -Class WmiMonitorBrightnessMethods).WmiSetBrightness(1,40)"])
the subprocess is the internal library that comes with python.
just run the above code,
hope this will work.
Install screen brightness control using pip
Windows: pip install screen-brightness-control
Mac/Linux: pip3 install screen-brightness-control I guess
Then use this code
import screen_brightness_control as sbc
sbc.set_brightness(25) # Number will be any number between 0 and hundred
# Sets screen brightness to 25%
I found info on the screen brightness module here
I used the WMI library and it really worked fine. Here is the code, but this is for Windows. I think it is OS specific so if it doesn't work for you, you should look for a better solution.
import wmi
brightness = 40 # percentage [0-100] For changing thee screen
c = wmi.WMI(namespace='wmi')
methods = c.WmiMonitorBrightnessMethods()[0]
methods.WmiSetBrightness(brightness, 0)
Please upvote and accept the answer if you like it.

Python crashes upon destroying Tkinter window

I'm a student in software development and I'm developing an application (my first application!) in Python for learning purposes.
It works fairly well, and I got almost all of the features working that I want to work.
A short explanation of the program: It's an administrative program to log the members of a sports club. So it has basic functions like adding members, listing members, etc.
For it to be complete, it also needs a function to delete a member. This has always worked fine, but I rarely used the function.
Now after I modified a ttk.Treeview() object so it now sorts by last name, I added a new member to see if it sorts like it should. It did!
Now I wanted to delete that member, but for some reason, it no longer works.
It crashes Python. It doesn't just crash the application, no error, just plain "Pythonw.exe has stopped working".
Here's all the code that belongs to that function:
def dellid(zeid, addwindow):
winsound.PlaySound("SystemHand", winsound.SND_ASYNC)
usure = tkinter.Tk()
print('usure window created')
usure.title('Lid verwijderen')
usure.geometry('{}x{}'.format('300', '150'))
usure.iconbitmap(default='programdata\\icon.ico')
usure.attributes("-topmost", True)
addwindow.grab_set()
#logo2 = PhotoImage(file="warning.png")
#logolabel = tkinter.Label(usure, image = logo2)
#logolabel.grid(row01, columnspan = 2)
usure.columnconfigure(0, weight = 1)
usure.columnconfigure(1, weight = 2)
label01 = tkinter.Label(usure, text = '''
Weet U zeker dat U dit lid wilt verwijderen?
Deze actie kan niet ongedaan worden gemaakt!''').grid(row = 1, columnspan = 2)
emptyrow = tkinter.Label(usure, text = ' ').grid(row = 2, columnspan = 2)
jaknop = ttk.Button(usure, text = 'Ja', command = lambda: delforsure(zeid, usure, addwindow)).grid(row = 3, column = 0, sticky = 'E')
neeknop = ttk.Button(usure, text = 'Nee', command = lambda: nodell(addwindow, usure)).grid(row = 3, column = 1, sticky = 'S')
def nodell(addwindow, usure):
addwindow.grab_release()
usure.destroy()
def delforsure(zeid, usure, addwindow):
#addwindow.grab_release()
addwindow.destroy()
print('addwindow destroyed')
usure.destroy()
print('usure destroyed')
conn = sqlite3.connect('test.db')
c = conn.cursor()
opendb = []
opendb.append(zeid)
print(zeid)
print(opendb)
c.execute("DELETE FROM leden WHERE ids = ?",opendb)
print('c.execute')
conn.commit()
print('c.commit')
#usure.destroy()
done = tkinter.Tk()
done.title('Lid verwijdert')
done.geometry('{}x{}'.format('300', '150'))
done.iconbitmap(default='programdata\\icon.ico')
label01 = tkinter.Label(done, text = '''
Lid verwijdert
''')
label01.pack()
done.update()
time.sleep(2)
on_return(done)
The on_return function closes the said window and reopens the main menu.
Now in delforsure(zeid, usure, addwindow) it locks up on the line usure.destroy()
It doesn't print the line 'usure destroyed' anymore, that I put there to see where it locks up.
It doesn't give any error, Python itself just crashes.
If I move
usure.destroy()
print('usure destroyed')
under on_return(done), all the way at the bottom, it does close the window and return to the main menu, but the main menu will be drawn with graphical distortions and soon still crashes afterwards.
I really don't understand what is going on.
Can anybody help me trace the issue please?
It looks like you are making a yes / no modal window. Is there a reason you don't want to use the version that is built into tkinter?
from tkinter import messagebox
def dellid(zeid, addwindow):
answer = messagebox.askyesno(
'Lid verwijderen',
'Weet U zeker dat U dit lid wilt verwijderen?\n'
'Deze actie kan niet ongedaan worden gemaakt!')
if answer:
addwindow.destroy()
print('addwindow destroyed')

Python Tkinter Gui Not Working

I have had an issue with this piece of code from awhile back, it's part of a GCSE mock and I have currently finished the working code (with text only) but I would like to expand it so that it has a nice GUI. I'm getting some issues with updating my sentence variables within the code. Anyone with any suggestions for me please do explain how I can fix it.
#GCSE TASK WITH GUI
import tkinter
from tkinter import *
from tkinter import ttk
var_sentence = ("default")
window = tkinter.Tk()
window.resizable(width=FALSE, height=FALSE)
window.title("Sentence")
window.geometry("400x300")
window.wm_iconbitmap("applicationlogo.ico")
file = open("sentencedata.txt","w")
file = open("sentencedata.txt","r")
def update_sentence():
var_sentence = sentence.get()
def submit():
file.write(sentence)
print ("")
def findword():
messagebox.showinfo("Found!")
print ("Found")
sentencetext = tkinter.Label(window, fg="purple" ,text="Enter Sentence: ")
sentence = tkinter.Entry(window)
sentencebutton = tkinter.Button(text="Submit", fg="red" , command=update_sentence)
findword = tkinter.Label(window, fg="purple" ,text="Enter Word To Find: ")
wordtofind = tkinter.Entry(window)
findwordbutton = tkinter.Button(text="Find!", fg="red" ,command=findword)
usersentence = sentence.get()
usersentence = tkinter.Label(window,text=sentence)
shape = Canvas (bg="grey", cursor="arrow", width="400", height="8")
shape2 = Canvas (bg="grey", cursor="arrow", width="400", height="8")
#Packing & Ordering Moduales
sentencetext.pack()
sentence.pack()
sentencebutton.pack()
shape.pack()
findword.pack()
wordtofind.pack()
findwordbutton.pack()
usersentence.pack()
shape2.pack()
window.mainloop()
If I understand your question right, you want to display the entered text in the usersentence label.
Changing update_sentence() function to what is shown below will archive the desired effect.
def update_sentence():
var_sentence = sentence.get()
usersentence.config(text=var_sentence)
usersentence never gets updated because you only set it once when the program starts this was the problem.

raw_input stops GUI from appearing

I have written a program in Python that allow me to change the names of many files all at once. I have one issue that is quite odd.
When I use raw_input to get my desired extension, the GUI will not launch. I don't get any errors, but the window will never appear.
I tried using raw_input as a way of getting a file extension from the user to build the file list. This program will works correctly when raw_input is not used.The section of code that I am referring to is in my globList function. For some reason when raw_imput is used the window will not launch.
import os
import Tkinter
import glob
from Tkinter import *
def changeNames(dynamic_entry_list, filelist):
for index in range(len(dynamic_entry_list)):
if(dynamic_entry_list[index].get() != filelist[index]):
os.rename(filelist[index], dynamic_entry_list[index].get())
print "The files have been updated!"
def drawWindow(filelist):
dynamic_entry_list = []
my_row = 0
my_column = 0
for name in filelist:
my_column = 0
label = Tkinter.Label(window, text = name, justify = RIGHT)
label.grid(row = my_row, column = my_column)
my_column = 1
entry = Entry(window, width = 50)
dynamic_entry_list.append(entry)
entry.insert(0, name)
entry.grid(row = my_row, column = my_column)
my_row += 1
return dynamic_entry_list
def globList(filelist):
#ext = raw_input("Enter the file extension:")
ext = ""
desired = '*' + ext
for name in glob.glob(desired):
filelist.append(name)
filelist = []
globList(filelist)
window = Tkinter.Tk()
user_input = drawWindow(filelist)
button = Button(window, text = "Change File Names", command = (lambda e=user_input: changeNames(e, filelist)))
button.grid(row = len(filelist) + 1 , column = 1)
window.mainloop()
Is this a problem with raw_input?
What would be a good solution to the problem?
This is how tkinter is defined to work. It is single threaded, so while it's waiting for user input it's truly waiting. mainloop must be running so that the GUI can respond to events, including internal events such as requests to draw the window on the screen.
Generally speaking, you shouldn't be mixing a GUI with reading input from stdin. If you're creating a GUI, get the input from the user via an entry widget. Or, get the user input before creating the GUI.
A decent tutorial on popup dialogs can be found on the effbot site: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm

Tkinter panedwindow not opening

I have created a panedwindow in python tkinter with two panes. It will open fine on it's own but within an if statement it no longer opens
First I had just the code for the panedwindow on it's own but I wanted to use it within another section of code. It won't work within an if statement, it appears to be ignored. Where have I gone wrong?
from tkinter import *
import time
ticketCost=6
username="Rob"
code = input("Enter code: ")
if code == "123":
year=str(time.localtime()[0])
month=str(time.localtime()[1])
day=str(time.localtime()[2])
hour=str(time.localtime()[3])
minute=str(time.localtime()[4])
ticketTime=str(hour+":"+minute)
ticketDate=str(day+"/"+month+"/"+year)
ticketInfo="Bus ticket\nSingle\nDate: "+ticketDate+"\nTime: "+ticketTime+"\nPassengers: "+
...str(int(ticketCost/3))+"\nPrice: "+str(ticketCost)+" credits"
ticketWindow = PanedWindow(orient=VERTICAL,bg="white")
ticketWindow.pack(fill=BOTH, expand=1)
top = Label(ticketWindow, text="top pane")
photo = PhotoImage(file='Coach 1.gif')
top.config(image=photo,bg="white")
top.image = photo
ticketWindow.add(top)
bottom = Label(ticketWindow, text="bottom pane")
bottom.config(text=ticketInfo)
bottom.config(bg="white")
ticketWindow.add(bottom)
print("\nThank you", username)
else:
print("no")
You do not appear to be making a root window, and are not starting the event loop.

Categories

Resources