Web shortcut not doing what i want it to do - python-3.x

So before you question the code, im just trying to learn tkinter a bit more so i though this be best way haha.
I am currently stuck on the web input, everytime i input a website it comes as "https://%21browser.%21text!" and i dont know why. Random web works but it doesnt work as inputting it.
import webbrowser as wb
from tkinter import *
from tkinter import ttk
import tkinter as tk
import ctypes, random, time
class Browser(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.start()
def start(self):
global webinput
self.title = Label(self, text="Web Shortcut", fg="purple", font="Kokila 20 bold")
self.title.pack(fill=BOTH)
self.webinput = Text(self, height=1, width=57)
self.webinput.pack(side=TOP, fill=BOTH, pady=30, padx=30)
self.openweb = Button(self, height=2, width=20, text="Open Web", bg="gray", fg="lightgreen", command=self.web)
self.openweb.pack(side=LEFT, padx=10)
self.random = Button(self, height=2, width=20, text="Random Web", bg="gray", fg="lightgreen", command=self.randomweb)
self.random.pack(side=LEFT, padx=5)
self.exit = Button(self, height=2, width=20, text="Exit", bg="gray", fg="lightgreen", command=exit)
self.exit.pack(side=LEFT, padx=5)
def web(self):
try:
self.sites = "https://{}".format(self.webinput)
if self.sites:
wb.open(self.sites)
except Exception as e:
ctypes.windll.user32.MessageBoxW(0, str(e), "CRASHED", 0)
def randomweb(self):
self.websites = [
"www.facebook.com",
"www.google.com",
"www.youtube.com",
"www.amazon.co.uk"
]
self.sites = random.choice(self.websites)
self.visit = "https://{}".format(self.sites)
wb.open(self.visit)
if __name__ == "__main__":
root = Tk()
root.title("Web Shortcut")
root.resizable(False, False)
root.geometry("500x200")
app = Browser(master=root)
app.mainloop()
root.destroy()

I have made some change, now it works very well
import webbrowser as wb
from tkinter import *
from tkinter import ttk
import tkinter as tk
import ctypes, random, time
class Browser(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.start()
def start(self):
global webinput
self.title = Label(self, text="Web Shortcut", fg="purple", font="Kokila 20 bold")
self.title.pack(fill=BOTH)
self.webinput = Entry(self)
self.webinput.pack(side=TOP, fill=BOTH, pady=30, padx=30)
self.openweb = Button(self, height=2, width=20, text="Open Web", bg="gray", fg="lightgreen", command=self.web)
self.openweb.pack(side=LEFT, padx=10)
self.random = Button(self, height=2, width=20, text="Random Web", bg="gray", fg="lightgreen", command=self.randomweb)
self.random.pack(side=LEFT, padx=5)
self.exit = Button(self, height=2, width=20, text="Exit", bg="gray", fg="lightgreen", command=exit)
self.exit.pack(side=LEFT, padx=5)
def web(self):
try:
self.sites = f"https://{self.webinput.get()}"
if self.sites:
wb.open(self.sites)
except Exception as e:
ctypes.windll.user32.MessageBoxW(0, str(e), "CRASHED", 0)
def randomweb(self):
self.websites = [
"www.facebook.com",
"www.google.com",
"www.youtube.com",
"www.amazon.co.uk"
]
self.sites = random.choice(self.websites)
self.visit = "https://{}".format(self.sites)
wb.open(self.visit)
if __name__ == "__main__":
root = Tk()
root.title("Web Shortcut")
root.resizable(False, False)
root.geometry("500x200")
app = Browser(master=root)
app.mainloop()
root.destroy()
Hope it helps. (●'◡'●)

Related

tkinter oo - how to iconify a top-level window linking to a button widget

I am working with python 3.8, macos Big Sur.
from tkinter import *
def test(window):
window.iconify()
def onclick():
window = Toplevel()
window.geometry("+300+300")
window.title("child window")
Button(window, text="click", command=lambda: test(window)).pack()
window.mainloop()
root = Tk()
root.title("parent window")
root.geometry("300x200+200+200")
root.resizable(False, False)
root.iconbitmap("tools.ico")
Button(root, text="open child window", command=onclick).pack()
root.mainloop()
I am trying to rewrite the code above as a class, like:
import tkinter as tk
from tkinter import ttk
class GUI:
def __init__(self):
self.root = tk.Tk()
self.root.title('title')
self.root.geometry("300x200+500+250")
self.root.resizable(False, False)
self.interface()
self.root.iconbitmap("tools.ico")
def interface(self):
self.btn = tk.Button(self.root, text="open child window", command=self.onclick).pack()
def onclick(self):
window = tk.Toplevel()
window.geometry('200x100+500+250')
window.title('child window')
self.btn = tk.Button(window, text="click", command=lambda window: self.test(*window)).pack()
window.mainloop()
def test(self, window):
window.iconify()
if __name__ == '__main__':
gui = GUI()
gui.root.mainloop()
however, it ends with
Traceback (most recent call last):
File "/Applications/miniconda3/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
return self.func(*args)
TypeError: <lambda>() missing 1 required positional argument: 'window'
I also have tried binding an iconify event with button, like:
import tkinter as tk
from tkinter import ttk
class GUI:
def __init__(self):
self.root = tk.Tk()
self.root.title('title')
self.root.geometry("300x200+500+250")
self.root.resizable(False, False)
self.interface()
self.root.iconbitmap("tools.ico")
def interface(self):
self.btn = tk.Button(self.root, text="open child window", command=self.onclick).pack()
def onclick(self):
window = tk.Toplevel()
window.geometry('200x100+500+250')
window.title('child window')
self.btn = tk.Button(window, text="click")
self.btn.pack()
self.btn.bind("<Button-1>", self.test(window=window))
window.mainloop()
def test(self, window):
window.iconify()
if __name__ == '__main__':
gui = GUI()
gui.root.mainloop()
just did not work either.
I would appreciate if anyone point out how I could work with lambda: window in the first example code given above.
==2022/8/13==:
class GUI:
def __init__(self):
self.root = tk.Tk()
self.root.title('title')
self.root.geometry("300x200+500+250")
self.root.resizable(False, False)
self.interface()
self.root.iconbitmap("tools.ico")
def interface(self):
btnopen = tk.Button(self.root, text="open child window", command=self.onclick).pack()
def onclick(self):
window = tk.Toplevel()
window.geometry('200x100+500+250')
window.title('child window')
btnclick = tk.Button(window, text="click", command=lambda: self.test(window)).pack()
window.mainloop()
def test(self, window):
window.iconify()
window.deiconify()
if __name__ == '__main__':
gui = GUI()
gui.root.mainloop()
pass with the code above...
a low class mistake I made is that I defined 2 self.btn. Besides, it should work with lambda: self.test(window).
If all you are looking to do is iconify() the window then why not just use that in the command? No need to separate it as its own method. Is this what you are looking for?
import tkinter as tk
from tkinter import ttk
class GUI:
def __init__(self):
self.root = tk.Tk()
self.root.title('title')
self.root.geometry("300x200+500+250")
self.root.resizable(False, False)
self.interface()
#self.root.iconbitmap("tools.ico")
def interface(self):
self.btn = tk.Button(self.root, text="open child window", command=self.onclick)
self.btn.pack()
def onclick(self):
window = tk.Toplevel()
window.geometry('200x100+500+250')
window.title('child window')
self.btn = tk.Button(window, text="click", command=lambda: window.iconify())
self.btn.pack()
if __name__ == '__main__':
gui = GUI()
gui.root.mainloop()

Ttk Frame, Background color

I'm using ttk, for my GUI. I know that it is also a very simple question ... I am trying to change the background color of the main window.
I tried to change the theme, because I am working on a Mac, (and Python 3.5) to avoid the problem with the theme 'aqua', which is the default.I've been reading about several solutions like these questions which are about the same problem... These are the numbers of the questions:
54476511,
38712352,
47327266,
23750141.
But, I haven't Solve the problem, yet.
Here it's my code.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from tkinter.scrolledtext import *
from tkinter import Tk, BOTH, W, N, E, S, messagebox, END
from tkinter.ttk import Button, Label, Style, Frame
class Example(Frame):
def __init__(self,master):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Example")
Style().theme_use("classic")
self.pack(fill=BOTH, expand=1)
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
self.txt_Pad = ScrolledText(self)
self.txt_Pad.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5, sticky=E+W+S+N)
self.txt_Pad.insert(END,'Type your info here')
btn_save = Button(self, text="Save", command=self.save_command)
btn_save.grid(row=1, column=3)
btn_close = Button(self, text="Close", command=self.onClose)
btn_close.grid(row=2, column=3, pady=4)
btn_help = Button(self, text="Help", command=self.about_command)
btn_help.grid(row=5, column=0, padx=5)
def onClose(self):
self.master.destroy()
def about_command(self):
msb = messagebox.showinfo("About", "\"Insert a useful tip Here\"")
def save_command(self):
print('Your info it\'s save now')
def open_command(self):
print('Choose your File')
def main():
root = Tk()
root.geometry("350x300+300+300")
root.configure(bg='#0059b3')
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
Any Suggestions would be appreciated.
Create a style then apply it.
from tkinter.scrolledtext import *
from tkinter import Tk, BOTH, W, N, E, S, messagebox, END
from tkinter.ttk import Button, Label, Style, Frame
class Example(Frame):
def __init__(self, master):
super().__init__()
self.initUI()
def initUI(self):
self.master.title("Example")
# create a new style
self.style = Style()
# configure it to the background you want
self.style.configure('My.TFrame', background='#0059b3')
#Style().theme_use("classic")
# apply it
self.config(style='My.TFrame')
self.pack(fill=BOTH, expand=1)
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
self.txt_Pad = ScrolledText(self)
self.txt_Pad.grid(row=1, column=0, columnspan=2, rowspan=4, padx=5, sticky=E+W+S+N)
self.txt_Pad.insert(END,'Type your info here')
btn_save = Button(self, text="Save", command=self.save_command)
btn_save.grid(row=1, column=3)
btn_close = Button(self, text="Close", command=self.onClose)
btn_close.grid(row=2, column=3, pady=4)
btn_help = Button(self, text="Help", command=self.about_command)
btn_help.grid(row=5, column=0, padx=5)
def onClose(self):
self.master.destroy()
def about_command(self):
msb = messagebox.showinfo("About", "\"Insert a useful tip Here\"")
def save_command(self):
print('Your info it\'s save now')
def open_command(self):
print('Choose your File')
def main():
root = Tk()
root.geometry("350x300+300+300")
root.configure(background='#0059b3')
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
I left comments at the parts I changed.

Multiprocessing not working with progress bar in tkinter

I'm attempting to get the progress bar to run while a method is running. The problem is when I set the method "generatePi" into the class it won't run simultaneously; however, when I set the method "generatePi" outside of the class it works.
The code with method in class that I can get to work is:
from tkinter import (Tk, BOTH, Text, E, W, S, N, END,
NORMAL, DISABLED, StringVar)
from tkinter.ttk import Frame, Label, Button, Progressbar, Entry
from tkinter import scrolledtext
from multiprocessing import Process, Manager, Queue
from queue import Empty
from decimal import Decimal, getcontext
DELAY1 = 80
DELAY2 = 20
q = Queue()
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, name="frame")
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Pi computation")
self.pack(fill=BOTH, expand=True)
self.grid_columnconfigure(4, weight=1)
self.grid_rowconfigure(3, weight=1)
lbl1 = Label(self, text="Digits:")
lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)
self.ent1 = Entry(self, width=10)
self.ent1.insert(END, "4000")
self.ent1.grid(row=0, column=1, sticky=W)
lbl2 = Label(self, text="Accuracy:")
lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)
self.ent2 = Entry(self, width=10)
self.ent2.insert(END, "100")
self.ent2.grid(row=0, column=3, sticky=W)
self.startBtn = Button(self, text="Start",
command=self.onStart)
self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)
self.pbar = Progressbar(self, mode='indeterminate')
self.pbar.grid(row=1, column=1, columnspan=3, sticky=W+E)
self.txt = scrolledtext.ScrolledText(self)
self.txt.grid(row=2, column=0, rowspan=4, padx=10, pady=5,
columnspan=5, sticky=E+W+S+N)
def onStart(self):
self.startBtn.config(state=DISABLED)
self.txt.delete("1.0", END)
digits = int(self.ent1.get())
accuracy = int(self.ent2.get())
self.p1 = Process(target=generatePi(q, digits, accuracy), args=())
self.p1.start()
self.pbar.start(DELAY2)
self.after(DELAY1, self.onGetValue)
def onGetValue(self):
if (self.p1.is_alive()):
self.after(DELAY1, self.onGetValue)
return
else:
try:
self.txt.insert('end', q.get(0))
self.txt.insert('end', "\n")
self.pbar.stop()
self.startBtn.config(state=NORMAL)
except Empty:
print("queue is empty")
def generatePi(q, digs, acc):
getcontext().prec = digs
pi = Decimal(0)
k = 0
n = acc
while k < n:
pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
(Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
(Decimal(1)/(8*k+6)))
k += 1
q.put(pi)
def main():
root = Tk()
root.geometry("400x350+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
The code with method outside class that I am unable to get to work:
from tkinter import (Tk, BOTH, Text, E, W, S, N, END,
NORMAL, DISABLED, StringVar)
from tkinter.ttk import Frame, Label, Button, Progressbar, Entry
from tkinter import scrolledtext
from multiprocessing import Process, Manager, Queue
from queue import Empty
from decimal import Decimal, getcontext
DELAY1 = 80
DELAY2 = 20
q = Queue()
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, name="frame")
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Pi computation")
self.pack(fill=BOTH, expand=True)
self.grid_columnconfigure(4, weight=1)
self.grid_rowconfigure(3, weight=1)
lbl1 = Label(self, text="Digits:")
lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)
self.ent1 = Entry(self, width=10)
self.ent1.insert(END, "4000")
self.ent1.grid(row=0, column=1, sticky=W)
lbl2 = Label(self, text="Accuracy:")
lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)
self.ent2 = Entry(self, width=10)
self.ent2.insert(END, "100")
self.ent2.grid(row=0, column=3, sticky=W)
self.startBtn = Button(self, text="Start",
command=self.onStart)
self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)
self.pbar = Progressbar(self, mode='indeterminate')
self.pbar.grid(row=1, column=1, columnspan=3, sticky=W+E)
self.txt = scrolledtext.ScrolledText(self)
self.txt.grid(row=2, column=0, rowspan=4, padx=10, pady=5,
columnspan=5, sticky=E+W+S+N)
def onStart(self):
self.startBtn.config(state=DISABLED)
self.txt.delete("1.0", END)
digits = int(self.ent1.get())
accuracy = int(self.ent2.get())
self.p1 = Process(target=self.generatePi(q, digits, accuracy), args=())
self.p1.start()
self.pbar.start(DELAY2)
self.after(DELAY1, self.onGetValue)
def onGetValue(self):
if (self.p1.is_alive()):
self.after(DELAY1, self.onGetValue)
return
else:
try:
self.txt.insert('end', q.get(0))
self.txt.insert('end', "\n")
self.pbar.stop()
self.startBtn.config(state=NORMAL)
except Empty:
print("queue is empty")
def generatePi(self, q, digs, acc):
getcontext().prec = digs
pi = Decimal(0)
k = 0
n = acc
while k < n:
pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
(Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
(Decimal(1)/(8*k+6)))
k += 1
q.put(pi)
def main():
root = Tk()
root.geometry("400x350+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
With the change in code being:
self.p1 = Process(target=generatePi(q, digits, accuracy), args=())
To:
self.p1 = Process(target=self.generatePi(q, digits, accuracy), args=())
I got same problem when I try it I find windows system seems react late but in terminal it's actually running

askopenfilename() disables editing tkinter Entry [duplicate]

This question already has answers here:
No input possible after tk
(2 answers)
Closed 4 years ago.
I'm using the following code to open a file, read its lines into a list and filter them using a substring from an Entry:
def get_entries(self):
"""
Open a file and load entries into a list.
"""
try:
# self.file_name = "p1.py"
self.file_name = askopenfilename(title="Open file")
self.file_handle = open(self.file_name, "r")
except IOError:
messagebox.showinfo("Info", "No file has been openned.")
self.destroy()
else:
self.entry_list = self.file_handle.readlines()
self.update_list()
def update_list(self, *args):
"""
Update the list after each editing of the search filter
"""
search_term = self.search_var.get()
self.lbox.delete(*self.lbox.get_children())
for index, item in enumerate(self.entry_list):
if search_term.lower() in item.lower():
self.lbox.insert('', END, values=(index, item))
Why does it work fine using self.file_name = "p1.py" but using askopenfilename() disables editing the Entry?
Minimizing and restoring the window with the Entry fixes the problem.
I'm using PyCharm on Windows 10
Here is the rest of the code for reference:
from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkinter.filedialog import askopenfilename
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.file_name = ""
self.file_handle = ""
self.entry_list = None
self.search_label = Label(self, text="Filter: ")
self.search_var = StringVar()
self.search_var.trace("w", self.update_list)
self.search_entry = Entry(self, textvariable=self.search_var)
self.lbox = ttk.Treeview(self, columns=('indices', 'entries'), displaycolumns='entries', show='headings')
self.lbox.heading('entries', text="Entries", anchor="w")
self.confirm = Button(self, text="Confirm", width=10, command=self.confirm_action)
self.cancel = Button(self, text="Cancel", width=10, command=quit)
self.search_label.grid(row=0, column=0, sticky=E, padx=12, pady=5)
self.search_entry.grid(row=0, column=1, sticky=W, columnspan=4, pady=5)
self.lbox.grid(row=1, column=0, columnspan=3, sticky=(N, W, S, E), padx=12, pady=5)
self.cancel.grid(row=2, column=0, pady=5)
self.confirm.grid(row=2, column=1, sticky=W, padx=12, pady=5)
self.grid_columnconfigure(0, weight=1, uniform="u")
self.grid_columnconfigure(1, weight=1, uniform="u")
self.grid_columnconfigure(2, weight=4, uniform="u")
self.get_entries()
def get_entries(self): ...
def update_list(self, *args): ...
def confirm_action(self): ...
root = Tk()
root.title('Filter Listbox Test')
app = Application(master=root)
app.mainloop()
This seems to be a problem due to calling the askfilename before the root window is drawn. As a workaround you can add self.update() before you call askopenfilename.
class Application(Frame):
def __init__(self, master=None):
# ... stuff ...
self.update()
self.get_entries()
I'll file a bug report about this right now.

Return Value from TkInter Entry with Button

Python novice, here. I've noticed there are a lot of questions around the topic of returning values from a TkInter function, but none of the solutions seem to solve my issue.
I can successfully print self.e1path to the shell from within getPath.submit, but I cannot return it to the rest of my code. I'm using a print statement outside of the class to test whether I've successfully returned the CSV path.
from tkinter import *
import tkinter as tk
class getPath(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.label1 = tk.Label(self, text="CSV Path").grid(row=0, column=0)
self.e1 = tk.Entry(self, width=50)
self.e1Grid = self.e1.grid(row=0, column=1)
self.browse = tk.Button(self, text='Browse', command=self.getCSV).grid(row=0, column=2)
self.submit = tk.Button(self, text='Submit', command=self.submit).grid(row=1, column=1)
def getCSV(self):
self.fileName = filedialog.askopenfilename( filetypes = (('Comma Separated Values', '*.csv'), ('All Files', '*.*')), title = "Choose a CSV File")
self.e1.insert(10, self.fileName)
def submit(self):
self.e1Path = self.e1.get()
return self.e1Path
app = getPath()
app.mainloop()
print(app)
I figured it out! I needed to add a self.destroy() to the submit function. This stopped the mainloop and let me call on self.e1path outside of the function using app.e1path. New code:
from tkinter import *
import tkinter as tk
class getPath(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.label1 = tk.Label(self, text="CSV Path").grid(row=0, column=0)
self.e1 = tk.Entry(self, width=50)
self.e1Grid = self.e1.grid(row=0, column=1)
self.browse = tk.Button(self, text='Browse', command=self.getCSV).grid(row=0, column=2)
self.submit = tk.Button(self, text='Submit', command=self.submit).grid(row=1, column=1)
def getCSV(self):
self.fileName = filedialog.askopenfilename( filetypes = (('Comma Separated Values', '*.csv'), ('All Files', '*.*')), title = "Choose a CSV File")
self.e1.insert(10, self.fileName)
def submit(self):
self.e1Path = self.e1.get()
self.destroy()
app = getPath()
app.mainloop()
print(app.e1Path)

Resources