Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am working with an example file of a Tkinter layout. I keep getting an error that is boggling my mind.
the code worked until I inserted the statements:
area.pack()
area.insert(end, "hello")
then I got the error:
Indentation error: unexpected indentation.
ok, so I commented the two statements out (as shown below), to get what is essentially the exact same code I started with, which worked fine- only to keep getting the same error again. I have played around with it for a few hours now and I simply can't grasp the - im sure- really simple thing that is really triggering this. Any thoughts?
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode Tkinter tutorial
In this script, we use the grid
manager to create a more complicated
layout.
author: Jan Bodnar
last modified: December 2010
website: www.zetcode.com
"""
from Tkinter import Tk, Text, BOTH, W, N, E, S
from ttk import Frame, Button, Label, Style
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Windows")
self.style = Style()
self.style.theme_use("default")
self.pack(fill=BOTH, expand=1)
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
lbl = Label(self, text="Windows")
lbl.grid(sticky=W, pady=4, padx=5)
area = Text(self)
area.grid(row=1, column=0, columnspan=2, rowspan=4,
padx=5, sticky=E+W+S+N)
#area.pack()
#area.insert(end, "hello")
abtn = Button(self, text="Activate")
abtn.grid(row=1, column=3)
cbtn = Button(self, text="Close")
cbtn.grid(row=2, column=3, pady=4)
hbtn = Button(self, text="Help")
hbtn.grid(row=5, column=0, padx=5)
obtn = Button(self, text="OK")
obtn.grid(row=5, column=3)
def main():
root = Tk()
root.geometry("350x300+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
You're mixing tabs and spaces. Don't do that :-) 1
For future reference, run the code with python -tt instead of just python2. If you mix tabs and spaces python -tt will yell at you and tell you to fix it rather than giving strange indentation errors.
1Don't do that in any language. It only leads to pain and suffering.
2I believe that this is the default behavior for python3.x.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
The program is meant to show 7 buttons but only shows the first three. I would appreciate some help, I'm trying to make a catalog program that writes files and text in those files. It works without tkinter, but the buttons arent showing up. I wrote the seven buttons and they worked originally but they have since stopped working. I don't know the problem since this is my first time with tkinter.
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
root.geometry("500x500")
root.title("Catalog 2020")
button = tk.Button(frame,
text = "Make New File",
command=answer1)
button.pack(side=tk.LEFT)
button2 = tk.Button(frame,
text = "Edit File",
command = answer2)
button2.pack(side=tk.LEFT)
button3 = tk.Button(frame,
text = "Append Data",
command = answer3)
button3.pack(side=tk.LEFT)
button4 = tk.Button(frame,
text = "Read File",
command = answer4)
button4.pack(side=tk.LEFT)
button5 = tk.Button(frame,
text = "Delete File",
command = answer5)
button5.pack(side=tk.LEFT)
button6 = tk.Button(frame,
text = "Tell me a Joke",
command = answer6)
button6.pack(side=tk.LEFT)
buttonquit = tk.Button(frame,
text="QUIT",
fg="red",
command=quit)
buttonquit.pack
root.mainloop()
With root.geometry('500x500') your asking your window to be '500x500' , remove that line to fit all the window with the widgets. Also you forgot to say () with the pack of last button, like buttonquit.pack() or you wont see that button too.
I'm a bit stumped with the proper way to design with Tkinter. I've read dozens of Tkinter examples but since most of them describe simple and specific cases I'm having trouble with finding the right global design for my script. I'm trying to separate as much as possible the GUI code from the data model (I'm working on a very simple card game).
My main problem is how to access Tkinter elements globally, from different functions and classes. Currently I am building the entire interface inside a large gui_build() function, right after the definitions for my data classes. This function is called from a main() function along with all the data initialisation stuff. Problem is, even if I return the Tk root object from gui_build() so that main() can pass it around, I'm having trouble accessing Tk elements when needed.
For example, I have several callback functions for different Tk buttons which are in the global scope. If one of those needs to check the state of a radio button, it's apparently impossible to find it in the Tk root hierarchy by name, and passing references to radio buttons all over the place seems very inelegant.
I can sort of make it work by declaring radio buttons globally but this defeats the purpose of keeping all the GUI code in the same place.
Wondering what could be considered as a "best practice" before trying to reinvent the wheel.
Thank you.
I have been making Tkinter interfaces for 2 years, now. I was facing the same problem initially. From my experience I would suggest that you define a class which inherits Tk root widget and then assign you element widgets as attributes of that class, also the callback functions as functions of that class. That will make accessing global widgets(button) and functions easy. These widgets and functions are global inside the class definition. It makes them easy to access. You can follow following template
from tkinter import *
class Interface(Tk):
def __init__(self, title):
Tk.__init__(self)
self.title(title)
self.build()
def build(self):
self.UserNameLabel = Label(self, text="User Name")
self.UserNameLabel.grid(row=0, column=0, sticky=E, pady=10)
self.UserNameEntry = Entry(self)
self.UserNameEntry.grid(row=0, column=1, sticky=W, pady=10)
self.PassWordLabel = Label(self, text="Password")
self.PassWordLabel.grid(row=1, column=0, sticky=E, pady=10)
self.PassWordEntry = Entry(self, show='*')
self.PassWordEntry.grid(row=1, column=1, sticky=W, pady=10)
self.status = Label(self, text='Please enter User Name and Password')
self.status.grid(row=2, column=0, columnspan=2, pady=10)
self.LoginButton = Button(self, text='Login', width=20, command=self.checkCreadentials)
self.LoginButton.grid(row=3, column=0, columnspan=2, pady=10)
def checkCreadentials(self):
if (self.UserNameEntry.get().strip() == 'username') and (self.PassWordEntry.get()=='password'):
self.status['text']= 'Welcome !'
else:
self.status['text']= 'Invalid User Name or Password!!!'
self.bell()
Interface('Login').mainloop()
I was testing a method to hide and show frames by pressing a button (the buttons will be a menu bar later). So I created this code:
import tkinter as tk
from tkinter import *
win = Tk()
win.geometry("275x350")
win.title("MyProgram")
win.configure(background="white")
frame1 = Frame(win, width=200, height=200)
frame1.grid_propagate(False)
frame2 = Frame(win, width=200, height=200)
frame2.grid_propagate(False)
Label(frame1, text="Hello world", font="20").grid()
Label(frame2, text="Zweiter frame", font="20").grid()
def runGrid(run, destroy):
run.grid(row=1, column=2)
destroy.grid_forget()
def run2nd(run, destroy):
run.grid(row=1, column=2)
destroy.grid_forget()
Button(win, text="Run", command=lambda:runGrid(frame1, frame2)).grid(row=0, column=0)
Button(win, text="Run 2nd", command=lambda:run2nd(frame2, frame1)).grid(row=0, column=1)
win.mainloop()
So here is the problem...
After pressing the first button, the first frame comes up in his wanted size. After pressing the 2nd button, the 2nd frame comes up in his wanted size. But when you press the first button again (after pressing both buttons once before) then the frame is just showing up like grid_propagate was removed from the code (the frame is just as big as the label in it). Can someone explain me the fault in my code which is causing the problem?
Thanks a lot ;)
I found an other way to get what I want:
By simply using grid_remove() instead of using grid_forget() it is working.
But I still hope someone can answer my question because it really should work with grid_forget() as well I think.
I am currently trying to make a scrollable list of entries using tkinter in Python 3. While looking for some documentation, I found this: Adding a scrollbar to a group of widgets in Tkinter. It is really great and works really fine with Labels, but it doesn't seem to work with Entries. You'll find right here my code which creates a 2x25 list of entries through which I would like to be able to scroll:
import tkinter as tk
class MainPage(tk.Frame):
def __init__(self, racine):
super().__init__(master=racine)
self.grid()
self.entriesCanvas = tk.Canvas(self, borderwidth=0, background="white")
self.entriesFrame = tk.Frame(self.entriesCanvas, background="white")
self.scrollbar = tk.Scrollbar(self, command=self.entriesCanvas.yview)
self.entriesCanvas.configure(yscrollcommand=self.scrollbar.set)
self.entriesCanvas.grid(column=0, row=2, columnspan=2)
self.scrollbar.grid(column=3, row=2, sticky='ns')
# self.entriesFrame.grid()
self.entriesCanvas.create_window((0, 0), window=self.entriesFrame,
anchor='nw', tags='self.entriesFrame')
# self.entriesFrame.grid()
self.entriesCanvas.bind('<Configure>', self.onFrameConfigure)
self.entries = []
for i in range(50):
self.entries.append(tk.Entry(self.entriesFrame, font=('arial', 30)))
self.entries[i].grid(column=i % 2, row=i//2)
def onFrameConfigure(self, event):
self.entriesCanvas.configure(scrollregion=self.entriesCanvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
mainPage = MainPage(root)
root.mainloop()
Notice I commented two lines out. If you "activate" the first line, there will be a scrollbar and one can scroll through the entries, but it is strangely zoomed. On the other hand, if you "activate" the second line, the GUI will be as I would like it to be, but without the possibility to scroll, and it seems to show all entries (even if there are 1000 entries, therefore making a window which is 20 times the size of your screen).
Do you know where my mistake is?
Okay, so I found a way to have my program doing what I want. I just changed the method
def onFrameConfigure(self, event):
self.entriesCanvas.configure(scrollregion=self.entriesCanvas.bbox("all"))
by
def onFrameConfigure(self, event):
self.entriesCanvas.configure(scrollregion=self.entriesCanvas.bbox("all"), width=self.entriesFrame.winfo_width())
(I basically only added a parameter to ask the canvas to be the width of the frame.)
I don't know if it is perfect (as I still use .grid() istead of .pack()), but it works.
Thank you for giving me the source Tkinter: How to get frame in canvas window to expand to the size of the canvas?, it really helped me find where my mistake was.
I truely apologise for my English, I know I make a lot of mistakes.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I was working on an autoclicker with a gui when I ran into this problem: TypeError: call() got an unexpected keyword argument 'text'
Not sure how to fix it, I've tried everything
Full code: https://codeshare.io/axY39N
Label(window, text="Tan AutoClicker", fg="white", bg="#1589d6", font="none
20", width=30).grid(row=0, column=0)
Label(window, text="Keybind:", fg="white", bg="#1589d6", font="none
10").grid(row=3, column=0)
binding = Entry(window, bg="white", width=10)
binding.grid(row=4, column=0)
Button (window, text="Submit", width=6, height=1,
command=set_keybind).grid(row=5, column=0)
Since you haven't posted the complete stacktrace, I'm guessing this is the issue, in your code you have
from tkinter import *
# ...
from pynput.mouse import Button, Controller
Later on you had
Button (window, text="Submit", width=6, height=1, command=set_keybind).grid(row=5, column=0)
So, I think the Button is actually a pynput.mouse.Button, not tkinter.Button as you expected, and pynput.mouse.Button is confused with the extra arguments (text to be exact).
That's one reason to avoid doing from package import *, apart from the readability misconceptions.