I am trying to open a toplevel window with a label from a function call but the label is not showing. What am I doing wrong?
Gratias.
from tkinter import *
import tkinter.font as fonte
def open_top():
top = Toplevel(master)
top.geometry("375x238+789+479")
top.resizable(width=FALSE, height=FALSE)
topFont = fonte.Font(family='Ubuntu', size=40)
label = Label(top, text='world', borderwidth=2, relief="sunk", width=24)
label.config(font = topFont, height=11, wraplength=350)
label.grid(row = 0, column = 0, columnspan=1, rowspan=1, sticky=W+E+N+S)
master.update()
# creating main tkinter window
master = Tk()
master.geometry("374x340+790+100")
master.resizable(width=FALSE, height=FALSE)
myFont = fonte.Font(family='Monospace', size=25)
view = Label(master, text='helo', borderwidth=2, relief="sunk", width=10)
view.config(font = ('Monospace', 36), height=3)
view.grid(row = 4, column = 0, columnspan=2, rowspan=1, sticky=W+E+N+S, padx=5, pady=5)
btn = Button(master, text ='toplevel', command = lambda: open_top())
btn.grid(row=6, column=0, columnspan=1, pady=4, padx=4)
btn = Button(master, text='Quit', command=master.destroy)
btn.grid(row=6, column=1, columnspan=1, pady=4, padx=4)
mainloop()
First about the problem:
When you create the label, you specify the width (and later) height arguments. Since your label contains text the units you pass as values to those arguments represent characters for width and lines for height (You can read about those attributes here)
#TheLizzard mention: wraplength's value also is in characters, and since you have set it to 350 and your font is not that small, it will wrap the text when a huge part of it is out of the window (and quite possibly even out of the screen) so with the current value it is quite useless. (it is also quite useless if you add static text because then you can simply add a newline or sth, a use case would be when you don't know how long the text is, for example, it was taken from user input)
Possible fixes:
Remove the width and height arguments (really the easiest):
label = Label(top, text='world', borderwidth=2, relief="sunk")
label.config(font=topFont, wraplength=350)
The widget can be also configured all at once, you don't need to use its method like this for initialization:
label = Label(top, text='world', borderwidth=2, relief="sunk", font=topFont, wraplength=350)
Change the height and width values (width tho really doesn't have to be used, especially if you use the wraplength argument):
label = Label(top, text='world', borderwidth=2, relief="sunk", font=topFont, wraplength=350, height=1)
Use anchor (really not that much of a fix or anything but will allow you to see the text (to an extent)):
label.config(anchor='nw')
Few other things:
Important (suggestions)
I strongly advise against using wildcard (*) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2 and so on or import the whole module: import module then You can also use an alias: import module as md or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.
Also: I strongly suggest following PEP 8 - Style Guide for Python Code. Function and variable names should be in snake_case, class names in CapitalCase. Don't have space around = if it is used as a part of keyword argument (func(arg='value')) but use if it is used for assigning a value (variable = 'some value'). Have two blank lines around function and class declarations.
Related
I am using Tkinter with Python2 to create a new window by clicking on the button. In this new window I want to Display text. Now I have Troubles with the alignment, is it possible to align it to the left? It is always centered and neither anchor=LEFT nor sticky="NSEW" help.
import tkinter as tki
btn3 = tki.Button(self.root, text="HELP", command=self.help, fg="black", bg="white", font=("Courier",22))
btn3.grid(row=1, column=2, padx=10, pady=10, sticky="NSEW" )
def help(self):
self.text = """ Hello.
You can find help here to the following subjects:
- getting started
- installation
- FAQ."""
self.top = tki.Toplevel()
self.top.title("Help")
self.label1 = tki.Label(self.top, text = self.text, height = 0, width=80, fg="black", bg="white", font=("Courier",18))
self.label1.pack()
When you use anchor = n you need to put anchor = "n" i.e. with the n in quotes. You're getting the global name is not defined error because of this.
Alternatively, use anchor = tki.N. Because you used import tkinter as tki you must prefix tkinter variables with tki. in order for python to know what you're referring to. However, I think you might want to try justify=tki.LEFT also if that doesn't work.
How do I align my Radiobuttons? I can add spaces to test4 but that solution doesn't seem proper. Here's what it looks like at the moment—as you can see text111111 has extra chars. I've tried using padx.
My code:
from tkinter import *
class GUI:
def __init__(self, master):
self.iconnum = IntVar()
self.master = master
self.master.title('test')
self.master.resizable(width=False, height=False)
self.master.maxsize(500, 250)
self.master.minsize(500, 250)
self.test1 = Radiobutton(master, text="test11111111", variable=self.iconnum,
value=1, )
self.test2 = Radiobutton(master, text="test2", variable=0, value=2, )
self.test3 = Radiobutton(master, text="test3", variable=0, value=3, )
self.test4 = Radiobutton(master, text="test4", variable=0, value=4)
self.test1.grid(row=2, columnspan=1)
self.test2.grid(row=2, columnspan=2)
self.test3.grid(row=2, column=1)
self.test4.grid(row=3, columnspan=1)
self.Checker = Radiobutton(master, text="test5", indicatoron=0, height=1, width=35,
value=0, command=self.icon_switcher) #var=Selection)
self.Turbo = Radiobutton(master, text="test6", indicatoron=0, height=1, width=35,
value=1, command=self.icon_switcher) #var#=Selection)
self.Checker.grid(row=1)
self.Turbo.grid(row=1, column=1, )
def icon_switcher(self):
print("Hello")
root = Tk()
gui = GUI(root)
root.mainloop()
You should use the sticky keyword argument in order to align your widgets better when using grid.
import Tkinter as tk
window = tk.Tk()
radio = tk.Radiobutton(window, text="I'm a radio")
radio.grid(column=0, row=0, sticky=tk.N+tk.S+tk.W+tk.E)
window.mainloop()
You can use any combination of the N, S, W and E members of the Tkinter module. This parameter will make your widgets stick to the sides of the cell you have specified, somewhat like justification in text. If your widget is resizable, such as with Button, the widget will also automatically resize to fit the cell if you use all of the N, S, W and E members.
Important to note is that this can only do so much as to make the widgets stick to the edges of the cell. Sometimes it is necessary to actually resize the cell or move your widget to another cell.
In your example image, you have Buttons with a set size that is larger than the default size (the example code you provide is incomplete). This causes the cell, and the whole columns that the cells of these Buttons are in, to become wider. In this case, you might want to use the columnspan keyword argument to divide your column into smaller, resizable, parts, so that your Radiobuttons can be aligned still better.
import Tkinter as tk
window = tk.Tk()
radio_one = tk.Radiobutton(window, text="I'm a radio")
radio_two = tk.Radiobutton(window, text="I'm another radio")
button = tk.Button(window, text="I am a very long button", width=50)
button.grid(row=0, column=0, columnspan=2, sticky=tk.N+tk.S+tk.W+tk.E)
radio_one.grid(column=0, row=1, sticky=tk.N+tk.W)
radio_two.grid(column=1, row=1, sticky=tk.N+tk.W)
window.mainloop()
If you would like more information on what parameters the grid geometry manager can use, I suggest you read this tutorial, I have found it to be very helpful in the past.
As a sidenote, please note that you use the variable keyword argument in the declaration of your Radiobuttons incorrectly. You must pass either a tk.StringVar, tk.IntVar or some other comparable object, as described here.
You can use sticky=W inside your .grid for all your buttons to make them align on the left side. And you can also include pady = 20 to make it not go all the way to the left.
Python 3.4.0.
Could you help me understand what is going on here:
from tkinter import *
root = Tk()
f = Frame(root, borderwidth=2) #
for relief in [RAISED, SUNKEN, FLAT, RIDGE, GROOVE, SOLID]:
Label(f, text=relief, width=10, relief = relief).pack(side=LEFT) #
#f = Frame(root, borderwidth=2, relief = relief)
#Label(f, text=relief, width=10).pack(side=LEFT)
f.pack(side=LEFT, padx=5, pady=5)
root.mainloop()
If I uncomment now commented lines and comment the lines that hafe '#' mark at the end, the result is the same.
First case: the present situation. It is understandable to me. Before the loop we create a frame. Then pack method places each label in the parent widget (which is f). In this case f expands and contains several labels.
Well, the second case: if I switch the comment marks.
A frame f is always new. Label is also always new. A label is always placed on a separate frame. I would suggest that 5 frames would be displayed with a different label in each frame.
Could you help me understand why the result is the same?
Sounds like you want five separate windows, each of which can be moved, closed, etc.
If so, you should use the Toplevel widget instead of Frame.
from tkinter import *
root = Tk()
for relief in [RAISED, SUNKEN, FLAT, RIDGE, GROOVE, SOLID]:
t = Toplevel(root, borderwidth=2, relief = relief)
Label(t, text=relief, width=10).pack(side=LEFT)
root.mainloop()
I am trying to clear the text box i typed already with a Button 'Clear'.But its not clearing the text once the button is clicked!
Please fix my problem!Answer will be appreciated!
import tkinter as tki
class App(object):
def __init__(self,root):
self.root = root
txt_frm = tki.Frame(self.root, width=600, height=400)
txt_frm.pack(fill="both", expand=True)
# ensure a consistent GUI size
txt_frm.grid_propagate(False)
self.txt1 = tki.Text(txt_frm, borderwidth=3, relief="sunken", height=4,width=55)
self.txt1.config(font=("consolas", 12), undo=True, wrap='word')
self.txt1.grid(row=0, column=1, sticky="nsew", padx=2, pady=2)
button1 = tki.Button(txt_frm,text="Clear", command = self.clearBox)
button1.grid(column=2,row=0)
def clearBox(self):
self.txt1.delete(0, END)
root = tki.Tk()
app = App(root)
root.mainloop()
Since END is in tkinter you need to use tki.END or "end" (with quotes, lower case) also your starting index should be "1.0"(thanks to BryanOakley) instead of 0.
This one should work.
def clearBox(self):
self.txt1.delete("1.0", "end")
EDIT: By the way it will be better if you use pack_propagate instead of grid_propagate since you used pack to place your frame.
EDIT2: About that index thing, it is written in here under lines and columns section.
...Line numbers start at 1, while column numbers start at 0...
Note that line/column indexes may look like floating point values, but it’s seldom possible to treat them as such (consider position 1.25 vs. 1.3, for example). I sometimes use 1.0 instead of “1.0” to save a few keystrokes when referring to the first character in the buffer, but that’s about it.
I create a LabelFrame widget. It has a nice size in the beginning:
import Tkinter
form = Tkinter.Tk()
errorArea = Tkinter.LabelFrame(form, text=" Errors ", width=250, height=80)
errorArea.grid(row=2, column=0, columnspan=2, sticky="E", \
padx=5, pady=0, ipadx=0, ipady=0)
But when I insert an empty string in it, the errorArea widget's size adjusts according to the inserted string:
errorMessage = Tkinter.Label(errorArea, text="")
errorMessage.grid(row=0, column=0, padx=5, pady=2, sticky='W')
How do I give the errorArea widget a fixed size, so that its size won't change according to Lable inserted in it?
That problem always was interesting to me. One way I found to fix it is by using the place method instead of grid:
import Tkinter
form = Tkinter.Tk()
errorArea = Tkinter.LabelFrame(form, text=" Errors ", width=250, height=80)
errorArea.grid(row=2, column=0, columnspan=2, sticky="E", \
padx=5, pady=0, ipadx=0, ipady=0)
errorMessage = Tkinter.Label(errorArea, text="")
# 1) 'x' and 'y' are the x and y coordinates inside 'errorArea'
# 2) 'place' uses 'anchor' instead of 'sticky'
# 3) There is no need for 'padx' and 'pady' with 'place'
# since you can specify the exact coordinates
errorMessage.place(x=10, y=10, anchor="w")
form.mainloop()
With this, the label is placed in the window without shrinking the labelframe.
If you use a sticky value that sticks the widget to all four sides of its cell rather than just one side, it won't shrink when you put a small label widget in it.
Another option is to call errorArea.grid_propagate(False), which tells the grid area not to shrink or expand to fit its contents. This will often result in undesirable resize behavior, or at least require you to do a little extra work to get the right resize behavior.
Use the grid function immediately after declaring the Labelframe.
EX :
String_l = ttk.Labelframe(pw, text='String',width=100, height=408).grid(column=1, row=0, padx=4, pady=4,rowspan=2)