Tk() Handling pagination with a button - python

Guys I am creating an app,and need pagination in the shape of NEXT and PREVIOUS e.g
listt1 = [[1,2,3], [4,5,6], [7,8,9], [10,11,12], [13,14,15], [16,17,18]]
list2=[]
next = ""
prev = ""
def show_list():
if next == "clicked":
for i in listt1[0 : 1]:
show.insert(END, i)
listt2.append(i)
listt1.del(i)
if prev == "clicked":
for n in listt2[0 : 1]:
show.insert(END, n)
def prev_btn():
prev = 'clicked'
show_list()
def next_btn():
next = 'clicked'
show_list()
btn1 = tk.Button(win, text='next',command=next_btn)
btn1.pack(side='left')
btn2 = tk.Button(win, text='prev',command=prev_btn)
btn2.pack=(side='left')
show = tk.Entry(win, width=6)
show.pack(side'bottom')
win = Tk()
win.title("clickers")
win.mainloop()
#OUTPUT FOR BUTTON(NEXT) ON EACH CLICK SHOULD BE
1,2,3 and 4,5,6
7,8,9 and 10,11,12
13,14,15 and 16,17,18
#OUTPUT FOR BUTTON(PREV) ON EACH CLICK SHOULD BE
7,8,9 and 10,11,12
1,2,3 and 4,5,6
I want it just the way it works on a website,please guys I know this is easy,and a basic knowledge of handling a list and loop will do,this i do but can't seem to get around this one.
Guys also need help with this
(1) i need a working code for uploading an image into my database,retrieving and displaying and resizing this to a really small size
(2) can a tkinter app page be printed just like in a website, probably need a code for this too
(3 ) i won't mind a link to a really beautiful looking tkinter app video too,as making one myself looks a bit ugly
thank you all in advance guys

Here's a simple example based on your code that paginates through a list and shows the items in the Entry box.
import tkinter as tk
import math
items = [str(n) for n in range(100)]
page = 0
per_page = 5
n_pages = math.ceil(len(items) / per_page)
def update_list():
print(page)
start_index = int(page * per_page)
end_index = int((page + 1) * per_page)
items_in_page = items[start_index:end_index]
view_text = "Page %d/%d: %s" % (page + 1, n_pages, ", ".join(items_in_page))
show.delete(0, tk.END)
show.insert(0, view_text)
def change_page(delta):
global page
page = min(n_pages - 1, max(0, page + delta))
update_list()
def prev_btn():
change_page(-1)
def next_btn():
change_page(+1)
win = tk.Tk()
win.title("clickers")
tk.Button(win, text="next", command=next_btn).pack()
tk.Button(win, text="prev", command=prev_btn).pack()
show = tk.Entry(win)
show.pack()
update_list() # to initialize `show`
win.mainloop()

Related

Python GUI, Label text showing "{}" instead of Space

I'm writing the code as mentioned below to display Table of 2. There must be "Space" shown Before & After "X" as " X " but instead I'm getting "{}". Seeking for Help as I'm new to programming.
Code:
import tkinter
table = tkinter.Tk()
table.geometry("280x420")
table.title("GUI Table Practice")
n = 2
for i in range(1, 11):
v = (n, ' X ', i, ' = ', n*i)
s = tkinter.Label(text=v, font="Times 20")
s.pack()
table.mainloop()
Result:
Try formatting instead of passing a tuple as text:
import tkinter
table = tkinter.Tk()
table.geometry("280x420")
table.title("GUI Table Practice")
n = 2
for i in range(1, 11):
s = tkinter.Label(text=f'{n} X {i} = {n*i}', font="Times 20")
s.pack()
table.mainloop()

python error - TypeError: string indices must be integers

I have been building a flashcard app and have run into a roadblock while trying to implement a radiobutton. The issue is when run the menu shows up and your able to access the lesson, but the radiobuttons do not appear. Whenever the code is run this error shows up TypeError: string indices must be integers attached to the radiobutton functionbalancing_radio_butto1 = Radiobutton(balancing_frame, text = balancing[answer_list[0]], variable=balancing_radio, value = 1) if someone could explain the why this error shows up as well as how to fix it it would be much appreciated. Below is my code that I have so far.
from tkinter import *
from PIL import ImageTk, Image
from random import branding
import random
root = Tk()
root.title('Chemistry Flashcards')
root.geometry("500x500")
def balancing():
balancing_frame.pack(fill="both", expand=1)
global show_balancing
show_balancing = Label(balancing_frame)
show_balancing.pack(pady=15)
global balancing
balancing = ['balanced1', 'balanced2', 'balanced3', 'balanced4', 'balanced5', 'unbalanced1', 'unbalanced2', 'unbalanced3', 'unbalanced4', 'unbalanced5']
global balancing_state
balancing_state = {
'balanced1':'balanced',
'balanced2':'balanced',
'balanced3':'balanced',
'balanced4':'balanced',
'balanced5':'balanced',
'unbalanced1':'unbalanced',
'unbalanced2':'unbalanced',
'unbalanced3':'unbalanced',
'unbalanced4':'unbalanced',
'unbalanced5':'unbalanced',
}
answer_list = []
count = 1
while count < 3:
rando = randint(0, len(balancing_state)-1)
if count == 1:
answer = balancing[rando]
global balancing_image
balancing = "C:/Users/Kisitu/Desktop/project/balancing/" + balancing[rando] + ".png"
balancing_image = ImageTk.PhotoImage(Image.open(balancing))
show_balancing.config(image=balancing_image)
answer_list.append(balancing[rando])
'''random.shuffle(balancing)'''
count += 1
random.shuffle(answer_list)
global balancing_radio
balancing_radio = IntVar()
balancing_radio_butto1 = Radiobutton(balancing_frame, text = balancing[answer_list[0]], variable=balancing_radio, value = 1)
balancing_radio_butto1.pack(pady=10)
balancing_radio_butto2 = Radiobutton(balancing_frame, text = balancing[answer_list[1]], variable=balancing_radio, value = 2).pack()
my_menu = Menu(root)
root.config(menu=my_menu, bg='#B7F7BB')
lesson_menu = Menu(my_menu)
my_menu.add_cascade(label="Lesson", menu=lesson_menu)
lesson_menu.add_command(label="balancing", command=balancing)
lesson_menu.add_separator()
lesson_menu.add_command(label="Exit", command=root.quit)
balancing_frame = Frame(root, width=500, height=500, )
root.mainloop()
... text = balancing[answer_list[0]] ...
balancing is a list, you are trying to index a value from the list.
you are passing answer_list[0] as index.
answer_list contains random strings from balancing.
you are trying to index a list with a string like in
balancing["balanced2"]
maybe you could use a dictionary?

Why wont my code return a value for the data input into a tkinter text box

I have written this code and for some reason it refuses to return any sort of value or input for slef.REV when used in the function post(self) however it will return a value when I try and return a value in the getlen() function which is used to reurn the number of characters in the review.I dont have this problem for any other variables that I retrieve data from within this class. Below is the relevant code, any help would be appreciated. the lines where this problem occures is the first functio calld post(lines 1-5) and 4 lines up from the bottom
def post(self):
MovieID = self.MovID
REV = self.REV
AddReview(conn,cursor,Add_Review,MovieID,REV)
print(REV)
def shrek_film(self):
self.title = "Shrek"
self.MovID = 1
self.root4 = tk.Toplevel()
self.root4.title("Watch Shreck")
self.root4.geometry("1400x800")
frame_4 = tk.Frame(self.root4, bg = "black")
frame_4.pack(fill = tk.BOTH, expand = True, padx=0 , pady=0)
frame_4.grid_columnconfigure(1,weight=1)
self.Create_canvas = tk.Canvas(frame_4, width=2000, height=1080)
self.Create_canvas.place(x=-50, y=-50)
self.Create_img = PhotoImage(file="shrek-landscape.gif")
self.Create_canvas.create_image(20, 20, anchor = NW, image=self.Create_img)
play_button= tk.Button(frame_4,bg="orange",text="play", command = self.addHistory)
play_button.place(x=700,y=400)
play_button.config(font=("Ariel","30"))
def gtelen():
Review = reviewbox.get('1.0',END)
REVLEN = len(Review)
REVLENLEFT = (231-len(Review))
if REVLEN >=230:
lenbox = tk.Label(frame_4 ,text="No words left",bg="orange")
lenbox.place(x=360,y=460)
lenbox.config(font=("Ariel","15"))
else:
lenbox = tk.Label(frame_4 ,text=REVLENLEFT,bg="orange")
lenbox.place(x=360,y=460)
lenbox.config(font=("Ariel","15"))
print(Review)
Words_button = tk.Button(frame_4, bg="orange",text="check number of words remaining", command=gtelen)
Words_button.place(x=150,y=460)
Words_button.config(font=("Ariel","10"))
reviewlable=tk.Label(frame_4,text="Write a review",bg="orange")
reviewlable.place(x=10,y=460)
reviewlable.config(font=("ariel","15"))
Review_button= tk.Button(frame_4,bg="orange",text="See Reviews")#, command = self.ViewReviews)
Review_button.place(x=490,y=450)
Review_button.config(font=("Ariel","15"))
reviewbox= Text(frame_4,width=100,height=12)
reviewbox.place(x=10,y=500)
self.REV = reviewbox.get('1.0',END)
post_button = tk.Button(frame_4,bg="orange",text="Post Review", command = self.post)
post_button.place(x=830,y=650)
post_button.config(font=("Ariel","15"))
You can use Entry instead and use a StringVar
v = StringVar() # Create StringVar
reviewbox = Entry(frame_4, width = 100, height = 12, textvariable = v) # Create Entry widget
reviewbox.place(x = 10, y = 500) # Place Entry widget
self.REV = v.get() # Get contents of StringVar
The line self.REV = reviewbox.get('1.0',END) is being called about a millisecond after creating the text widget. The user will not even have seen the widget yet, much less have had time to type in it.
You can't call the get() method until after the user has had a chance to enter data, such as inside the post method.
def post(self):
MovieID = self.MovID
REV = reviewbox.get("1.0", "end")
AddReview(conn,cursor,Add_Review,MovieID,REV)
print(REV)

Python Tkinter- Clear a text box every time it is clicked and displaying with digit group separator

I am writing a simple app to calculate some values according to entered value by user. I almost accomplished it!
Now I want to know:
1. How can I clear my txtFixedIncome text box every time I click on it?
2. How can it be implemented to display the content of txtFixedIncome text box with thousands separator (digit group separator)? i.e. displaying 27659 as 27,659.
import tkinter
mainForm = tkinter.Tk()
mainForm.title('Shahr Fixed Income Fund')
def btnCalculatePressed():
txtCalculationResult.delete('1.0', 'end')
#txtCalculationResult.insert(tkinter.INSERT, "Button was pressed")
#txtCalculationResult.pack()
yourIncomePortion = txtFixedIncome.get('1.0', 'end')
print(yourIncomePortion)
txtCalculationResult.insert(tkinter.INSERT, yourIncomePortion)
btnCalculate = tkinter.Button(mainForm , text = "Calculate", command= btnCalculatePressed)
txtCalculationResult = tkinter.Text(mainForm )
txtCalculationResult.insert(tkinter.INSERT, "CalculationResults")
txtFixedIncome = tkinter.Text(mainForm, height = 1, width = 30 )
txtFixedIncome.insert(tkinter.INSERT, "your income portion")
txtFixedIncome.pack();
txtCalculationResult.pack()
btnCalculate.pack()
mainForm.mainloop()
Solution of first question:
bind focus in and focus out of your widget. Like:
txtFixedIncome.bind("<FocusIn>",lambda _:txtFixedIncome.delete('1.0', 'end'))
txtFixedIncome.bind("<FocusOut>",lambda _:txtFixedIncome.insert("1.0","your income portion" if str(txtFixedIncome.get("1.0","end")) == "\n" else ""))
This will erase all data in entry when focused out and enter information data when focused in.
Solution of second question:
You can make a function to update your values and format them like:
def updat(text):
try:txtCalculationResult.insert(tkinter.INSERT,"{:,.0f}".format(float(text)))
except:txtCalculationResult.insert(tkinter.INSERT,"CalculationResults")
As:
>>> "{:,.0f}".format(23442)
'23,442'
>>>
Full code:
Here is a full example code that shows the behavior you are expecting:
import tkinter
mainForm = tkinter.Tk()
mainForm.title('Shahr Fixed Income Fund')
def updat(text):
try:txtCalculationResult.insert(tkinter.INSERT,"{:,.0f}".format(float(text)))
except:txtCalculationResult.insert(tkinter.INSERT,"CalculationResults")
def btnCalculatePressed():
txtCalculationResult.delete('1.0', 'end')
yourIncomePortion = txtFixedIncome.get('1.0', 'end')
updat(yourIncomePortion)
btnCalculate = tkinter.Button(mainForm , text = "Calculate", command= btnCalculatePressed)
txtCalculationResult = tkinter.Text(mainForm)
txtCalculationResult.insert(tkinter.INSERT, "CalculationResults")
txtFixedIncome = tkinter.Text(mainForm, height = 1, width = 30 )
txtFixedIncome.insert(tkinter.INSERT, "your income portion")
txtFixedIncome.bind("<FocusIn>",lambda _:txtFixedIncome.delete('1.0', 'end'))
txtFixedIncome.bind("<FocusOut>",lambda _:txtFixedIncome.insert("1.0","your income portion" if str(txtFixedIncome.get("1.0","end")) == "\n" else ""))
txtFixedIncome.pack();
txtCalculationResult.pack()
btnCalculate.pack()
mainForm.mainloop()
Format during typing:
If you want to format the string during typing as you commented then use the following code:
import tkinter
mainForm = tkinter.Tk()
mainForm.title('Shahr Fixed Income Fund')
def updat(text):
try:txtCalculationResult.insert(tkinter.INSERT,"{:,.0f}".format(float(text.replace(",",""))))
except:txtCalculationResult.insert(tkinter.INSERT,"CalculationResults")
def btnCalculatePressed():
txtCalculationResult.delete('1.0', 'end')
yourIncomePortion = txtFixedIncome.get('1.0', 'end')
updat(yourIncomePortion)
btnCalculate = tkinter.Button(mainForm , text = "Calculate", command= btnCalculatePressed)
txtCalculationResult = tkinter.Text(mainForm)
txtCalculationResult.insert(tkinter.INSERT, "CalculationResults")
txtFixedIncome = tkinter.Text(mainForm, height = 1, width = 30 )
txtFixedIncome.insert(tkinter.INSERT, "your income portion")
def updat2():
text = txtFixedIncome.get("1.0","end")
txtFixedIncome.delete("1.0","end")
try:
txtFixedIncome.insert(tkinter.INSERT,"{:,.0f}".format(float(text.replace(",",""))))
except:
txtFixedIncome.insert(tkinter.INSERT,text[:-1])
txtFixedIncome.bind("<FocusIn>",lambda _:txtFixedIncome.delete('1.0', 'end'))
txtFixedIncome.bind("<FocusOut>",lambda _:txtFixedIncome.insert("1.0","your income portion" if str(txtFixedIncome.get("1.0","end")) == "\n" else ""))
txtFixedIncome.bind("<Key>",lambda _:mainForm.after(50,updat2))
txtFixedIncome.pack();
txtCalculationResult.pack()
btnCalculate.pack()
mainForm.mainloop()

Sanitizing list for Tkinter label

I'm trying to build a simple name generator as a project, and I've got it to work, but it doesn't output correctly I'm getting outputs like this:
{NameA}{NameB}NameC NameD{NameE}
While I know for a fact that they are being stored in a list like this:
['Name A', 'NameB', 'NameC', 'NameD', 'NameE']
Here is the full code:
import tkinter as tk
import random
printout = []
def generate():
for _ in range(var1.get()):
C = random.randrange(6)
if C == 0:
printout.append(random.choice(Prefix))
elif 1 <= C <= 2:
printout.append(random.choice(Prefix)+random.choice(Suffix))
elif 3 <= C <= 5:
printout.append(random.choice(Prefix)+" "+random.choice(Prefix)+random.choice(Suffix))
var.set(printout)
print(printout)
root = tk.Tk()
root.title("Simple GUI")
root.geometry("200x200")
var = tk.StringVar()
app = tk.Frame(root)
app.grid()
list1 = [1, 5, 10, 50]
var1 = tk.IntVar(app)
var1.set(1)
drop = tk.OptionMenu(root,var1,*list1)
drop.grid()
label = tk.Label(app, text = "How many results:")
label.grid()
button1 = tk.Button(app, text = "Generate!", command=generate)
button1.grid()
label2= tk.Label(app, textvariable=var)
label2.grid()
with open('D:/My Documents/prefix.txt') as f:
Prefix = [line.rstrip('\n') for line in f]
with open('D:/My Documents/suffix.txt') as r:
Suffix = [line.rstrip('\n') for line in r]
root.mainloop()
I can't find anyone have this problem online so I'm not sure what's happening.
The curly braces you see in your output are a result of Tkinter trying to print a list as if it were a string. You should explicitly convert your list to a string before passing it to var.set.

Categories