I currently working on some code on Tkinter and I want to know if its possibly and if so how to add a website hyperlink to a button. In my case I'm trying to add the Caldicot School web address to a button through Tkinter on Python 3 and when its clicked it sends you there
Welcome to SO!
This page has a recipe for creating a button that acts like a hyperlink in tkinter
http://code.activestate.com/recipes/580774-tkinter-link-or-hyperlink-button/
The main part of the code is as follows:
if __name__ == "__main__":
import webbrowser
try:
from Tkinter import Tk, Frame
except ImportError:
from tkinter import Tk, Frame
def callback():
webbrowser.open_new(r"http://www.google.com")
root = Tk()
frame = Frame(root, bg="white")
frame.pack(expand=True, fill="both")
# Creates a button that, when clicked, calls the function that sends you to your hyperlink.
link = Link_Button(frame, text="Google Hyperlink", action=callback)
link.pack(padx=10, pady=10)
root.mainloop()
Check the website above for the code behind the class Link_Button. In case the link dies, here's the rest of the code:
# Author: Miguel Martinez Lopez
try:
from Tkinter import Label
from ttk import Style
from tkFont import Font, nametofont
except ImportError:
from tkinter import Label
from tkinter.ttk import Style
from tkinter.font import Font, nametofont
def get_background_of_widget(widget):
try:
# We assume first tk widget
background = widget.cget("background")
except:
# Otherwise this is a ttk widget
style = widget.cget("style")
if style == "":
# if there is not style configuration option, default style is the same than widget class
style = widget.winfo_class()
background = Style().lookup(style, 'background')
return background
class Link_Button(Label, object):
def __init__(self, master, text, background=None, font=None, familiy=None, size=None, underline=True, visited_fg = "#551A8B", normal_fg = "#0000EE", visited=False, action=None):
self._visited_fg = visited_fg
self._normal_fg = normal_fg
if visited:
fg = self._visited_fg
else:
fg = self._normal_fg
if font is None:
default_font = nametofont("TkDefaultFont")
family = default_font.cget("family")
if size is None:
size = default_font.cget("size")
font = Font(family=family, size=size, underline=underline)
Label.__init__(self, master, text=text, fg=fg, cursor="hand2", font=font)
if background is None:
background = get_background_of_widget(master)
self.configure(background=background)
self._visited = visited
self._action = action
self.bind("<Button-1>", self._on_click)
#property
def visited(self):
return self._visited
#visited.setter
def visited(self, is_visited):
if is_visited:
self.configure(fg=self._visited_fg)
self._visited = True
else:
self.configure(fg=self._normal_fg)
self._visited = False
def _on_click(self, event):
if not self._visited:
self.configure(fg=self._visited_fg)
self._visited = True
if self._action:
self._action()
You can basicly add this method:
from tkinter import *
from tkinter import ttk
import webbrowser
root = Tk()
root.title = 'Link Button'
def link():
webbrowser.open_new(r"https://www.python.org")
and then link method to the button:
nut = ttk.Button(root, text='Link Button', command=link)
nut.pack()
root.mainloop()
import tkinter
import webbrowser
root = Tk()
root.title = 'link to the button'
def link():
webbrowser.open_new(r"https://www.python.org")
nut = ttk.Button(root, text='link to the button')
nut.pack()
root.mainloop()
and then just simply use
nut = ttk.Button(root, text= 'link to the button', command=link)
nut.pack()
root.mainloop()
Related
I'm trying to create a sample GUI using tkinter with customtkinter module ,but nothing appears in the window.
import tkinter
import tkinter.messagebox
import customtkinter
customtkinter.set_appearance_mode("System")
customtkinter.set_default_color_theme("green")
class App(customtkinter.CTk):
def __init__(self):
super().__init__()
# configure window
self.title("Tracking System")
self.geometry("350x500")
self.resizable(False,False) # to disable the minimize/maximize buttons.
self.checkbox_slider_frame = customtkinter.CTkFrame(self)
self.switch = customtkinter.CTkSwitch(master=self.checkbox_slider_frame, command=lambda: print("switch 1 toggle"))
self.switch.grid(row=0, column=0)
self.switch.select()
self.button = customtkinter.CTkButton(master=self.checkbox_slider_frame, text="CTkButton")
self.button.grid(row=1 , column = 1)
if __name__ == "__main__":
app = App()
app.mainloop()
I looked into the customtkinter example:-
https://github.com/TomSchimansky/CustomTkinter/blob/master/examples/complex_example.py
But I
You forgot to add self.checkbox_slider_frame to a geometry manager (pack, place, or grid)
self.checkbox_slider_frame = customtkinter.CTkFrame(self)
self.checkbox_slider_frame.pack(expand=True, fill=tkinter.BOTH)
I'm tinkering with Tkinter and trying to check if my program is open on pressing a button, but the Tkinter is not updating my label. Why?
from win32gui import GetWindowRect, FindWindow
from tkinter import Tk, ttk, BooleanVar
class Bot:
root = Tk()
is_gta_open = BooleanVar(None, False)
def mta_open_string(self):
return "włączone" if self.is_gta_open.get() else "wyłączone"
def draw_gui(self):
frame = ttk.Frame(self.root, padding=10)
frame.grid()
ttk.Label(frame, text=f"Status gry: {self.mta_open_string()}").grid(column=0, row=0)
ttk.Button(frame, text="Odśwież", command=lambda: [self.try_finding_rect(), self.root.update()]).grid(column=1, row=0)
self.root.mainloop()
def try_finding_rect(self):
window_handle = FindWindow("Grand theft auto San Andreas", None)
if window_handle == 0:
self.is_gta_open.set(False)
return
self.is_gta_open.set(True)
def run(self):
self.try_finding_rect()
self.draw_gui()
if __name__ == "__main__":
Bot().run()
I'm updating the state using self.root.update method and using BooleanVar, so I don't know why this is not working.
I've put together a very minimal example app that should work as intended. I don't have a copy of GTA to test with so I used a different app, but it should function the same way with any app in principle:
import tkinter as tk
import ctypes
from tkinter import ttk
class Bot(tk.Tk): # init Tk
def __init__(self):
super.__init___()
APP_NAME = 'Grand theft auto San Andreas'
self.status_label = tk.Label(self, text='Press the button')
self.status_label.pack()
self.run_btn = ttk.Button(
self,
text='Click Me!',
command=lambda: self.check_for_app(APP_NAME)
)
self.run_btn.pack()
def check_for_app(app_name: str):
user32 = ctypes.WinDLL('user32')
if user32.FindWindowW(None, app_name):
self.status_label.config(text='Running')
else:
self.status_label.config(text='Not Running')
if __name__ == '__main__':
app = Bot()
app.mainloop()
Updating a variable won't change an f-string that uses the variable. You must explicitly configure the widget to show the new value.
To do that you'll need to keep a reference to the label widget, and then update the widget with the configure method.
def draw_gui(self):
...
self.status_label = ttk.Label(frame, text=f"Status gry: {self.mta_open_string()}")
self.status_label.grid(column=0, row=0)
...
def try_finding_rect(self):
...
self.is_gta_open.set(True)
self.status_label.configure(text=f"Status gry: {self.mta_open_string()}")
Personally I recommend using a proper method for the button rather than a complicated lambda. That will make the code easier to read and easier to debug.
For example:
def draw_gui(self):
...
ttk.Button(frame, text="Odśwież", command=self.update_status)
...
def update_status(self):
self.try_finding_rect(),
self.status_label.configure(text=f"Status gry: {self.mta_open_string()}")
when i run python file kill_app its run first 2nd python file(Hb_test.py) then run 1st python on tkinter.i am using vs code and python version is 3.10
see the code below
from tkinter import*
from Lab.Hb_Test import Hba
class kill_App:
def __init__(self,root):
self.root = root
self.root.geometry("1350x700+0+0")
self.root.title("Billing Software")
bg_color = "#074463"
title = Label(self.root,text = "PATHOLAB",bd=12,relief=GROOVE,bg=bg_color,fg="white",
font = ("ALGERIAN",40),pady=2).pack(fill=X)
if __name__=="__main__":
root =Tk()
obj = kill_App(root)
root.mainloop()
****
this is my second
**
**from tkinter import*
from tkinter import ttk
class Hba:
def __init__(self,root):
self.root = root
self.root.geometry("300x70+200+200")
self.root.title("JIBAN PRABHA PATHOLAB")
bg_color = "#074463"
Hb = LabelFrame(self.root,text="BLOOD TEST",font=("ALGERIAN",15,"bold")
,fg="gold",bg=bg_color)
Hb.place(x=0,y=0)
self.hb_neu_lbl = Label(Hb,text="Hb%(sahils) Test",bg=bg_color,fg="white",font=("Bell MT",15,"bold")).grid(row=1,column=1,padx=5,pady=5)
self.hb_neu=Entry(Hb,width=10,font="BellMT 15",bd=5,relief=SUNKEN).grid(row=1,column=2,padx=5,pady=5)
root = Tk()
obj = Hba(root)
root.mainloop()**
**
When Hb_Test is imported, its code will be executed, so the last three lines in the module will create a window:
Hb_Test.py
...
# below lines will create a window
root = Tk()
obj = Hba(root)
root.mainloop()
Note that it is not recommended to create more than one instance of Tk() and execute .mainloop() more than once.
For window other than the main/root window, use Toplevel instead of Tk. For your case, I would suggest that Hba inherits from Toplevel:
import tkinter as tk
class Hba(tk.Toplevel):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.geometry("300x70+200+200")
self.title("JIBAN PRABHA PATHOLAB")
bg_color = "#074463"
Hb = tk.LabelFrame(self, text="BLOOD TEST", font=("ALGERIAN",15,"bold"), fg="gold", bg=bg_color)
Hb.place(x=0, y=0)
self.hb_neu_lbl = tk.Label(Hb, text="Hb%(sahils) Test", bg=bg_color, fg="white", font=("Bell MT",15,"bold"))
self.hb_neu_lbl.grid(row=1,column=1,padx=5,pady=5)
self.hb_neu = tk.Entry(Hb, width=10, font="BellMT 15", bd=5, relief=tk.SUNKEN)
self.hb_neu.grid(row=1,column=2,padx=5,pady=5)
Note that I have changed from tkinter import * to import tkinter as tk because wildcard import is not recommended as well.
Also don't write code like below:
self.hb_neu_lbl = Label(Hb,text="Hb%(sahils) Test",bg=bg_color,fg="white",font=("Bell MT",15,"bold")).grid(row=1,column=1,padx=5,pady=5)
because self.hb_neu_lbl will be None (result of .grid(...)). Code like below instead:
self.hb_neu_lbl = Label(Hb, text="Hb%(sahils) Test", bg=bg_color, fg="white", font=("Bell MT",15,"bold"))
self.hb_neu_lbl.grid(row=1,column=1,padx=5,pady=5)
How to bind resize event? my event broken.
I found weird 2 conditions if i sets condition greater width 600 font-size 5. it will trigger event once only.
the other condition if i sets font-size to 12. no event trigger.
style.py
import tkinter.ttk as ttk
class Style(ttk.Style):
_window = None
def __init__(self, window):
super().__init__(window)
self._window = window
self.configure("USERINFO.TLabel", font=('script', 12))
self._window.bind("<Configure>", self.__resize)
def __resize(self, event):
if event.width > 600:
self.configure("USERINFO.TLabel", font=('Helvetica', 5))
else:
self.configure("USERINFO.TLabel", font=('script', 12))
guy.py
import tkinter
import tkinter.ttk as ttk
from style import Style
class MainWindow(tkinter.Tk):
def __init__(self):
super().__init__()
Style(self)
self._clientarea()
def _clientarea(self):
frame = ttk.Frame(self).grid(column=0, row=0)
ttk.Label(frame, text="Username: ", style="USERINFO.TLabel").grid(column=0, row=0)
if __name__ == "__main__":
root = MainWindow()
root.mainloop()
This is my code :
import sys
from tkinter import *
#first new screen
def next_screen(names):
for widget in names:
widget.place_forget()
buttonhyp = Button (text = "button1",fg = "blue",command = hypoténusegetdef())
buttonhyp.grid (row = 1,column = 2)
def forget_page1():
widgets = [mLabel1, button]
next_screen(widgets)
################################################################################
def hypténusegetdef ():
widgets1 = [buttonhyp]
nextscreen1(widgets1)
def next_screen(names):
for widget in names:
widget.place_forget()
hyplabel1 = Label (text = "This is my text")
#first page things
mGui = Tk ()
mGui.geometry("600x600+545+170")
mGui.title("MyMathDictionary")
mLabel1 = Label (text = "Welcome to MyMathDictionary. Press Next to continue.",
fg = "blue",bg = "white")
mLabel1.place (x= 150,y = 200)
button = Button (text = "Next", command = forget_page1 )
button.place(x = 275,y = 230)
mGui.mainloop()
What i'm trying to do is to open the program and get the user to click on "Next" and then to show another button which is called "button1" and when the user clicks on "button1" it shows up a text called which says "This is my text" in my code.But when i run it i click on "Next" and nothing shows up i checked and re- checked but nothing seems to work.Any help would be appreciated.
#
I am not an expert, but i will give it a try.
Firstly, import sys is not necessary. And importing all the objects from tkinter module using from tkinter import* is not recommended. You should use import tkinter or import tkinter as tk to avoid unexepcted consequences.
You have 2 functions with the same name. next_screen(names) which should not happen.
Instead of using widgets = [mLabel1, button] to hide the widgets, you should put them in a frame so that you can use winfo_children() to find all the children widgets.
You should put the parent widget name when you create buttons and labels. for example,
import tkinter as tk
root = tk.Tk()
mylabel = tk.Label(root,text='this is a label')
mylabel.pack()
root.mainloop()
In your first next_screen(names) function , you used grid method to display the button. You should not mix the grid method and place method.
This is something i came up with
import tkinter as tk
def Screen_1():
Clear(myframe)
mybutton2= tk.Button(myframe,text = "Button1", command = Screen_2)
mybutton2.pack()
def Screen_2():
Clear(myframe)
mylabel2= tk.Label(myframe,text = "This is my text",fg = "blue",bg = "white")
mylabel2.pack(side='top')
def Clear(parent):
for widget in parent.winfo_children():
widget.pack_forget()
root =tk.Tk()
myframe=tk.Frame(root)
myframe.pack()
mylabel1= tk.Label(myframe,text = "Welcome to MyMathDictionary. Press Next to continue.",fg = "blue",bg = "white")
mylabel1.pack(side='top')
mybutton1= tk.Button(myframe,text = "Next", command = Screen_1)
mybutton1.pack(side='bottom')
root.mainloop()
hope it helps!