tkinter messagebox link to notebook page - python-3.x

referwork = ttk.Notebook(root, style =".TNotebook")
f1 = ttk.Frame(referwork)
f2 = ttk.Frame(referwork)
referwork.add(f1, text="Search", padding = 1)
referwork.add(f2, text="Add/Delete", padding = 1)
#referwork.configure (height = 500, width = 800)
referwork.grid(row=0, column=0, sticky=(N,W,S,E))
I have used the above to create a two-tab notebook. On the first a search is performed. What I want to do is to have an alert in a message box appear messagebox.askyesno and when 'yes' is selected that the focus moves to the second page of the notebook
messagebox.askyesno(0.0,'"{0}"{1} \n {2}\n'.format(search_analyte.get(),' is not in the database.','Add,if appropriate'))
if True:
is as far as I have got. I cannot figure out how to 'open' the second page using this dialogue and conditional. Many thanks for any help

Use Notebook.select(tab) method, where tab is one of the notebook child widgets.
from tkinter import *
from tkinter.ttk import *
from tkinter.messagebox import askyesno
def open_first():
referwork.select(f1)
def open_second():
if askyesno('Title', 'Press "Yes" to open second page') == YES:
referwork.select(f2)
root = Tk()
referwork = Notebook(root, style =".TNotebook")
f1 = Frame(referwork)
f2 = Frame(referwork)
Button(f1, text='Go =>', command=open_second).pack(padx=100, pady=100)
Button(f2, text='<= Go', command=open_first).pack(padx=100, pady=100)
referwork.add(f1, text="Search", padding = 1)
referwork.add(f2, text="Add/Delete", padding = 1)
referwork.grid(row=0, column=0, sticky=(N,W,S,E))
root.mainloop()

Related

How to change the button position when pressed in tkinter python

please tell me how to change the position of the button in tkinter. I predicted that it could be done by button['padx' = 4], but it doesn't work. Do you know how to do it?
from tkinter import ttk
import random
window = tk.Tk()
window.geometry('512x512')
def click():
pass
button = ttk.Button(
text="No",
command=click
).pack(padx=5, pady=15)
window.mainloop()
I instead assigned 2 variables to random integers, and then updated the position of the button with those variables. If you want the random position to be a wider area increase the number "100" in "random_int".
from tkinter import *
import random
window = Tk()
window.geometry('512x512')
x = 5
y = 15
def click():
random_int = random.randint(0, 100)
x = (random_int)
random_int = random.randint(0, 100)
y = (random_int)
button.place(x=x, y=y)
button = Button(text="No", command=click)
button.pack(padx=5, pady=15)
window.mainloop()

tkinter - how to make separate hyperlink button in my loop?

I'm trying to make some simple program to open url if the condition fits.
Here's the minimal reproducible example.
from tkinter import *
import requests
from bs4 import BeautifulSoup
import webbrowser
import time
def call_back(event):
input_id.delete(0,END)
return None
def open_browse(url):
webbrowser.open_new(url)
win = Tk()
win.geometry("150x150")
win.title("Example")
search_btn = Button(win)
search_btn.config(text="search")
search_btn.config(width=5,height=1)
search_btn.grid(column = 2, row = 2)
def search_chr():
chr_list = ["test1","test2"]
result = [(0,"test_r_1"),(0,"test_r_2")]
var_dict = {}
num = -1
for ch in chr_list:
num += 1
var_dict["output%s" %num] = Entry(win, width = 10)
if result[0] == 0:
pass
else:
link_url = result[num][1]
print(link_url)
var_dict["o-button%s" %num] = Button(win, command=lambda aurl=link_url:open_browse(link_url))
var_dict["output"+str(num)].insert(0, "Text")
var_dict["output"+str(num)].grid(column = 0, row = 0+num, columnspan = 4, sticky=W, padx=5, pady=5)
var_dict["o-button"+str(num)].config(text="URL")
var_dict["o-button"+str(num)].grid(column = 4, row = 0+num, sticky=E, padx=5, pady=5)
var_dict["output"+str(num)].config(state="disabled")
search_btn.config(command = search_chr)
win.mainloop()
So, if you run the code, there would be a button.
And if you click it, There will be two sets of Label with "Text" in it and Button with "URL" in it. When you press the URL button, it should open a browse with a given url.
As you see the printed text in your terminal, the url is supposed to be "test_r_1" and "test_r_2"
But, if you press each button, all buttons are directed to "test_r_2".
It seems that it somehow overwrote the previous "test_r_1" as well.
If anyone can explain how to make each button to link to each url, it would be perfect.
Thanks for stopping by, and I hope you can help me with this.
Okay, I tracked down that I didn't fully understand that how lambda works.
So I changed my search keyword and found this beautiful question and answer.
Tkinter assign button command in loop with lambda
I changed
var_dict["o-button%s" %num] = Button(win, command=lambda aurl=link_url:open_browse(link_url))
into
var_dict["o-button%s" %num] = Button(win, command=lambda link_url=link_url:open_browse(link_url))
and it worked.
Thanks all!

Toplevel in tkinter is creating another empty window at the side

I am new in python.
I was trying to write a code with tkinter.
In click of a button it should open another window and close the previous window.
The code is closing the previous window correctly.
But the problem is it is also opening another empty window at the side on the screen.
Here's my code:
# The first part got no problem
from tkinter import *
import time
class Start:
def __init__(self):
self.first_screen = Tk()
self.win_width = 500
self.win_height = 500
self.screen_width = self.first_screen.winfo_screenwidth()
self.screen_height = self.first_screen.winfo_screenheight()
self.x_position = (self.screen_width / 2) - (self.win_width / 2)
self.y_position = (self.screen_height / 2) - (self.win_height / 2)
self.first_screen.title("Number game")
self.first_screen.config(bg="#ffff00")
self.first_screen.geometry("%dx%d+%d+%d" % (self.win_width, self.win_height, self.x_position, self.y_position))
self.btn_play = Button(self.first_screen, text="Start", command=self.btn_play_click_action, width="10")
self.btn_play.pack(side="top")
self.btn_play.place(height=40, width=200, x=150, y=200)
self.first_screen.mainloop()
# This is where the problem happened
def btn_play_click_action(self):
time.sleep(1)
self.first_screen.destroy()
self.second_screen = Toplevel()
self.second_screen.geometry("%dx%d+%d+%d" % (self.win_width, self.win_height, self.x_position, self.y_position))
self.second_screen.title("Number game")
self.second_screen.config(bg="#eeee00")
self.label1 = Label(self.second_screen, width=50, bg="#000000")
self.label1.pack(side="top")
self.second_screen.mainloop()
Start()
Edit:
When I remove the " self.first_screen.destroy()" line, then the there is no problem.
Maybe it is because Toplevel needs a parent window. But I need to close the previous window. In this case what should I do?
You can not destroy the root window of the program which is self.first_screen = Tk().
Also, you dont need a mainloop for Toplevel window.
You can use .withdraw() method to hide root window instead of .destroy()
Here is you updated code -
from tkinter import *
import time
class Start:
def __init__(self):
self.first_screen = Tk()
self.win_width = 500
self.win_height = 500
self.screen_width = self.first_screen.winfo_screenwidth()
self.screen_height = self.first_screen.winfo_screenheight()
self.x_position = (self.screen_width / 2) - (self.win_width / 2)
self.y_position = (self.screen_height / 2) - (self.win_height / 2)
self.first_screen.title("Number game")
self.first_screen.config(bg="#ffff00")
self.first_screen.geometry("%dx%d+%d+%d" % (self.win_width, self.win_height, self.x_position, self.y_position))
self.btn_play = Button(self.first_screen, text="Start", command=self.btn_play_click_action, width="10")
self.btn_play.pack(side="top")
self.btn_play.place(height=40, width=200, x=150, y=200)
self.first_screen.mainloop()
# This is where the problem happened
def btn_play_click_action(self):
time.sleep(1)
self.first_screen.withdraw()
self.second_screen = Toplevel()
self.second_screen.geometry("%dx%d+%d+%d" % (self.win_width, self.win_height, self.x_position, self.y_position))
self.second_screen.title("Number game")
self.second_screen.config(bg="#eeee00")
self.label1 = Label(self.second_screen, width=50, bg="#000000")
self.label1.pack(side="top")
There is unnecessary to make another window in Toplevel(). You can make it easier → Instead of self.second_screen = Toplevel() you can type self.second_screen = Tk().

tkinter - display random image from array on button click

I would like a label to display a random image when a button is clicked.
This is my approach, but it does not work. Any ideas on how to solve welcome.
from tkinter import *
import random
window = Tk()
filechoices = ["image1.png", "image2.png", "image3.png"]
filename = PhotoImage(file = random.choice[filechoices])
def press():
image = Label(window, image=filename).pack()
button1 = Button(window, text="click to see image", command = press)
button1.pack()
random.choice is a function,not a list.
It should be:
filename = PhotoImage(file = random.choice(filechoices))
Read random module
random.choice(seq)
Return a random element from the non-empty sequence seq.
Also,in your code,you haven't used mainloop()

Returning a value from a tkinter form

I'm using code where I need to ask the user for input, using a tkinter window (I'm not using tkinter in other parts of the code).
My issue is that I simply need to use the tkinter window to return a value upon pressing the OK button on the form, which will also close down the form. The only way I can get it to work so far is by using a global variable. I've searched for other solutions to this but either they don't return a value (they simply print it) or don't allow passing text for the prompt.
Thanks in advance if you can help with this.
from tkinter import *
def input_text(prompt):
def ok():
global ret
ret = entry.get()
master.destroy()
master = Tk()
lbl = Label(master, text=prompt)
lbl.pack()
entry = Entry(master)
entry.pack()
entry.focus_set()
butt = Button(master, text = "OK", width = 10, command = ok)
butt.pack()
mainloop()
print("I am here!")
ret=""
input_text("Enter something")
print("ret is:", ret)
After a good night's sleep I've solved the problem :-)
The solution was to create a class and return the response via an attribute. Here's the code for the archive ... just in case anyone out there has a similar question.
from tkinter import *
class InputForm():
def __init__ (self, prompt):
self.prompt = prompt
self.response = ""
def ok():
self.response = entry.get()
master.destroy()
master = Tk()
lbl = Label(master, text=self.prompt)
lbl.pack()
entry = Entry(master)
entry.pack()
entry.focus_set()
butt = Button(master, text = "OK", width = 10, command = ok)
butt.pack()
mainloop()
abc = InputForm("Enter something").response
print("returned value is:", abc)

Resources