Label inside Entry in tkinter - python

I have a searchbox that is an Entry in tkinter and I want to have an X-button in the right corner that the user can click on and it will delete everything that was typed in the box. But I cannot fin a solution on how to put a Label or Button inside Entry. Any suggestions?
Thanks in advance

this is an oop solution, init function creates widgets and the clear function deletes the text inside the entry. You can arrange the position of the widgets with pack(), grid() would also work.
here is a similar question: How to clear the Entry widget after a button is pressed in Tkinter?
import tkinter as tk
from tkinter import ttk
class App(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.entryText = ttk.Entry(self)
self.entryText.pack()
self.XButton = ttk.Button(self, text="X-Button", command=self.clear_text).pack()
def clear_text(self):
self.entryText.delete(0, 'end')
if __name__ == "__main__":
root = tk.Tk()
root.geometry('200x100')
App(root).pack()
root.mainloop()

Related

How to create a subclass of ttk.Button correctly (class function doesnt work)?

I want to create Buttons with a text and define a function that prints me the text on the monitor when i press the button.
Everything works well without classes:
from tkinter import *
from tkinter import ttk
def PressButton():
print(FirstButton.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=ttk.Button(ButtonsFrame, text=1, command= PressButton)
FirstButton.grid()
root.mainloop()
"1" is printed on the monitor when I press FirstButton.
Because I want to have a lot of Buttons, I created a class MyButton with the parent ttk.Button:
from tkinter import *
from tkinter import ttk
class MyButton(ttk.Button):
def __init__(self, text):
self.text=text
super().__init__()
self.Button=ttk.Button(ButtonsFrame, text=self.text, command=self.PressButton)
def PressButton(self):
print(self.Button.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(1)
FirstButton.grid()
root.mainloop()
Here a button is created but without text at all.
I found out that if I change the super().__init__() to super()._init__(text=self.text) then I get a Button with the right text but the PressButton command doesnt work. I tried diffent things with *args aswell but had no success.
What am I doing wrong? I would appreciate any help.
The main problem is that you're not specifying the parent widget for the parent in the constructor.
Here's corrected version of code:
from tkinter import *
from tkinter import ttk
class MyButton(ttk.Button):
def __init__(self, parent, text):
self.text=text
super().__init__(parent, text=self.text, command=self.PressButton)
def PressButton(self):
print(self.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(ButtonsFrame, 1)
FirstButton.grid()
root.mainloop()
You could've also swapped super(). with this:
super(MyButton,self).__init__(parent, text=self.text,command=self.PressButton)
Which is equal to super().__init__(parent, text=self.text, command=self.PressButton)
You can read more about it here:
https://docs.python.org/3/library/functions.html#super

Opening a new window using a link in tkinter

How do I open a new window using a link in tkinter .
(For eg : in a login window i want to add a link that says "New user ? click here" and when I click on "click here" it takes me to the register window .
Please help me
enter image description here
[1]: https://i.stack.imgur.com/K5GV0.png
Please click the above link to see the image
Creating new toplevel windows works almost exactly the same as creating new widgets.
Toplevel windows are created using the Toplevel function:
t = Toplevel(parent)
Unlike regular widgets, you don't have to "Grid" a toplevel fo it to appear on screen. Once you've created a toplevel you can add children widgets within and grid them like in the main window. In other words toplevel behaves exactly like the automatic created root window.
To destroy a window use the method:
window.destroy()
You can open new windows in tkinter with the tkinter.Toplevel() command.
import tkinter as tk
class Gui:
"""Gui class"""
def __init__(self):
self.root = tk.Tk()
self.new_window = tk.Button(master=self.root, text="Open new window", width=20, pady=4, command=self.new_window)
self.new_window.pack()
self.root.mainloop()
def new_window(self):
"""Create a new top level window"""
new_window = tk.Toplevel()
tk.Label(master=new_window, text="This is a new window").pack()
if __name__ == '__main__':
Gui()
You can create a function to open a new window and then bind it to that Label, for example:
import tkinter as tk
def newWindow():
# Window object (top level)
newWindow = Toplevel(master)
# Title
newWindow.title("New Window 1")
# Geometry
newWindow.geometry("300x300")
root = tk.Tk()
label = tk.Label(text="Hello!", width=50, height=10, master=root)
label.pack()
label.bind("<Button-1>", newWindow)

Tkinter Toplevel always in front

I am working on a program that uses a tkinter TopLevel window to display periodically updating log information to the user. My problem is that the main program is fullscreen, so whenever they interact with it after opening the log window, the log window isn't visible since it is now behind the main program.
Is there a way to force a Toplevel window (or actually, any Tkinter window) to remain permanently ontop of all other windows?
Consider this quick setup for example:
import tkinter as tk
from tkinter import ttk
class Example(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
self.pack()
btn = ttk.Button(self, text = "Press", command = self.openTopLevel)
btn.pack()
def openTopLevel(self):
topLevelWindow = tk.Toplevel(self)
root = tk.Tk()
main = Example(root)
root.mainloop()
When you Press the button and open the Toplevel Window, it is on top. But if you grab the Frame, move it around, etc, the Toplevel goes behind it. How do I stop that? Or is that not something Tkinter allows me to do?
To make a window stay in front of others in a tkinter application, use attributes('-topmost', 'true'). In your code, it is a one-line to add.
import tkinter as tk
from tkinter import ttk
class Example(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
self.pack()
btn = ttk.Button(self, text = "Press", command = self.openTopLevel)
btn.pack()
def openTopLevel(self):
topLevelWindow = tk.Toplevel(self)
# Make topLevelWindow remain on top until destroyed, or attribute changes.
topLevelWindow.attributes('-topmost', 'true')
root = tk.Tk()
main = Example(root)
root.mainloop()

tkk checkbutton appears when loaded up with black box in it

I create a check button / box, with the following call
x=ttk.Checkbutton(tab1,state='disabled',command = lambda j=i,x=k: fCheckButton(j,x))
x.state(['selected'])
The box appears fine and is selected, but it appears on load up, with a black box in it, which seems to have nothing to do with the state of it.
I have looked for reasons why, but can't actually find anyone with the same problem.
thanks
I hit this problem when creating a Checkbutton object from within a class. I was declaring a local variable instead of a member variable in the class. The local variable was getting out of scope causing the checkbox value to not be either a 0 or a 1.
Wrong:
import tkinter as Tk
from tkinter import IntVar
from tkinter.ttk import Frame, Checkbutton
class TestGui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
var1 = IntVar()
var1.set(1)
button = Checkbutton(parent,
text="Pick me, pick me!",
variable=var1)
button.grid()
root = Tk.Tk()
app = TestGui(root)
root.mainloop()
Fixed:
import tkinter as Tk
from tkinter import IntVar
from tkinter.ttk import Frame, Checkbutton
class TestGui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.var1 = IntVar()
self.var1.set(1)
button = Checkbutton(parent,
text="Pick me, pick me!",
variable=self.var1) # note difference here
button.grid()
root = Tk.Tk()
app = TestGui(root)
root.mainloop()
I've had a similar issue on Windows 7.
After loading the app, one of my checkbuttons contained a filled square. But after clicking on it, it became a normal checkbutton:
In my case, it was because I had multiple checkbuttons sharing the same variable... After creating a separate Tk.IntVar() variable for each checkbutton, the problem disappeared.
import Tkinter as Tk
import ttk
root = Tk.Tk()
checkVar = Tk.IntVar()
x = ttk.Checkbutton(root, variable=checkVar, text="check 1")
x.pack()
checkVar2 = Tk.IntVar()
y = ttk.Checkbutton(root, variable=checkVar2, text="check 2")
y.pack()
root.mainloop()

Using Tkinter in python to edit the title bar

I am trying to add a custom title to a window but I am having troubles with it. I know my code isn't right but when I run it, it creates 2 windows instead, one with just the title tk and another bigger window with "Simple Prog". How do I make it so that the tk window has the title "Simple Prog" instead of having a new additional window. I dont think I'm suppose to have the Tk() part because when i have that in my complete code, there's an error
from tkinter import Tk, Button, Frame, Entry, END
class ABC(Frame):
def __init__(self,parent=None):
Frame.__init__(self,parent)
self.parent = parent
self.pack()
ABC.make_widgets(self)
def make_widgets(self):
self.root = Tk()
self.root.title("Simple Prog")
If you don't create a root window, Tkinter will create one for you when you try to create any other widget. Thus, in your __init__, because you haven't yet created a root window when you initialize the frame, Tkinter will create one for you. Then, you call make_widgets which creates a second root window. That is why you are seeing two windows.
A well-written Tkinter program should always explicitly create a root window before creating any other widgets.
When you modify your code to explicitly create the root window, you'll end up with one window with the expected title.
Example:
from tkinter import Tk, Button, Frame, Entry, END
class ABC(Frame):
def __init__(self,parent=None):
Frame.__init__(self,parent)
self.parent = parent
self.pack()
self.make_widgets()
def make_widgets(self):
# don't assume that self.parent is a root window.
# instead, call `winfo_toplevel to get the root window
self.winfo_toplevel().title("Simple Prog")
# this adds something to the frame, otherwise the default
# size of the window will be very small
label = Entry(self)
label.pack(side="top", fill="x")
root = Tk()
abc = ABC(root)
root.mainloop()
Also note the use of self.make_widgets() rather than ABC.make_widgets(self). While both end up doing the same thing, the former is the proper way to call the function.
Here it is nice and simple.
root = tkinter.Tk()
root.title('My Title')
root is the window you create and root.title() sets the title of that window.
Try something like:
from tkinter import Tk, Button, Frame, Entry, END
class ABC(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
root = Tk()
app = ABC(master=root)
app.master.title("Simple Prog")
app.mainloop()
root.destroy()
Now you should have a frame with a title, then afterwards you can add windows for
different widgets if you like.
One point that must be stressed out is:
The .title() method must go before the .mainloop()
Example:
from tkinter import *
# Instantiating/Creating the object
main_menu = Tk()
# Set title
main_menu.title("Hello World")
# Infinite loop
main_menu.mainloop()
Otherwise, this error might occur:
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 2217, in wm_title
return self.tk.call('wm', 'title', self._w, string)
_tkinter.TclError: can't invoke "wm" command: application has been destroyed
And the title won't show up on the top frame.
Example of python GUI
Here is an example:
from tkinter import *;
screen = Tk();
screen.geometry("370x420"); //size of screen
Change the name of window
screen.title('Title Name')
Run it:
screen.mainloop();
I found this works:
window = Tk()
window.title('Window')
Maybe this helps?
Easy method:
root = Tk()
root.title('Hello World')
Having just done this myself you can do it this way:
from tkinter import Tk, Button, Frame, Entry, END
class ABC(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.parent = parent
self.pack()
ABC.make_widgets(self)
def make_widgets(self):
self.parent.title("Simple Prog")
You will see the title change, and you won't get two windows. I've left my parent as master as in the Tkinter reference stuff in the python library documentation.
For anybody who runs into the issue of having two windows open and runs across this question, here is how I stumbled upon a solution:
The reason the code in this question is producing two windows is because
Frame.__init__(self, parent)
is being run before
self.root = Tk()
The simple fix is to run Tk() before running Frame.__init__():
self.root = Tk()
Frame.__init__(self, parent)
Why that is the case, I'm not entirely sure.
self.parent is a reference to the actual window, so self.root.title should be self.parent.title, and self.root shouldn't exist.
widget.winfo_toplevel().title("My_Title")
changes the title of either Tk or Toplevel instance that the widget is a child of.
I found a solution that should help you:
from tkinter import Tk, Button, Frame, Entry, END
class ABC(Frame):
def __init__(self,master=None):
super().__init__(master)
self.pack()
self.master.title("Simple Prog")
self.make_widgets()
def make_widgets(self):
pass
root = Tk()
app = ABC(master=root)
app.mainloop()
Found at: docs.python.org

Categories

Resources