I am experimenting with Tkinter to build a simple UI. This will contain a similar structure to the below:
Menu
Settings
Action1
Etc...
I want Menu to be my main frame, and there to be some general stuff on there and then buttons to the other frames.
I have been using some code I found here as a baseline but my amendments failed to work as expected. For example, why do the Label's and Entry's I place not show?
Code is as follows:
import tkinter as tk
def raise_frame(frame):
frame.tkraise()
root = tk.Tk()
root.title("Name")
width=400
height=500
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
f1 = tk.Frame(root)
f2 = tk.Frame(root)
f3 = tk.Frame(root)
f4 = tk.Frame(root)
title = tk.Label(f1, text = "Title", background = '#3b5997', foreground ="white", font = ("Times New Roman", 25))
title.place(x=100,y=20,width=200,height=50)
eg1 = tk.Label(f1, text="Text :")
eg1.place(x=10,y=195,width=70,height=25)
eg2 = tk.Label(f1, text="Text")
eg2.place(x=290,y=195,width=70,height=25)
eg3 = tk.Entry(f1, width=20)
eg3.place(x=100,y=195,width=200,height=25)
raise_frame(f1)
root.mainloop()
I have used .grid() and pack() but never used place however I found the issue.
you need to use .place() for frame f1 as well, after the content that you want in that frame.
import tkinter as tk
def raise_frame(frame):
frame.tkraise()
root = tk.Tk()
root.title("Name")
width=400
height=500
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
f1 = tk.Frame(root)
f2 = tk.Frame(root)
f3 = tk.Frame(root)
f4 = tk.Frame(root)
title = tk.Label(f1, text = "Title", background = '#3b5997', foreground ="white", font = ("Times New Roman", 25))
title.place(x=100,y=20,width=200,height=50)
eg1 = tk.Label(f1, text="Text :")
eg1.place(x=10,y=195,width=70,height=25)
eg2 = tk.Label(f1, text="Text")
eg2.place(x=290,y=195,width=70,height=25)
eg3 = tk.Entry(f1, width=20)
eg3.place(x=100,y=195,width=200,height=25)
f1.place(x=100,y=20,width=1000,height=900) # <-------------like this
raise_frame(f1)
root.mainloop()
Related
When I create the scroll bar there seems to be no option to scroll even though the contents inside of it are bigger than the canvas.
The canvas is inside a frame as I heard this is the way to do this properly.
The relevant part of my code:
from tkinter import *
class UniversityProcessor:
def __init__(self):
self.root = Tk()
self.rootWidth, self.rootHeight = 1200, 1200
screenWidth, screenHeight = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
xPosition, yPosition = (screenWidth/2) - (self.rootWidth/2), (screenHeight/2) - (self.rootHeight/2)
self.root.geometry("%dx%d+%d+%d"%(self.rootWidth, self.rootHeight, xPosition, yPosition))
self.root.title("University processor")
self.updateUniText()
self.root.mainloop()
def updateUniText(self):
self.textPixelTotal = 0
self.frame = Frame(self.root, bg = self.bg, width = self.rootWidth, height = self.rootHeight)
self.frame.pack()
self.canvas = Canvas(self.frame, bg = self.bg, width = self.rootWidth, height = self.rootHeight)
self.inner = Frame(self.canvas, bg = self.bg, width = self.rootWidth, height = self.rootHeight)
self.canvas.create_window((0, 0), window = self.inner, anchor = "nw")
for it in range(0, 50):
label = Label(self.inner, bg = self.bg, text = f"Title {it + 1}", font = ("Arial", 20, "bold"))
label.place(y = self.textPixelTotal, x = it)
self.canvas.update()
self.textPixelTotal += label.winfo_height()
self.inner.configure(height = self.textPixelTotal)
self.inner.place(x=0,y=0,anchor="nw")
self.scroll = Scrollbar(self.frame, orient = VERTICAL, command = self.canvas.yview)
self.scroll.pack(side = RIGHT, fill = Y)
self.canvas.configure(yscrollcommand = self.scroll.set)
self.canvas.bind("<Configure>", lambda e: self.canvas.configure(scrollregion = self.canvas.bbox("all")))
self.canvas.pack(side=LEFT, expand=True, fill=BOTH)
UniversityProcessor()
I have no idea if there's some kind of canvas property or scroll bar property I need to set but it fills the screen...
Scroll bar does appear, it's the correct size however no scrolling actually happens
You should not use place() to put labels inside canvas. You need to create an internal frame inside the canvas and put all the labels inside that frame:
def updateUniText(self):
textPixelTotal = 0
self.frame = Frame(self.root, width=self.rootWidth, height=self.rootHeight)
self.frame.pack()
self.background = Canvas(self.frame, width=self.rootWidth, height=self.rootHeight)
# an internal frame inside canvas
self.internal = Frame(self.background)
self.background.create_window(0, 0, window=self.internal, anchor="nw")
# create labels inside the internal frame
for i in range(0,200):
label = Label(self.internal, bg=self.bg, text=f"Title {i+1}", font=("Arial", 20, "bold"))
label.pack(anchor="w")
self.background.update()
self.scroll = Scrollbar(self.frame, orient=VERTICAL)
self.scroll.pack(side=RIGHT, fill=Y)
self.scroll.config(command=self.background.yview)
self.background.config(width=self.rootWidth-20, height=self.rootHeight)
self.background.config(yscrollcommand=self.scroll.set, scrollregion=self.background.bbox("all"))
self.background.pack(side=LEFT, expand=True, fill=BOTH)
I'm trying to write a simple Tkinter form. It should read user's input, and then display the result when clicking a button.
However, my code doesn't return anything. I found this thread:
Python Tkinter Entry get()
But still nothing I do returns me the text that users entered.
This is my script. Your help is appreciated:
import tkinter as tk
import tkinter.font as tkFont
class App:
def __init__(self, root):
# setting title
root.title("undefined")
# setting window size
global result
width = 600
height = 500
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
LineEdit = tk.Entry(root)
LineEdit["borderwidth"] = "2px"
LineEdit.place(x=250, y=50, width=289, height=30)
result = LineEdit.get()
LineLabel = tk.Label(root)
LineLabel["text"] = "Enter Your Input:"
LineLabel.place(x=60, y=50, width=177, height=30)
GoButton = tk.Button(root)
GoButton["text"] = "Analyze"
GoButton.place(x=170, y=130, width=195, height=58)
GoButton["command"] = self.DisplayInput
def DisplayInput(self):
print(result)
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
You should get the content of LineEdit inside DisplayInput(). But you need to change LineEdit to instance variable self.LineEdit, otherwise it cannot be accessed inside DisplayInput():
import tkinter as tk
import tkinter.font as tkFont
class App:
def __init__(self, root):
# setting title
root.title("undefined")
# setting window size
#global result
width = 600
height = 500
screenwidth = root.winfo_screenwidth()
screenheight = root.winfo_screenheight()
alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
root.geometry(alignstr)
root.resizable(width=False, height=False)
self.LineEdit = tk.Entry(root)
self.LineEdit["borderwidth"] = "2px"
self.LineEdit.place(x=250, y=50, width=289, height=30)
#result = LineEdit.get()
LineLabel = tk.Label(root)
LineLabel["text"] = "Enter Your Input:"
LineLabel.place(x=60, y=50, width=177, height=30)
GoButton = tk.Button(root)
GoButton["text"] = "Analyze"
GoButton.place(x=170, y=130, width=195, height=58)
GoButton["command"] = self.DisplayInput
def DisplayInput(self):
result = self.LineEdit.get()
print(result)
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
import tkinter as tk
from tkinter import *
import pyautogui
root = tk.Tk()
#label = tk.Label(root, text='you coomand hacking', font= ('Times New Roman','80'), fg='black', bg='white')
#label.pack()
root.title("Wallpaper")
wall = PhotoImage(file = "20170227180026_3.gif")
wall_label = Label(image = wall)
root.geometry(f"{wall.width()}x{wall.height()}")
root.overrideredirect(True)
currentMouseX,currentMouseY = pyautogui.position()
print(f'{currentMouseX} {currentMouseY}')
root.geometry("+0+0")
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")
wall_label.place(x = -2,y = -2)
root.after(1000 , root.destroy)
#root.geometry("+{}+{}".format(currentMouseX,currentMouseY))
root.geometry("+{}+{}".format(currentMouseX,currentMouseY))
root.mainloop()
root.after(1000 , root.destroy)
root.geometry("+{}+{}".format(currentMouseX,currentMouseY))
Please understand even if the source code is dirty.
What I want is for the image to follow the mouse
I tried to follow the mouse by repeating the image disappearing and appearing, but it is not easy.
Here. I made the image follow the mouse, without pyautogui.
Code:
import tkinter as tk
from tkinter import *
#import pyautogui
root = tk.Tk()
#label = tk.Label(root, text='you coomand hacking', font= ('Times New Roman','80'), fg='black', bg='white')
#label.pack()
root.title("Wallpaper")
wall = PhotoImage(file = "20170227180026_3.gif")
c = Canvas(root, height = 1200, width = 1200)
c.pack()
pic = c.create_image(600, 600, image = wall)
def movepic(event):
x,y = event.x, event.y
c.coords(pic, x, y)
c.bind_all("<Motion>", movepic)
root.mainloop()
In this code, entering an integer and clicking the process button shows a number of entry boxes. I want the back button to act as a reverting button which makes the entry boxes disappear and bring the GUI to its original state. How can I do this?
import tkinter as tk
import tkinter.ttk as ttk
hht=[]
tks = []
window = tk.Tk()
def open_window(pll):
numh = int(pll)
l0 = tk.Label(canvas, text="H T", font="Calibri 12", bg="white")
canvas.create_window(390,125, window=l0, anchor=tk.NW)
for i in range(numh):
hht.append(tk.StringVar())
tks.append(tk.StringVar())
en = ttk.Entry(canvas, textvariable = hht[i])
en.config({"background": "gainsboro"})
canvas.create_window(350, 150+i*25, window=en, anchor=tk.NW)
aen = ttk.Entry(canvas, textvariable = tks[i])
aen.config({"background": "gainsboro"})
canvas.create_window(500, 150+i*25, window=aen, anchor=tk.NW)
ws = window.winfo_screenwidth()
hs = window.winfo_screenheight()
w = 700 # width for the Tk root
h = 410 # height for the Tk root
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
window.geometry('%dx%d+%d+%d' % (w, h, x, y))
canvas = tk.Canvas(window,bg="white",width=700, height=410, highlightthickness=0)
canvas.pack()
l13= tk.Label(canvas, text="Enter Numbers", font="Calibri 16", bg="white")
canvas.create_window(300,8, window=l13, anchor=tk.NW)
l0 = tk.Label(canvas, text="Entry", font="Calibri 12", bg="white")
canvas.create_window(15,58, window=l0, anchor=tk.NW)
PLz = tk.DoubleVar()
entry_PLz = ttk.Entry(canvas, textvariable=PLz)
entry_PLz.config({"background": "gainsboro"})
canvas.create_window(270,70, window=entry_PLz)
submit_button = ttk.Button(canvas, text="Process >>", command=lambda: open_window(PLz.get()))
canvas.create_window(300, 100, window=submit_button, anchor=tk.NW)
back_button = ttk.Button(canvas, text="Back")
canvas.create_window(450, 100, window=back_button, anchor=tk.NW)
window.resizable(False, False)
window.mainloop()
Help! I am using python 3.5.2 and the function self.new_game is not working. It is supposed to put text on the canvas but it does nothing! There are also no errors that appear in the shell.
from tkinter import *
import time
import os
WIDTH = 1920
HEIGHT = 1080
root = Tk()
root.state('zoomed')
planet_selected = 0
planet_name = "nothing"
planet_temp = -270
planet_size = 0.0
planet_life = 0.0
class Space(Frame):
def __init__(self):
Frame.__init__(self)
frame1 = Frame(self)
self.canvas = Canvas(frame1, width = WIDTH, height = HEIGHT, bg ="white")
self.canvas.focus_set()
self.canvas.create_text(1920,1000,text='Planetary Creator',font=('Arial',15))
self.master.title("Planetary Creator Alpha 0.1")
frame = Frame(root, bg='grey', width=1920, height=40)
frame.pack(fill='x')
button1 = Button(frame, text='New Game',command=lambda : self.new_game())
button1.pack(side='left', padx=10)
button2 = Button(frame, text='Quit Game',command=lambda : os._exit(0))
button2.pack(side='left')
#this function below does not work!!!
def new_game(self):
self.canvas.delete(ALL)
size = self.canvas.create_text(960,540,text=str(planet_size) + "moon",font=("Arial",10))
life = self.canvas.create_text(960,520,text="✣" + str(planet_life) + "%",font=("Arial",10))
temp = self.canvas.create_text(960,500,text=str(planet_temp) + "°C",font=("Arial",10))
name = self.canvas.create_text(960,480,text=planet_name,font=("Arial",15))
Space().mainloop()
I removed frame1 and put Canvas in root , and use canvas.pack() to see canvas in window.
(but I could use self instead of root and use self.pack() because Space inherits from Frame. it would ne more logical)
After that I had to only change text positions because windows was too big for my screen.
I used variables CENTER_X, CENTER_Y to put text in center regardless of the size of the screen.
from tkinter import *
import time
import os
class Space(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master.title("Planetary Creator Alpha 0.1")
self.canvas = Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
self.canvas.pack()
self.canvas.focus_set()
self.canvas.create_text(CENTER_X, CENTER_Y, text='Planetary Creator', font=('Arial',15))
frame = Frame(root, bg='grey', width=WIDTH, height=40)
frame.pack(fill='x')
button1 = Button(frame, text='New Game', command=self.new_game)
button1.pack(side='left', padx=10)
button2 = Button(frame, text='Quit Game', command=root.destroy)
button2.pack(side='left')
def new_game(self):
self.canvas.delete(ALL)
size = self.canvas.create_text(CENTER_X, CENTER_Y, text=str(planet_size) + "moon", font=("Arial",10))
life = self.canvas.create_text(CENTER_X, CENTER_Y-20, text="✣" + str(planet_life) + "%", font=("Arial",10))
temp = self.canvas.create_text(CENTER_X, CENTER_Y-40, text=str(planet_temp) + "°C", font=("Arial",10))
name = self.canvas.create_text(CENTER_X, CENTER_Y-60, text=planet_name, font=("Arial",15))
# --- main ---
WIDTH = 800 #1920
HEIGHT = 500 #1080
CENTER_X = WIDTH//2
CENTER_Y = HEIGHT//2
planet_selected = 0
planet_name = "nothing"
planet_temp = -270
planet_size = 0.0
planet_life = 0.0
root = Tk()
#root.state('zoomed')
Space(root)
root.mainloop()