I started working on the code, and when I put the widgets in places, there was a problem, the widgets move down
I.e. on pressing the button that adds more "entry" fields
they appear very crooked, and I do not know why, what to do with this, and what I did wrong?
1: https://i.stack.imgur.com/b8DBm.png - a picture of my problem
import tkinter as tk
from tkinter import ttk
import requests
import time
from tkinter import *
from tkinter import messagebox
window = Tk()
window.geometry('400x700')
window.title("SiteChecker")
def clicked():
txt = Entry(window, width=18)
txt.grid(column=0, pady=8)
tim = Entry(window, width=3)
tim.grid(column=1, pady=8)
lbl1 = Label(window, text="Enter links: ")
lbl1.grid(column=0, row=1)
lbl2 = Label(window, text="Enter the test time: ")
lbl2.grid(column=1, row=1)
lbl3 = Label(window, text="Availability status ")
lbl3.grid(column=2, row=1)
txt1 = Entry(window,width=18)
txt1.grid(column=0, row=2, pady=8)
txt2 = Entry(window,width=18)
txt2.grid(column=0, row=3,pady=8)
txt3 = Entry(window,width=18)
txt3.grid(column=0, row=4,pady=8)
txt4 = Entry(window,width=18)
txt4.grid(column=0, row=5,pady=8)
txt5 = Entry(window,width=18)
txt5.grid(column=0, row=6,pady=8)
tim1 = Entry(window,width=3)
tim1.grid(column=1, row=2, pady=8)
tim2 = Entry(window,width=3)
tim2.grid(column=1, row=3, pady=8)
tim3 = Entry(window,width=3)
tim3.grid(column=1, row=4, pady=8)
tim4 = Entry(window,width=3)
tim4.grid(column=1, row=5, pady=8)
tim5 = Entry(window,width=3)
tim5.grid(column=1, row=6, pady=8)
btn = Button(window, text="Add more site", command=clicked)
btn.grid(column=1, row = 0)
window.mainloop()
The new line isn't "crooked." The second Entry widget is being placed on the next row, because the row value auto-increments in calls to .grid() if not declared.
You could just keep track of on which row you want to place the new pair of widgets. Or, you can place the first one, which works as expected. Then ask the layout manager on which row it placed the first one, and then place the second widget on that same row.
Here's the code that does that:
def clicked():
txt = Entry(window, width=18)
txt.grid(column=0, pady=8)
txt_row = txt.grid_info()['row'] # the row the widget was mapped onto
tim = Entry(window, width=3)
tim.grid(row=txt_row, column=1, pady=8) # put the 2nd widget on the same row
Related
I wanted to write a code that will check the availability of sites using "status_code"
But in the end I got into a stupor, I do not know how to implement the verification of each site entered into the widgets
I manage to check only one site from one widget, but I need to check each one, and set a time for each site to check
I would like to know, or at least get hints on how to implement it
I will be grateful for any help
My attempt:
import tkinter as tk
from tkinter import ttk
import requests
import time
from tkinter import *
from tkinter import messagebox
window = Tk()
window.geometry('400x700')
window.title("SiteChecker")
def SiteCheck():
res=int(tim1.get())
Site_Value = txt1.get()
Get_Response = requests.get(Site_Value)
time.sleep(res)
if Get_Response.status_code != 200:
#as I understand it, you need to make a "for" loop, but I don't understand how to implement
def clicked():
txt = Entry(window, width=18)
txt.grid(column=0, pady=8)
txt_row = txt.grid_info()['row']
tim = Entry(window, width=3)
tim.grid(row=txt_row, column=1, pady=8)
lbl1 = Label(window, text="Enter references:")
lbl1.grid(column=0, row=1)
lbl2 = Label(window, text="Enter the test time: ")
lbl2.grid(column=1, row=1)
lbl3 = Label(window, text="Availability status ")
lbl3.grid(column=2, row=1)
txt1 = Entry(window,width=18)
txt1.grid(column=0, row=2, pady=8)
txt2 = Entry(window,width=18)
txt2.grid(column=0, row=3,pady=8)
txt3 = Entry(window,width=18)
txt3.grid(column=0, row=4,pady=8)
txt4 = Entry(window,width=18)
txt4.grid(column=0, row=5,pady=8)
txt5 = Entry(window,width=18)
txt5.grid(column=0, row=6,pady=8)
tim1 = Entry(window,width=3)
tim1.grid(column=1, row=2, pady=8)
tim2 = Entry(window,width=3)
tim2.grid(column=1, row=3, pady=8)
tim3 = Entry(window,width=3)
tim3.grid(column=1, row=4, pady=8)
tim4 = Entry(window,width=3)
tim4.grid(column=1, row=5, pady=8)
tim5 = Entry(window,width=3)
tim5.grid(column=1, row=6, pady=8)
result1 = Label(window,text="status")
result1.grid(column=2, row=2, pady=8)
result2 = Label(window,text="status")
result2.grid(column=2, row=3, pady=8)
result3 = Label(window,text="status")
result3.grid(column=2, row=4, pady=8)
result4 = Label(window,text="status")
result4.grid(column=2, row=5, pady=8)
result5 = Label(window,text="status")
result5.grid(column=2, row=6, pady=8)
btn = Button(window, text="Add another site", command=clicked)
btn.grid(column=1, row = 0)
Check_Button = Button(
window,
command = SiteCheck,
text='Start checking',
)
Check_Button.grid(row=0, column=2)
window.mainloop()
try this but i am do it without time sleep you can add later
import tkinter as tk
from tkinter import ttk
import requests
import time
from tkinter import *
from tkinter import messagebox
data_list = []
window = Tk()
window.geometry('400x700')
window.title("SiteChecker")
def set_input(obj, value):
obj.delete(1.0, "END")
obj.insert("END", value)
def SiteCheck():
#res=int(tim1.get())
#time.sleep(res)
for data in data_list:
url = data[0].get()
status = data[2]
if not str(url).startswith('http'):
continue
print(url)
Get_Response = None
try:
Get_Response = requests.get(url)
except:
status.config(text = 'status bad')
continue
if Get_Response.status_code == 200:
status.config(text = 'status ok')
pass
#as I understand it, you need to make a "for" loop, but I don't understand how to implement
else:
status.config(text = 'status bad')
def clicked():
txt = Entry(window, width=18)
txt.grid(column=0, pady=8)
txt_row = txt.grid_info()['row']
tim = Entry(window, width=3)
tim.grid(row=txt_row, column=1, pady=8)
txt_row = tim.grid_info()['row']
result1 = Label(window,text="status")
result1.grid(row=txt_row, column=2, pady=8)
data_list.append([txt, tim, result1])
lbl1 = Label(window, text="Enter references:")
lbl1.grid(column=0, row=1)
lbl2 = Label(window, text="Enter the test time: ")
lbl2.grid(column=1, row=1)
lbl3 = Label(window, text="Availability status ")
lbl3.grid(column=2, row=1)
for loop in range(2 ,6):
txt1 = Entry(window,width=18)
txt1.grid(column=0, row=loop, pady=8)
tim1 = Entry(window,width=3)
tim1.grid(column=1, row=loop, pady=8)
result1 = Label(window,text="status")
result1.grid(column=2, row=loop, pady=8)
data_list.append([txt1, tim1, result1])
btn = Button(window, text="Add another site", command=clicked)
btn.grid(column=1, row = 0)
Check_Button = Button(
window,
command = SiteCheck,
text='Start checking',
)
Check_Button.grid(row=0, column=2)
window.mainloop()
Whenever I try to move individual widgets or click a button that produces words effectively moving other widgets that had nothing to do those both specified actions above.
Here is my code:
import tkinter as tk
# Create the main window
window = tk.Tk()
window.title("Price Calculator")
window.geometry("800x600")
window.config(background = "#777474")
def calculate_price():
global input_field
input_field_value = input_field.get()
try:
input = int(input_field_value)
price = input* 0.1
answer.config(text = (f"Your price is ","%.3f"%price,"KWD"))
except ValueError as ve:
answer.config(text = 'What you have just entered are not numbers whatsoever, try again!', fg = "#CD5F66")
price_input = tk.Label(window, text = "Total Pages:", font = "Arial", bg = "#777474", fg = "#FEFCF2")
price_input.grid(column = 0, row = 0)
input_field = tk.Entry(window, font = "Arial", bg = "#FEFCF2")
input_field.grid(column = 1, row = 0, padx = 0,pady = 10)
answer = tk.Label(window, bg = "#777474")
answer.grid(pady = 20)
button_return = tk.Button(window, text = "Calculate Price", command = calculate_price).grid()
# Run the main loop
window.mainloop()
This is my GUI before I click on the button which is called "Calculate Price":
This is my GUI after I have clicked on the button:
The problem here is that I don't want the Total Pages and the entry field to move away from each other whenever I click on the button.
I would suggest to put price_input and input_field into a frame for easier layout management. I also use sticky="w" on the frame, answer and button_return so that they are aligned at the left.
Below is the modified code:
import tkinter as tk
FGCOLOR = "#FEFCF2"
BGCOLOR = "#777474"
ERRCOLOR = "#FF5F66"
# Create the main window
window = tk.Tk()
window.title("Price Calculator")
window.geometry("800x600")
window.config(background="#777474")
def calculate_price():
input_field_value = input_field.get()
try:
input = int(input_field_value)
price = input * 0.1
answer.config(text=f"Your price is {price:.3f} KWD", fg=FGCOLOR)
except ValueError as ve:
answer.config(text='What you have just entered are not numbers whatsoever, try again!', fg=ERRCOLOR)
# create a frame for price_input and input_field
frame = tk.Frame(window, bg=BGCOLOR)
frame.grid(column=0, row=0, padx=10, pady=10, sticky="w")
price_input = tk.Label(frame, text="Total Pages:", font="Arial", bg=BGCOLOR, fg=FGCOLOR)
price_input.grid(column=0, row=0)
input_field = tk.Entry(frame, font="Arial", bg=FGCOLOR)
input_field.grid(column=1, row=0)
answer = tk.Label(window, bg=BGCOLOR)
answer.grid(column=0, row=1, padx=10, pady=10, sticky="w")
button_return = tk.Button(window, text="Calculate Price", command=calculate_price)
button_return.grid(column=0, row=2, sticky="w", padx=10, pady=10)
# Run the main loop
window.mainloop()
I am trying to align three button at the top of my widget side by side and fill "Y" and "X" without changing the placement of the text widget which is just under them. I tried to place the button side by side using those anchor=NW,N,NE but it's not working i don't how to tell it in English, so here is an image of what I got:
Here is my code:
root = Tk()
screen_x = int(root.winfo_screenwidth())
screen_y = int(root.winfo_screenheight()) - int(root.winfo_screenheight()) * int(9.1145833333) // 100
window_x = 512
window_y = 690
posX = (screen_x // 2) - (window_x // 2)
posY = (screen_y // 2) - (window_y // 2)
geo = "{}x{}+{}+{}". format(window_x, window_y, posX, posY)
root.geometry(geo)
root.resizable(0,0)
root.title("StoryApp")
root.config(background="gray8")
photo2 = PhotoImage(file = "Newico.png")
root.iconphoto(False, photo2)
Btn1 = Button(root, text="Button1", command=passit, padx=5, pady=5,borderwidth=5, relief="sunken", activebackground="dark red", bg="gray15", fg="red")
Btn1.configure(height=1, width=6)
Btn1.pack(padx=10, pady=5, side=TOP, anchor=NW, fill=Y)
Btn2 = Button(root, text="Button2", command=passit, padx=2, pady=5,borderwidth=5, relief="sunken", activebackground="dark red", bg="gray15", fg="red")
Btn2.configure(height=1, width=6)
Btn2.pack(padx=10, pady=5,side=TOP, anchor=N, fill=Y)
Btn3 = Button(root, text="Button3", command=passit, padx=2, pady=5,borderwidth=5, relief="sunken", activebackground="dark red", bg="gray15", fg="red")
Btn3.configure(height=1, width=6)
Btn3.pack(padx=10, pady=5,side=TOP, anchor=NE, fill=Y)
DecodedTextBoxTitle = LabelFrame(root, text="Decoded code", padx=5, pady=5, height=260)
DecodedTextBoxTitle.config(background="gray8")
DecodedTextBoxTitle.config(foreground="red")
DecodedTextBoxTitle.pack(padx=10, pady=5, fill="both", expand=True)
DecodedTextBox = Text(DecodedTextBoxTitle,wrap='none', undo=True, autoseparators=True,borderwidth=5, relief="sunken",selectbackground="dark red")
DecodedTextBox.config(highlightbackground="gray15")
DecodedTextBox.config(foreground="red")
DecodedTextBox.config(highlightthickness=3)
DecodedTextBox.config(highlightcolor="dark red")
DecodedTextBox.config(background="gray15")
DecodedTextBox.pack(fill="both", expand=True)
DecodedTextBox.configure(state='normal')
If you want to use pack, then you should create a frame just for the buttons. You can then use pack to put the frame on top and the LabelFrame below.
Or, you can switch to using grid so that you can put each button in the same row but a different column.
I don't have any idea how to make a buttons that output an integer.
This is a cash register system, everytime the user click that button the price should automatically sums up in the total, and automatically minus and show up a change.
from tkinter import *
from tkinter.font import Font
class MainUI:
def __init__(self,master):
#MAIN WINDOW
self.mainFrame = Frame(master, width=800, height=600,
bg="skyblue")
master.title("FCPC CASH REGISTER")
self.mainFrame.pack()
self.title = Label(self.mainFrame, text="FIRST CITY PROVIDENTIAL"
" COLLEGE", bg="blue")
self.font = Font(family="Helvetica", size=29)
self.title.configure(font=self.font)
self.title.place(x=50, y=50)
#BUTTONS
self.snacksButton = Button(self.mainFrame, text="SNACKS",
command=self.snackList, width=10, bg="blue")
self.font = Font(family="Helvetica", size=20)
self.snacksButton.configure(font=self.font)
self.snacksButton.place(x=100,y=150,)
#TOTAL
self.total = Label(self.mainFrame,text="TOTAL:",
bg="blue",width=8)
self.total.place(x=370,y=160)
self.font = Font(family="Helvetica", size=25)
self.total.configure(font=self.font)
#CHANGE
self.change = Label(self.mainFrame,text="CHANGE:", bg="blue")
self.change.place(x=370,y=240)
self.font = Font(family="Helvetica", size=25)
self.change.configure(font=self.font)
def snackList(self):
self.frame = Toplevel(width=800,height=600,bg="skyblue")
self.frame.title("SNACKS")
self.novaButton = Button(self.frame, text="NOVA(12php)",
command=self.calculate ,width=15, bg="blue")
self.font = Font(family="Helvetica", size=15)
self.novaButton.configure(font=self.font)
self.novaButton.place(x=100,y=150)
root = Tk()
ui = MainUI(root)
root.mainloop()
I want the button to output the price and automatically calculates the total amount.
I've put together a simple example to illustrate what you might need to do. Associate each button to a function that adds the price of a snack to the total amount and changes what is displayed. One way to do it is with a textvariable option of tkinter Label widget.
Example:
import tkinter as tk
def calculate(price):
global total, var
total += price
text = 'Total = ' + str(total)
var.set(text)
root = tk.Tk()
total = 0
var = tk.StringVar()
button1 = tk.Button(root, text='Snickers 1$', command=lambda: calculate(price=1)).pack()
button2 = tk.Button(root, text='Mars 2$', command=lambda: calculate(price=2)).pack()
totalLabel = tk.Label(root, textvariable=var).pack()
root.mainloop()
I'm struggling with grid layout - basically I want to print some data in the loop like this:
But can't figure it out by myself. I managed to make it work properly but just for the first entry - my code:
from tkinter import *
from PIL import Image, ImageTk
import urllib.request
import io
app = Tk()
images = []
for i in range(0, 8):
text1 = Label(font=("Helvetica",10), text="top, left", cursor="hand2")
text2 = Label(font=("Helvetica",10), text="top, right")
text3 = Label(font=("Helvetica",10),text="lower")
image = "https://www.gravatar.com/avatar/b9630126afbff209bb068195307a5e4c?s=328&d=identicon&r=PG"
get_image = urllib.request.urlopen(image).read()
im1 = Image.open(io.BytesIO(get_image))
im_small = im1.resize((70, 70))
im = ImageTk.PhotoImage(im_small)
image1 = Label(app, image=im)
images.append(im)
image1.grid(rowspan=2, column=0, sticky=W)
text1.grid(row=0, column=1, sticky=W)
text2.grid(row=0, column=2, sticky=W)
text3.grid(row=1, column=1, sticky=W)
app.mainloop()
and the result:
I also tried this:
from tkinter import *
from PIL import Image, ImageTk
import urllib.request
import io
app = Tk()
images = []
for i in range(0, 8):
text1 = Label(font=("Helvetica",10), text="top, left", cursor="hand2")
text2 = Label(font=("Helvetica",10), text="top, right")
text3 = Label(font=("Helvetica",10),text="lower")
image = "https://www.gravatar.com/avatar/b9630126afbff209bb068195307a5e4c?s=328&d=identicon&r=PG"
get_image = urllib.request.urlopen(image).read()
im1 = Image.open(io.BytesIO(get_image))
im_small = im1.resize((70, 70))
im = ImageTk.PhotoImage(im_small)
image_cover = Label(app, image=im)
images.append(im)
image_cover.grid(rowspan=2, column=0, sticky=W)
text1.grid(row=i+1, column=1, sticky=W)
text2.grid(row=i+1,column=2)
text3.grid(row=i+2, column=1, sticky=W)
app.mainloop()
Since the picture should occupy two rows (let's call it 1 and 2), "top left" should be in row number 1 in column 1, "top right" in column number two, and lower in row 2.
Is this what you're looking for:
from tkinter import *
root = Tk()
root.geometry("500x500")
imgvar = PhotoImage(file="world.gif")
for i in range(5):
Label(root, image=imgvar, bg='red', bd=10, relief='groove').grid()
Label(root, text="Upper", bg='blue', bd=5, relief='groove').grid(column=1, row=i, sticky=N)
Label(root, text="Lower", bg='green', bd=5, relief='groove').grid(column=1, row=i, sticky=S)
?