I have this snippet of code and I expect it to create a gui with a bunch of buttons and a text box. But I only see the empty box with the title:
from tkinter import *
root = Tk()
root.title("title")
root.mainloop()
button1 = Button(root, text="button1")
button2 = Button(root, text="button2")
button3 = Button(root, text="button3")
text = Entry(root)
listbox = Listbox(root)
text.pack()
button1.pack()
button2.pack()
button3.pack()
listbox.pack()
Is it because of inconsistencies between different versions of Python? I am trying to learn about Tkinter using this quick guide
You have to move the call to root.mainloop() to the end of the file.
You have to do root.mainloop() at the end to get the code.
Related
i have 2 python file TestBtnImage1.py and TestBtnImage2.py
I am trying to call display() fucntion of TestBtnImage2 on button click of TestBtnImage1.py,
button without image displying in frame, however button with image is not displying.
thanks in advance
TestBtnImage1.py
from tkinter import *
from TestBtnImage1 import *
frame = Tk()
frame.title("TextBox Input")
frame.geometry('200*200')
frame.config(background="blue")
printButton = Button(frame, text="click me", command=display()).place(x=50, y=50)
frame.mainloop()
TestBtnImage2.py
from tkinter import *
def display():
frame = Tk()
frame.title("TextBox Input")
frame.geometry('200*200')
frame.config(background="blue")
logo1 = PhotoImage(file="cheta.png")
Button(gui, text="click me", image=logo1, bg="blue", relief=FLAT).place(x=100, y=200)
frame.mainloop()
tried googling for the same issue also stackoverflow but no help.
There are a few problems in your code.
In TestBtnImage1.py
You are importing itself, which will cause a NameError.
from TestBtnImage1 import *
and you just need to change it to TestBtnImage2
The geometry specifier should be 'x'
If you use frame.geometry('200*200'), it will cause tkinter bad geometry specifier error.
So use 200x200 instead of 200*200.
The button command
printButton = Button(frame, text="click me", command=display()).place(x=50, y=50)
The display() function will automatically run when executed. You can remove the brackets ()
-> printButton = Button(frame, text="click me", command=display).place(x=50, y=50)
(*) Also, the printButton (None) does nothing. So you can remove it.
In TestBtnImage2.py
Use Toplevel() instead of a new Tk()
-> frame = Toplevel()
Again, bad geometry specifier.
-> frame.geometry('200x200')
Use mainloop() only once.
You can remove frame.mainloop() at the end of the function
(*) Also,
Button(gui, text="click me", image=logo1, bg="blue", relief=FLAT).place(x=100, y=200)
The master gui is not defined.
So, the full code should be:
TestBtnImage1.py:
from tkinter import *
from TestBtnImage2 import *
frame = Tk()
frame.title("TextBox Input")
frame.geometry('200x200')
frame.config(background="blue")
Button(frame, text="click me", command=display).place(x=50, y=50)
frame.mainloop()
TestBtnImage2.py:
from tkinter import *
def display():
frame = Toplevel()
frame.title("TextBox Input")
frame.geometry('200x200')
frame.config(background="blue")
logo1 = PhotoImage(file="cheta.png")
Button(frame, text="click me", image=logo1, bg="blue", relief=FLAT).place(x=100, y=200)
I am making a program that can launch files and programs like a Stream Deck. After selecting the file I want to assign to a button, the button resizes due to the filename being wider than the placeholder text "Add".
I couldn't find any solutions to this problem anywhere.
I am desperate on finding the solution as this is pretty much the final thing i need to fix to make the program pre-Alpha.
Thank you in advace.
How to reproduce this issue:
import tkinter
from tkinter import *
root = Tk()
button1 = Button(root, text="Add", padx=10, pady=10)
button2 = Button(root, text="More Text", padx=10, pady=10)
button1.grid(row=0, column=0)
button2.grid(row=1, column=0)
root.mainloop()
A widget appears in its natural size, if not defined otherwise. The natural size is usally the smallest amount of pixels needed to display the widget in width and height. You can change that appearance by defining a width for your Button, even better have a constant if you use the same value for a couple of Buttons. Example:
import tkinter as tk
#from tkinter import *
#dont't use wildcard imports
#only import your modul once
BUTTONWIDTH = 10 #Constant
root = tk.Tk()
button1 = tk.Button(root, text="Add", width=BUTTONWIDTH) #use width
button2 = tk.Button(root, text="More Text", width=BUTTONWIDTH)
button1.grid(row=0, column=0)
button2.grid(row=1, column=0)
root.mainloop()
So what I am trying to do is create a theme picker for my application
For example, the user could click on a the Green/Black button and it would change every widgets background to Black and it would change every widgets foreground to Green. Then they could click the Red/White button and it would do the same thing but change every widgets background to White and every widgets foreground to Red.
# Imports the tkinter library.
from tkinter import *
from tkmacosx import Button
# Pillow is a improved verison of PIL, stands for Python Image Library. Allows you to import image types like .jpg and .png
from PIL import ImageTk,Image
# Imports messagebox module from tkinter library.
from tkinter import messagebox
# Declare global variables
global selectedBackground
global selectedForeground
selectedBackground="white"
selectedForeground="red"
# Tk() helps to display the root window and manages all the other components of the tkinter application and assigns it to root.
root = Tk()
root.eval("tk::PlaceWindow . center")
root.configure(bg=selectedBackground)
cipherButton = Button(root, text=" Cipher ", padx=40, pady=20, command=openCipher, borderwidth=0, fg="#22fd35", bg="black", highlightbackground="#22fd35").grid(row=1, column=0)
decipherButton = Button(root, text="Decipher", padx=40, pady=20, command=openDecipher, borderwidth=0, fg="#22fd35", bg="black", highlightbackground="#22fd35").grid(row=1, column=1)
spacer1 = Label(root, text=" ", padx=10, pady=1, background="black").grid(row=4, column=1)
quitButton = Button(root, text="Exit d3cryptt", padx=10, pady=5, command=root.quit, borderwidth=0, fg="#22fd35", bg="black", highlightbackground="#22fd35").grid(row=5, column=0, columnspan=2)
spacer2 = Label(root, text=" ", padx=10, pady=1, background=selectedBackground).grid(row=6, column=1)
changecolour = Button(root, text="change colour", padx=1, pady=5, background="black", command=changeColour).grid(row=7, column=0)
#Enter the event main loop
root.mainloop()
I have tried using a function. Something like this.
def changeColour():
selectedBackground="black"
selectedForeground="#22fd35"
changecolour = Button(root, text="change colour", padx=1, pady=5, background="black", command=changeColour).grid(row=7, column=0)
But that doesn't work. I think a function is the right way to go, but I may be wrong.
I will also need this 'theme' to carry on to any other windows that are created from this window. I think I can just do that by using lambda in the command section of the widget.
Widget.config(bg=color) is what your looking for.
Here is a small example of a theme-changing app:
from tkinter import *
from tkmacosx import Button
root = Tk()
def changethemetoblack():
root.config(bg="#000000")
def changethemetowhite():
root.config(bg="#ffffff")
def changethemetored():
root.config(bg="#ff0000")
themeblackbutton = Button(root, text="Change Theme To Black", command=changethemetoblack, bg="#000000", fg="#ffffff")
themewhitebutton = Button(root, text="Change Theme To White", command=changethemetowhite)
themeredbutton = Button(root, text="Change Theme To Red", command=changethemetored, bg="#ff0000", fg="#ffffff")
themeblackbutton.pack()
themewhitebutton.pack()
themeredbutton.pack()
root.mainloop()
I'll try to change it so that it applies for your code.
However, your provided script does not seem to be a working one. I assume this is because it is only a snippet of the real one. I'm not pushing for your entire code, but edit it so we can run it. Ex. openCipher method is causing errors as we have not defined it.
I am trying to update a Text widget, but it's not updated no matter what I try, there is no error as well
def update():# a button calls this
textBox.delete(1.0, tk.END)
textBox.insert(tk.END,"test")
textBox = tk.Text(frame1,height=2,width=10)
textBox.config(state='disabled') #disable editing
textBox.grid(row=0,column=1,pady=2)
Using #JacksonPro's suggestion
import tkinter as tk
def update():# a button calls this
textBox.config(state="normal") # Make the state normal
textBox.delete("0.0", "end")
textBox.insert("end", "test")
textBox.config(state="disabled") # Make the state disabled again
root = tk.Tk()
textBox = tk.Text(root, height=2, width=10)
textBox.config(state="disabled") #disable editing
textBox.grid(row=0, column=1, pady=2)
button = tk.Button(root, text="Click me", command=update)
button.grid(row=1, column=1)
root.mainloop()
When button 1 is pressed I want this program to say word 'hi' and when button 2 is pressed I want it to say 'goodbye' in the same spot as it says hi and override what button 1 produced. However, it doesn't override it just merges the 2 labels together. What is a good way to prevent this from happening while making sure both labels appear in the same spot?
from tkinter import *
root = Tk()
def press():
word = Label(root, text='hi')
word.grid(row=0, column=1)
def press_2():
word_2 = Label(root, text='goodbye')
word_2.grid(row=0, column=1)
button_1 = Button(root, text=1, command=press)
button_2 = Button(root, text=2, command=press_2)
button_1.grid(row=0, column=0)
button_2.grid(row=1, column=0)
root.mainloop()
You just need to use one Label and keep changing its text. We can do this efficiently by using a lambda for the widget command. As stated by #Bryan Oakley, using a StringVar adds unnecessary overhead. This is a slightly modified version from my original. In this version we use the config method of the widget to set the text. As a bonus the code is formatted with a class structure. Using a procedural style with tkinter eventually turns into a big mess. Considering the required imports are minimal, we import them directly and do not need to prefix every widget.
from tkinter import Tk, Button, Label
class Application(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
lbl = Label(self, text='hi')
lbl.grid(row=0, column=1)
btn1 = Button(self, text='1',)
btn1.config(command=lambda m='hi': lbl.config(text=m))
btn1.grid(row=0, column=0)
btn2 = Button(self, text='2')
btn2.config(command=lambda m='goodbye': lbl.config(text=m))
btn2.grid(row=1, column=0)
if __name__ == "__main__":
app = Application()
app.minsize(100, 50)
app.title("My Application")
app.mainloop()
from tkinter import *
root = Tk()
def press():
label['text'] = "hi"
def press_2():
label['text'] = "goodbye"
label = Label(root)
label.grid(row=0, column=1)
button_1 = Button(root, text=1, command=press)
button_2 = Button(root, text=2, command=press_2)
button_1.grid(row=0, column=0)
button_2.grid(row=1, column=0)
root.mainloop()
Put it on the windows firstly,Then change the text config.
A better way to do so would be by using config() method of widgets. But here i dont know if its gonna help out much. But give it a try
from tkinter import *
root = Tk()
def press():
word.config(text='hi')
def press_2():
word.config(text='goodbye')
button_1 = Button(root, text=1, command=press)
button_2 = Button(root, text=2, command=press_2)
button_1.grid(row=0, column=0)
button_2.grid(row=1, column=0)
word = Label(root, text='') #creating a blank label to edit later on in functions
word.grid(row=0, column=1)
root.mainloop()