I am working through online tutorials to learn how to make a GUI with Tkinter. But i am having an issue when using the .grid() function.
Here is what i have so far:
from Tkinter import *
root = Tk()
title = Label(root, text = "Hello World")
title.pack()
name = Label(root, text = "Name")
password = Label(root, text = "Password")
entry_name = Entry(root)
entry_password = Entry(root)
name.grid (row = 0, sticky = E)
password.grid (row = 0, sticky = E)
entry_name.grid (row = 0, column = 1)
entry_password.grid (row = 1, column = 1)
check = Checkbutton(root, text = "Keep me logged in")
check.grid(columnspan = 2)
root.mainloop()
So the problem im having is as soon as i include that first line:
name.grid(row = 0, sticky = E)
And then run the script, there are no errors, but nothing opens. The program just hangs and i have to close the command prompt in order to regain control.
If i comment out all the lines using .grid() they program works fine and will open a window with my title inside it.
So, does anyone know what im doing wrong?
Im using Python 2.7
You cannot use both pack and grid with two or more widgets that share the same parent. In your case you're using pack for title and grid for everything else. Use one or the other.
Keep grid geometry manager consistent so use title.grid().
from tkinter import *
root = Tk()
title = Label(root, text = "Hello World")
title.grid()
name = Label(root, text = "Name")
password = Label(root, text = "Password")
entry_name = Entry(root)
entry_password = Entry(root)
name.grid(row = 0, sticky = E)
password.grid (row = 0, sticky = E)
entry_name.grid (row = 0, column = 1)
entry_password.grid (row = 1, column = 1)
check = Checkbutton(root, text = "Keep me logged in")
check.grid(columnspan = 2)
root.mainloop()
Related
Python: 3.9.5
Os: macOS 11.4
from tkinter import *
window = Tk()
e1_value = StringVar()
def printText():
print(e1_value.get())
# def printText():
# print('HelloWorld!')
b1 = Button(window, text = "Excute", command = printText())
b1.grid(row = 0, column = 0)
e1 = Entry(window, textvariable = e1_value)
e1.grid(row = 0, column = 1)
t1 = Text(window, height = 1, width = 20)
t1.grid(row = 0, column = 2)
window.mainloop()
I met an error that was printed out in the terminal so I couldn't print out the value into the terminal. The error said,
"TSM AdjustCapsLockLEDForKeyTransitionHandling -
_ISSetPhysicalKeyboardCapsLockLED Inhib"
, when I type something into Entry window. I've been searching for the answer on Google, but I still can't find it. Do you happen to know how to solve the problem?
Besides, I could see 'Hellow world!' only once even if I pushed the Button a few times.
I'm not acquainted with tkinter so I don't know what to do.
I deleted the parenthesis after printText.
b1 = Button(window, text = "Excute", command = printText)
I could print out what I typed in the Entry box. I still saw "TSM AdjustCapsLockLEDForKeyTransitionHandling - _ISSetPhysicalKeyboardCapsLockLED Inhib" though.
from tkinter import *
window = Tk()
e1_value = StringVar()
def printText():
print(e1_value.get())
# def printText():
# print('HelloWorld!')
b1 = Button(window, text = "Excute", command = printText)
b1.grid(row = 0, column = 0)
e1 = Entry(window, textvariable = e1_value)
e1.grid(row = 0, column = 1)
t1 = Text(window, height = 1, width = 20)
t1.grid(row = 0, column = 2)
window.mainloop()
It's because you have another language in your keyboard preferences.
Delete the language that is not english in your keyboard preferences
I've recently finished a data standardisation script and am currently trying to make it more user-friendly by creating an app with Tkinter. I have already managed to run the data standardisation script through Tkinter, but the script requires minor changes between different data sets.
What I'm trying to achieve is inserting a user-defined piece of text to a specific location in the script. I have tried the text widget on Tkinter, however I have only managed to open the script in the app, which is something I avoid doing (optimally the app user would not even need to see the original code).
What I'm rather trying to do is having a Tkinter textbox, with a 'Run' button next to it. That way when a user inserts a specific name (e.g. 'Law Conference Attendees Jan 2020') it would automatically place this piece of text here df['Data Identifier'] = ''
My current Tkinter code looks like this:
def __init__(self):
super(Root, self).__init__()
self.title("Python Tkinter Dialog Widget")
self.minsize(320, 200)
self.text_area = Text()
self.text_area.grid(column = 2, row = 3)
self.labelFrame = ttk.LabelFrame(self, text = "Open File")
self.labelFrame.grid(column = 0, row = 1, padx = 20, pady = 20)
self.button()
self.button1()
self.button2()
self.textbox()
self.textbox1()
self.textbox2()
def button(self):
self.button = ttk.Button(self.labelFrame, text = "Browse a File",command = self.open_file)
self.button.grid(column = 1, row = 1)
def button1(self):
self.button1 = ttk.Button(self.labelFrame, text = "Cleanse Campaign Codes",command = self.standardize)
self.button1.grid(column = 1, row = 7)
def button2(self):
self.button2 = ttk.Button(self.labelFrame, text = "Cleanse Data",command = self.helloCallBack)
self.button2.grid(column = 1, row = 8)
def textbox(self):
self.textbox = ttk.Entry(self.labelFrame)
self.textbox.grid(column = 6, row = 1)
def textbox1(self):
self.textbox1 = ttk.Entry(self.labelFrame)
self.textbox1.grid(column = 6, row = 2)
def textbox2(self):
self.textbox2 = ttk.Entry(self.labelFrame)
self.textbox2.grid(column = 6, row = 3)
def helloCallBack(self):
os.system('python data_cleansing_final.py')
def open_file(self):
open_return = filedialog.askopenfile(initialdir = "C:/", title="Select file to open", filetypes=(("python files", "*.py"), ("all files", "*.*")))
for line in open_return:
self.text_area.insert(END, line)
def standardize(self):
open_return = open_return.apply(lambda x: difflib.get_close_matches(x, textbox)[0])
root = Root()
root.mainloop()
I would very much appreciate any help or advice.
You could add a StringVar to your textbox.
self.inputstring = ttk.StringVar(self.lableFrame, value = 'value')
self.textbox2 = ttk.Entry(self.labelFrame, textvariable = self.inputstring)
self.textbox2.grid(column = 6, row = 3)
To read the variable you should use:
self.inputstring.get()
You can make an entry:
text = Entry(root, width=10)
text.grid(column=0, row=0)
With a button next to it:
run = Button(root, text="Run", width=10, command=runClicked)
run.grid(column=1, row=0)
And then a method called runClicked above these:
def runClicked():
userText = text.get()
And then the variable userText variable will hold whatever the user types in and you can use it as you wish.
All in all your code would look something like:
def runClicked():
userText = text.get()
text = Entry(root, width=10)
text.grid(column=0, row=0)
run = Button(root, text="Run", width=10, command=runClicked)
run.grid(column=1, row=0)
I am a newbie in python. I am trying to write a program to reference books, book chapters and journal articles in Harvard and APA style. I need to be able to print the entry from the user.
The code displays three windows. In the first, the user is asked to choose the referencing style (Harvard/APA) and when clicking the button it opens a second window which allows the user to choose the source (book/book chapter/journal). Then a third window opens which allows the user to input the information that is required (author/year/title and so on).
After this, the user must click another button done to see the full reference. To visualise the execution, select Harvard, then Book, as I have only written that part of the code.
from tkinter import *
def book_harvard():
reference = author_entry.get()
reference_1 = year_entry.get()
reference_2 = title_entry.get()
string_to_display = reference + reference_1 + reference_2
print(string_to_display)
def TypeofTextHarvard():
second = Toplevel(first)
first.withdraw()
second.title("Type of Source")
Source = Label (second, text = "What type of source would you like to reference?").grid(column = 1, row = 0)
Book = Button (second, text = "Book", command = Harvard).grid(column = 1, row = 1)
Chapter = Button (second, text = "Book Chapter").grid (column = 1, row = 2)
Journal = Button (second, text = "Journal Article").grid (column = 1, row = 3)
first = Tk()
first.title("Referencing Style")
Reference = Label (first, text = "Which referencing style would you like to use?").grid(column = 1, row = 0)
Harvard = Button (first, text = "Harvard Style", command = TypeofTextHarvard).grid (column = 1, row = 1)
APA = Button (first, text = "APA Style").grid (column = 1, row = 2)
def Harvard():
third = Toplevel()
third.title("book")
author = StringVar()
year = StringVar()
title = StringVar()
author_label = Label(third, text = "Author")
author_entry = Entry(third)
year_label = Label(third, text = "Year")
year_entry = Entry(third)
title_label = Label(third, text = "Title")
title_entry = Entry(third)
button_1 = Button(third, text = "Done", command = book_harvard)
author_label_2 = Label(third, textvariable = author)
year_label_2 = Label(third, textvariable = year)
title_label_2 = Label(third, textvariable = title)
author_label.grid (row = 0, column = 0)
author_entry.grid (row = 0, column = 1)
year_label.grid (row = 1, column = 0)
year_entry.grid (row = 1, column = 1)
title_label.grid (row = 2, column = 0)
title_entry.grid (row = 2, column = 1)
button_1.grid (row = 3, column = 0)
author_label_2.grid (row = 4, column = 1)
year_label_2.grid (row = 4, column = 2)
title_label_2.grid (row = 4, column = 3)
first.mainloop()
However I get the following error:
reference = author_entry.get()
NameError: name 'author_entry' is not defined
The cause of the NameError is because author_entry is a variable local to the Harvard() function, so can't be referenced outside of it, such as in the separate book_harvard() function. The simplest—although not the best—solution is to make it a global variable. The other Entry widgets potentially have the same problem, so in the code below I have declared all of them global.
I also noticed another potential issue you're likely to run into, namely assigning the return value of the grid() method to a variable. e.g.:
Book = Button(second, text="Book", command=Harvard).grid(column=1, row=1)
This is not doing what you think because the grid() method always returns None, so that's the value that's getting assigned to Book. I haven't fixed these, but doing so is easy, just create the widget first and assign it to a variable, and then on another line, all variable.grid(...).
One final piece of advice: read and start following the PEP 8 - Style Guide for Python Code. I've done that to some degree to the version of your code with the fix in it shown below.
FYI: The accepted answer to the question Best way to structure a tkinter application describes an excellent object-oriented way to structure and implement Tkinter-based applications.
from tkinter import *
def book_harvard():
global author_entry, year_entry, title_entry # ADDED
reference = author_entry.get()
reference_1 = year_entry.get()
reference_2 = title_entry.get()
string_to_display = reference + reference_1 + reference_2
print(string_to_display)
def TypeofTextHarvard():
second = Toplevel(first)
first.withdraw()
second.title("Type of Source")
Source = Label(second, text = "What type of source would you like to reference?").grid(column=1, row=0)
Book = Button(second, text="Book", command=Harvard).grid(column=1, row=1)
Chapter = Button(second, text="Book Chapter").grid(column=1, row=2)
Journal = Button(second, text="Journal Article").grid(column=1, row=3)
first = Tk()
first.title("Referencing Style")
Reference = Label(first, text="Which referencing style would you like to use?").grid(column=1, row=0)
Harvard = Button(first, text="Harvard Style", command=TypeofTextHarvard).grid(column=1, row=1)
APA = Button(first, text="APA Style").grid(column=1, row=2)
def Harvard():
global author_entry, year_entry, title_entry # ADDED
third = Toplevel()
third.title("book")
author = StringVar()
year = StringVar()
title = StringVar()
author_label = Label(third, text="Author")
author_entry = Entry(third)
year_label = Label(third, text="Year")
year_entry = Entry(third)
title_label = Label(third, text="Title")
title_entry = Entry(third)
button_1 = Button(third, text="Done", command=book_harvard)
author_label_2 = Label(third, textvariable=author)
year_label_2 = Label(third, textvariable=year)
title_label_2 = Label(third, textvariable=title)
author_label.grid(row=0, column=0)
author_entry.grid(row=0, column=1)
year_label.grid(row=1, column=0)
year_entry.grid(row=1, column=1)
title_label.grid(row=2, column=0)
title_entry.grid(row=2, column=1)
button_1.grid(row=3, column=0)
author_label_2.grid(row=4, column=1)
year_label_2.grid(row=4, column=2)
title_label_2.grid(row=4, column=3)
first.mainloop()
I want to create two windows.
Behaviour of windows:
Window1 has a label and a button. When I click on that button, 2nd window has to open. 2nd window have a label.
Problem:
Label in 2nd window is not appearing.
Code:
def window1():
root = tkinter.Tk()
root.geometry("200x200")
root.title("Window1")
var = tkinter.StringVar()
tkinter.Label(root, textvariable = var, bg = "red").grid(row = 0, column = 0)
var.set("This is window1")
tkinter.Button(root, text = "Button1", command = OnBut).grid(row = 0, column = 1)
root.mainloop()
def OnBut():
window2()
def window2():
root = tkinter.Tk()
root.title("Window2")
root.geometry("250x250")
var = tkinter.StringVar()
tkinter.Label(root, textvariable = var, bg = "blue").grid(row = 1, column = 0, padx = 3, pady = 3)
tkinter.Button(root, text = "Button", command = OnBut).grid(row = 0, column = 1, padx =3, pady = 3)
var.set("This is window2") #not appearing <-- problem
root.mainloop()
window1()
when I call window2 seperately, its working fine. Why label not printing in 2nd window, by clicking on button?
You don't really need a real function for your command in this case. This is what lambdas are made for -- callbacks!
Remove your onBut function (which is the problem anyway, since root isn't defined there) and replace your command in each button with:
command = lambda: window2(root)
Currently, when you call onBut, it tries to do:
window2(root)
# HELP I DON'T KNOW WHAT root IS!!
This throws a NameError on my copy. Your code may vary.
Since you're editing willy nilly, let me just write you some working code.
import tkinter
def run():
root = tkinter.Tk()
root.title("Window1")
s_var = tkinter.StringVar()
tkinter.Label(root, textvariable = s_var).pack()
tkinter.Button(root, text = "Button", command = lambda: makewindow(root)).pack()
s_var.set("Window #1")
def makewindow(root):
top = tkinter.Toplevel(root)
top.title("Window2")
s_var = tkinter.StringVar()
tkinter.Label(top, textvariable = s_var).pack()
tkinter.Button(top, text = "Button", command = lambda: makewindow(root)).pack()
s_var.set("Window #2")
if __name__ == "__main__":
run()
Basically I want there to be a list, which displays files I have stored in a certain folder, and beside the list there are buttons which open up separate windows which can edit or add a new item to that list.
I want addchar to open up an new window with spaces for different fields, then when you press a "create" button in that window it closes, creates a file on the info you just entered (that's why i've imported os) as well as creating a new item on the main interface's listbox as the name of the character (which is one of the fields). The removechar function would remove that entry and delete the file, and editchar would open up a window similar to addchar, but with the info of the selected item on the list.
EDIT: Here's the code so far
from tkinter import *
import os
import easygui as eg
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
# character box
Label(frame, text = "Characters Editor").grid(row = 0, column = 0, rowspan = 1, columnspan = 2)
charbox = Listbox(frame)
for chars in []:
charbox.insert(END, chars)
charbox.grid(row = 1, column = 0, rowspan = 5)
charadd = Button(frame, text = " Add ", command = self.addchar).grid(row = 1, column = 1)
charremove = Button(frame, text = "Remove", command = self.removechar).grid(row = 2, column = 1)
charedit = Button(frame, text = " Edit ", command = self.editchar).grid(row = 3, column = 1)
def addchar(self):
print("not implemented yet")
def removechar(self):
print("not implemented yet")
def editchar(self):
print("not implemented yet")
root = Tk()
root.wm_title("IA Development Kit")
app = App(root)
root.mainloop()
Ok, I implemented addchar and removechar for you (and tweaked a few other things in your code). I'll leave the implementation of editchar to you - take a look at what I wrote to help you, as well as the listbox documentation
from Tkinter import * # AFAIK Tkinter is always capitalized
#import os
#import easygui as eg
class App:
characterPrefix = "character_"
def __init__(self, master):
self.master = master # You'll want to keep a reference to your root window
frame = Frame(master)
frame.pack()
# character box
Label(frame, text = "Characters Editor").grid(row = 0, column = 0, rowspan = 1, columnspan = 2)
self.charbox = Listbox(frame) # You'll want to keep this reference as an attribute of the class too.
for chars in []:
self.charbox.insert(END, chars)
self.charbox.grid(row = 1, column = 0, rowspan = 5)
charadd = Button(frame, text = " Add ", command = self.addchar).grid(row = 1, column = 1)
charremove = Button(frame, text = "Remove", command = self.removechar).grid(row = 2, column = 1)
charedit = Button(frame, text = " Edit ", command = self.editchar).grid(row = 3, column = 1)
def addchar(self, initialCharacter='', initialInfo=''):
t = Toplevel(root) # Creates a new window
t.title("Add character")
characterLabel = Label(t, text="Character name:")
characterEntry = Entry(t)
characterEntry.insert(0, initialCharacter)
infoLabel = Label(t, text="Info:")
infoEntry = Entry(t)
infoEntry.insert(0, initialInfo)
def create():
characterName = characterEntry.get()
self.charbox.insert(END, characterName)
with open(app.characterPrefix + characterName, 'w') as f:
f.write(infoEntry.get())
t.destroy()
createButton = Button(t, text="Create", command=create)
cancelButton = Button(t, text="Cancel", command=t.destroy)
characterLabel.grid(row=0, column=0)
infoLabel.grid(row=0, column=1)
characterEntry.grid(row=1, column=0)
infoEntry.grid(row=1, column=1)
createButton.grid(row=2, column=0)
cancelButton.grid(row=2, column=1)
def removechar(self):
for index in self.charbox.curselection():
item = self.charbox.get(int(index))
self.charbox.delete(int(index))
try:
os.remove(characterPrefix + item)
except IOError:
print "Could not delete file", characterPrefix + item
def editchar(self):
# You can implement this one ;)
root = Tk()
root.wm_title("IA Development Kit")
app = App(root)
root.mainloop()