I'm relatively new to Python and this is my first application. The code works well when run though terminal and in Pycharm but when I packaged it using Py2app and tied launching it through the file created "Paattajahaku.app" I get the message "Paattajahaku quit unexpectedly." Does anyone know whats wrong?
Thanks!
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
from bs4 import BeautifulSoup as bs
import requests
import pandas as pd
from time import sleep
from random import randint
root = tk.Tk()
root.title("Tkinter open file dialog")
root.resizable(False, False)
root.geometry("300x150")
titleslist = []
nameslist = []
fonrlist = []
df = pd.DataFrame(titleslist)
def select_file():
filetypes = (
("text files", "*txt",
"excel files", "*xlsx")
)
filename = fd.askopenfile(
title="open a file",
initialdir="/",
)
print("Please wait...")
for files in filename:
newfo_nr = files.strip().zfill(8)
fonrlist.append(newfo_nr)
sleep(randint(2, 4)) # sleep for a random time
url = f"https://www.asiakastieto.fi/yritykset/fi/{newfo_nr}/paattajat"
page = requests.get(url)
soup = bs(page.content, "html.parser")
names = soup.find_all(attrs={"data-title": "Nimi"})
titles = soup.find_all(attrs={"data-title": "Asema"})
for title in titles:
titleslist.append(title.text)
for name in names:
nameslist.append(name.text)
number_of_names = len(nameslist)
number_of_fo_nr = len(fonrlist)
sumfo = number_of_names - number_of_fo_nr
for i in range(sumfo):
if i < sumfo:
fonrlist.append(newfo_nr.strip())
if title == " ":
break
else:
continue
break
else:
continue
break
else:
continue
break
print("Files saved")
df = pd.DataFrame(list(zip(fonrlist, titleslist, nameslist))) # works
try:
# with block automatically closes file
with fd.asksaveasfile(mode='w', defaultextension=".xlsx") as file:
df.to_excel(file.name)
except AttributeError:
# if user cancels save, filedialog returns None rather than a file object, and the 'with' will raise an error
print("The user cancelled save")
def saveFile():
try:
# with block automatically closes file
with fd.asksaveasfile(mode='w', defaultextension=".xlsx") as file:
df.to_excel(file.name, index=False, header=False)
except AttributeError:
# if user cancels save, filedialog returns None rather than a file object, and the 'with' will raise an error
print("The user cancelled save")
open_button = ttk.Button(
root,
text="Open a file",
command=select_file
)
exit_button = ttk.Button(
root,
text="Exit",
command=root.destroy
)
open_button.pack(expand=True)
exit_button.pack(expand=True)
root.mainloop()
Related
so I am making a program on tkinter that gets a response from a server and depending on the answer, it will change the background color, to either green for success or red for error, the problem is that I realized that when running the code, the windows.after() method doesn't wait till is done to continue and when I do the request for the server, it have to do it three times to check if the response is correct, and it is suppossed to change the window background color each time, but it is only doing it one time. And not only the background color changing fails, also I want to change a label's text when it is doing the request,but it does it really quick and I'm not able to diferentiate the changes, so the question is: how can I
How can I make the program wait until one line finishes running to go to the next one and not everything happens at the same time and so fast?
Here is a piece of my code, I removed the request part because I'm trying to solve this problem first:
# import gpiozero
# import picamera
import json
import requests
import tkinter as tk
with open("config.json") as file:
config = json.load(file)
ENDPOINT = config["ENDPOINT"]
USUARIO = config["USUARIO"]
ESTACION = config["ESTACION"]
TIEMPO_ESPERA = config["TIEMPO_ESPERA"]
PIN_RELE = config["PIN_RELE"]
PATH_SALIDA = ENDPOINT + "Salida.getTicket/" + ESTACION + "/" + USUARIO + "/"
barcode = ""
# RELAY = gpiozero.OutputDevice(PIN_RELE, active_high=True, initial_value=False)
# CAMERA = picamera.PiCamera()
def check_scan_barcode(event=None):
info_label.config(text = "Wait...")
barcode = barcode_entry.get()
barcode_entry.delete(0, "end")
for i in range(3):
response = get_request(ENDPOINT + barcode)
if response["data"] == "True":
success()
open_barrier()
else:
error()
info_label.config(text = "Scan barcode")
def get_request(url):
response = requests.get(url)
response.raise_for_status()
response = response.json()
return response
def normal():
window.configure(bg="white")
info_label.configure(bg="white")
def success():
window.configure(bg="green")
info_label.configure(bg="green")
window.after(1000, normal)
def error():
window.configure(bg="red")
info_label.configure(bg="red")
window.after(1000, normal)
def open_barrier(barcode):
# CAMERA.capture(f"/home/pi/Pictures{barcode}.jpg")
# RELAY.on()
# window.after(TIEMPO_ESPERA, RELAY.off)
pass
window = tk.Tk()
# window.attributes('-fullscreen', True)
info_label = tk.Label(window, text= "Scan barcode.", font=("Arial", 40))
info_label.pack()
barcode_entry = tk.Entry(window, width=50)
barcode_entry.bind('<Return>', check_scan_barcode)
barcode_entry.pack(expand=True)
barcode_entry.focus()
window.mainloop()
I have installed Anaconda on my PC, and I've also added Anaconda to path. I've made a script which works fine in Jupyter, and it also works fine when I call it from the Anaconda Prompt terminal. However, when I try to execute it as a Python script from my desktop, nothing happens. I don't even get an output, so I can see what's going wrong. This is the script:
from bs4 import BeautifulSoup
import requests
import re
import urllib.request
import os
from tkinter import *
from PIL import Image, ImageTk
import tkinter as tk
from tkinter import Tk, Menu, Canvas
import datetime
from pathlib import Path
url = requests.get("https://politiken.dk/underholdning/wulffmorgenthaler/")
html = url.text
soup = BeautifulSoup(html,'lxml')
main = soup.find_all("a", attrs={"data-prefetchable":"true"})
list_of_links = []
for i in main:
list_of_links.append(re.findall(r'(https://politiken.dk/underholdning/wulffmorgenthaler/.{1,34}(?="))', str(i))[0])
list_of_links = list(dict.fromkeys(list_of_links))
counter = 0
def next_day():
global counter
counter += 1
today = datetime.date.today()
date = today - datetime.timedelta(days=counter)
final_date = date.strftime("%m%d")
image_downloader(final_date)
def prev_day():
global counter
if counter == 0:
pass
else:
counter -= 1
today = datetime.date.today()
date = today - datetime.timedelta(days=counter)
final_date = date.strftime("%m%d")
image_downloader(final_date)
def image_downloader(date_numbers):
global counter
my_file = Path(fr"C:\Users\Peter\Desktop\Wolfmorgenthaler/{date_numbers}.jpg")
if my_file.exists():
open_img(date_numbers)
elif counter<len(list_of_links):
new_url = requests.get(list_of_links[counter])
new_html = new_url.text
new_soup = BeautifulSoup(new_html,'html')
new_main = new_soup.find_all("img", attrs={"class":"media__image image--fullwidth"})
new_picture_links = re.findall(r'https.+? ', str(new_main[0]))
final_link = new_picture_links[0]
fullfilename = os.path.join(r"C:\Users\Peter\Desktop\Wolfmorgenthaler", f"{date_numbers}.jpg")
urllib.request.urlretrieve(final_link, fullfilename)
open_img(date_numbers)
else:
counter = counter - 1
def open_img(name):
filepath = fr"C:\Users\Peter\Desktop\Wolfmorgenthaler/{name}.jpg"
img = Image.open(filepath)
img = img.resize((960, 449), Image.ANTIALIAS)
img = ImageTk.PhotoImage(img)
panel = Label(root, image=img)
panel.image = img
panel.grid(row = 1, columnspan=4)
root = Tk()
root.geometry("964x483")
root.resizable(width=True, height=True)
today = datetime.date.today()
date = today - datetime.timedelta(days=counter)
final_date = date.strftime("%m%d")
image_downloader(final_date)
btn1 = Button(root, text='Næste billede', command=next_day, width = 67).grid(row = 2, column = 2)
btn2 = Button(root, text='Forrige billede', command=prev_day, width = 67).grid(row = 2, column = 1)
root.mainloop()
I just reset my PC today, and it worked just fine before I reset it. I have no idea how to get it to work. I would like to just have it be a clickable icon on my desktop, which executes the script.
Executing it with a batch file did not work either. Any ideas?
This is the weirdest solution found here:
Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website
" My workaround: I have copied the following files
libcrypto-1_1-x64.*
libssl-1_1-x64.*
from D:\Anaconda3\Library\bin to D:\Anaconda3\DLLs.
And it works as a charm! "
Hello i get following error:
pytube.exceptions.RegexMatchError: get_ytplayer_config: could not find match for config_patterns
My python version: 3.9.2
Can somebody please help me?
My Code:
from tkinter import ttk
from tkinter import filedialog
from pytube import YouTube #pip install pytube3
Folder_Name = ""
#file location
def openLocation():
global Folder_Name
Folder_Name = filedialog.askdirectory()
if(len(Folder_Name) > 1):
locationError.config(text=Folder_Name,fg="green")
else:
locationError.config(text="Please Choose Folder!!",fg="red")
#donwload video
def DownloadVideo():
choice = ytdchoices.get()
url = ytdEntry.get()
if(len(url)>1):
ytdError.config(text="")
yt = YouTube(url)
if(choice == choices[0]):
select = yt.streams.filter(progressive=True).first()
elif(choice == choices[1]):
select = yt.streams.filter(progressive=True,file_extension='mp4').last()
elif(choice == choices[2]):
select = yt.streams.filter(only_audio=True).first()
else:
ytdError.config(text="Paste Link again!!",fg="red")
#download function
select.download(Folder_Name)
ytdError.config(text="Download Completed!!")
root = Tk()
root.title("YTD Downloader")
root.geometry("350x400") #set window
root.columnconfigure(0,weight=1)#set all content in center.
#Ytd Link Label
ytdLabel = Label(root,text="Enter the URL of the Video",font=("jost",15))
ytdLabel.grid()
#Entry Box
ytdEntryVar = StringVar()
ytdEntry = Entry(root,width=50,textvariable=ytdEntryVar)
ytdEntry.grid()
#Error Msg
ytdError = Label(root,text="Error Msg",fg="red",font=("jost",10))
ytdError.grid()
#Asking save file label
saveLabel = Label(root,text="Save the Video File",font=("jost",15,"bold"))
saveLabel.grid()
#btn of save file
saveEntry = Button(root,width=10,bg="red",fg="white",text="Choose Path",command=openLocation)
saveEntry.grid()
#Error Msg location
locationError = Label(root,text="Error Msg of Path",fg="red",font=("jost",10))
locationError.grid()
#Download Quality
ytdQuality = Label(root,text="Select Quality",font=("jost",15))
ytdQuality.grid()
#combobox
choices = ["720p","144p","Only Audio"]
ytdchoices = ttk.Combobox(root,values=choices)
ytdchoices.grid()
#donwload btn
downloadbtn = Button(root,text="Donwload",width=10,bg="red",fg="white",command=DownloadVideo)
downloadbtn.grid()
#developer Label
developerlabel = Label(root,text="Dream Developers",font=("jost",15))
developerlabel.grid()
root.mainloop()
The error pytube.exceptions.RegexMatchError: get_ytplayer_config: could not find match for config_patterns has been a known bug in pytube. You can either update the request.py file. Or the best way is to update pytube:
python -m pip uninstall pytube pytube3 pytubex
python -m pip install git+https://github.com/nficano/pytube
In Python 3.6.4, what is a good approach for starting a new separate process or thread on every click of a button? I have written this code but it's not working the way I want it to.
from multiprocessing import process
import requests
import threading
from tkinter import *
def download():
name=entry2.get()
url=entry1.get()
r = requests.head(url)
if name:
file_name = name
else:
file_name = url.split('/')[-1]
try:
file_size = int(r.headers['content-length'])
part=file_size/4
start=0
end=part
except:
print ("Invalid URL")
return
print ('%s downloaded' % file_name)
def thread(url):
file_name=entry2.get()
r=requests.get(url)
data=r.content
with open('file_name','rb+')as fp:
data1=fp.read()
with open('file_name',"wb+") as fp:
data1=fp.write(data)
print("its working3")
if __name__=='__main__':
p=process(target=download,args=())
p.start()
p.join()
root=Tk()
frame=Frame(root,width=500,height=450,bg="lightpink")
url1=Label(frame,text="enter url here")
name=Label(frame,text="enter the name of the file")
url1.grid(row=0,sticky=E)
name.grid(row=1,sticky=E)
entry1=Entry(frame)
entry2=Entry(frame)
entry1.grid(row=0,column=1)
entry2.grid(row=1,column=1)
button1=Button(frame,text="download" ,command=download)
button1.grid(row=2,column=0)
button3=Button(frame,text="quit",command=frame.quit)
button3.grid(row=2,column=1)
frame.grid()
print("its working4")
root.mainloop()
Does this do the job? It uses the threading module rather than multiprocessing:
#from multiprocessing import process
from threading import Thread as process
import requests
import threading
from tkinter import *
def download():
name=entry2.get()
url=entry1.get()
r = requests.head(url)
if name:
file_name = name
else:
file_name = url.split('/')[-1]
try:
file_size = int(r.headers['content-length'])
part=file_size/4
start=0
end=part
except:
print ("Invalid URL")
return
print ('%s downloaded' % file_name)
def thread(url):
file_name=entry2.get()
r=requests.get(url)
data=r.content
with open('file_name','rb+')as fp:
data1=fp.read()
with open('file_name',"wb+") as fp:
data1=fp.write(data)
print("its working3")
root=Tk()
frame=Frame(root,width=500,height=450,bg="lightpink")
url1=Label(frame,text="enter url here")
name=Label(frame,text="enter the name of the file")
url1.grid(row=0,sticky=E)
name.grid(row=1,sticky=E)
entry1=Entry(frame)
entry2=Entry(frame)
entry1.grid(row=0,column=1)
entry2.grid(row=1,column=1)
button1=Button(frame,text="download" ,command=lambda: process (target = download).start ())
button1.grid(row=2,column=0)
button3=Button(frame,text="quit",command=root.destroy)
button3.grid(row=2,column=1)
frame.grid()
print("its working4")
root.mainloop()
I need a progress to show during file download for Python 3.
I have seen a few topics on Stackoverflow, but considering that I'm a noob at programming and nobody posted a complete example, just fractions of it, or the one that I can make work on Python 3, none are good for me...
additional info:
ok, so i have this:
from urllib.request import urlopen
import configparser
#checks for files which need to be downloaded
print(' Downloading...')
file = urlopen(file_url)
#progress bar here
output = open('downloaded_file.py','wb')
output.write(file.read())
output.close()
os.system('downloaded_file.py')
script is run through python command line
There is urlretrieve() that downloads an url to a file and allows to specify a reporthook callback to report progess:
#!/usr/bin/env python3
import sys
from urllib.request import urlretrieve
def reporthook(blocknum, blocksize, totalsize):
readsofar = blocknum * blocksize
if totalsize > 0:
percent = readsofar * 1e2 / totalsize
s = "\r%5.1f%% %*d / %d" % (
percent, len(str(totalsize)), readsofar, totalsize)
sys.stderr.write(s)
if readsofar >= totalsize: # near the end
sys.stderr.write("\n")
else: # total size is unknown
sys.stderr.write("read %d\n" % (readsofar,))
urlretrieve(url, 'downloaded_file.py', reporthook)
Here's a GUI progress bar:
import sys
from threading import Event, Thread
from tkinter import Tk, ttk
from urllib.request import urlretrieve
def download(url, filename):
root = progressbar = quit_id = None
ready = Event()
def reporthook(blocknum, blocksize, totalsize):
nonlocal quit_id
if blocknum == 0: # started downloading
def guiloop():
nonlocal root, progressbar
root = Tk()
root.withdraw() # hide
progressbar = ttk.Progressbar(root, length=400)
progressbar.grid()
# show progress bar if the download takes more than .5 seconds
root.after(500, root.deiconify)
ready.set() # gui is ready
root.mainloop()
Thread(target=guiloop).start()
ready.wait(1) # wait until gui is ready
percent = blocknum * blocksize * 1e2 / totalsize # assume totalsize > 0
if quit_id is None:
root.title('%%%.0f %s' % (percent, filename,))
progressbar['value'] = percent # report progress
if percent >= 100: # finishing download
quit_id = root.after(0, root.destroy) # close GUI
return urlretrieve(url, filename, reporthook)
download(url, 'downloaded_file.py')
On Python 3.3 urlretrieve() has different reporthook interface (see issue 16409). To workaround it, you could access the previous interface via FancyURLopener:
from urllib.request import FancyURLopener
urlretrieve = FancyURLopener().retrieve
To update the progress bar within the same thread, you could inline urlretrieve() code:
from tkinter import Tk, ttk
from urllib.request import urlopen
def download2(url, filename):
response = urlopen(url)
totalsize = int(response.headers['Content-Length']) # assume correct header
outputfile = open(filename, 'wb')
def download_chunk(readsofar=0, chunksize=1 << 13):
# report progress
percent = readsofar * 1e2 / totalsize # assume totalsize > 0
root.title('%%%.0f %s' % (percent, filename,))
progressbar['value'] = percent
# download chunk
data = response.read(chunksize)
if not data: # finished downloading
outputfile.close()
root.destroy() # close GUI
else:
outputfile.write(data) # save to filename
# schedule to download the next chunk
root.after(0, download_chunk, readsofar + len(data), chunksize)
# setup GUI to show progress
root = Tk()
root.withdraw() # hide
progressbar = ttk.Progressbar(root, length=400)
progressbar.grid()
# show progress bar if the download takes more than .5 seconds
root.after(500, root.deiconify)
root.after(0, download_chunk)
root.mainloop()
download2(url, 'downloaded_file.py')
I think this piece of code can help you. I'm not quite sure it's exactly what you want. At least it should give you something to work on.
import tkinter
from tkinter import ttk
from urllib.request import urlopen
def download(event):
file = urlopen('http://www.python.org/')
output = open('downloaded_file.txt', 'wb')
lines= file.readlines()
i = len(lines)
for line in lines:
output.write(line)
pbar.step(100/i)
output.close()
file.close()
root = tkinter.Tk()
root.title('Download bar')
pbar = ttk.Progressbar(root, length=300)
pbar.pack(padx=5, pady=5)
btn = tkinter.Button(root, text="Download")
# bind to left mouse button click
btn.bind("<Button-1>", download)
btn.pack(pady=10)
root.mainloop()
This works, I've tried it.