【发布时间】:2020-01-11 00:47:31
【问题描述】:
问题:
我通过 unsplash API 设置了一个图像下载 GUI 应用程序(tkinter)。 每件事都在进行中。没有任何错误,但是当我运行应用程序时 它显示“未响应”导致图像在后台下载。如何创建两个线程。一个将处理 tkinter GUI,第二个将处理背景图像下载过程。
我的代码:
from tkinter import *
import requests
import os, pprint
from time import sleep
from threading import *
from urllib.request import urlretrieve
class Gui(Tk):
def __init__(self):
self.do_splash_call = False
Tk.__init__(self)
self.title('unsplash image download')
self.geometry('900x500')
# main canvas
main = Canvas(self, bg='#0099e6')
main.place(relx=0, rely=0, relwidth=1, relheight=1)
# frame1 for upper left
name_frame = Frame(main)
name_frame.place(relx=.1, rely=.1)
# name input and label
name_label = Label(name_frame, text='Image Name:')
name_label.pack(side=LEFT, pady=3)
self.name = Entry(name_frame, bd=0, font=2, width=23)
self.name.pack(side=RIGHT, pady=3)
# frame2 for upper right
page_frame = Frame(main)
page_frame.place(relx=.5, rely=.1, relwidth=.3)
# landing page
Label(page_frame, text='Landing page:').pack(side=LEFT, pady=3)
self.page = Spinbox(page_frame, from_=1, to=50, width=30)
self.page.pack(side=RIGHT, pady=3)
# frame3 for down left
size_frame = Frame(main)
size_frame.place(relx=.1, rely=.2)
# name input and label
size_label = Label(size_frame, text='Android, pc, tablet:')
size_label.pack(side=LEFT, pady=3)
self.size = Entry(size_frame, bd=0, font=2)
self.size.pack(side=RIGHT, pady=3)
# button
download = Button(main, bd=1, font=4, text='Download', width=10, command=lambda :self.splash())
download.place(relx=.6, rely=.2)
# output
self.output = Text(main, bd=2)
self.output.place(relx=0, rely=.5, relheight=1, relwidth=1)
# path to save images
save_frame = Frame(main)
save_frame.place(relx=.1, rely=.3, relwidth=.7)
Label(save_frame, text='Save:').pack(side=LEFT, padx=5)
self.save = Entry(save_frame, bd=1)
self.save.place(relx=.1, relwidth=1)
# insert path for save images
self.save.insert(0, str('c:\\users\\abc\\Desktop\\photos'))
def path(self):
if os.path.exists(self.save.get()):
os.chdir(self.save.get())
else:
os.mkdir(self.save.get())
os.chdir(self.save.get())
def splash(self):
self.do_splash_call = True
self.call_splash()
def call_splash(self):
if self.do_splash_call:
# getting input from user
image_name = self.name.get()
pages = self.page.get()
size = self.size.get()
# set the size of photos
if size == 'pc' or 'desktop':
size = 1080
orientation = 'landscape'
elif size == 'hd' or 'full hd' or 'clear' or 'normal' or 'HD':
size = 1500
orientation = 'landscape'
elif size == 'android' or 'mini' or 'mobile':
size = 400
orientation = 'portrait'
else:
size = 1500
orientation = 'landscape'
try:
api = f'''https://api.unsplash.com/photos/search?query=
{image_name}&resolution={size}&orientation=
{orientation}&client_id=API Key
&page={pages}&w=1500&dpi=2'''
res = requests.get(api).json()
for i in range(2):
url = res[i]['links']['download']
name_of_image = str(res[i]['alt_description'])
img_name = '_'.join(name_of_image[:40].split(' '))
# create folder for download images
self.path()
# print current images downloading
self.output.insert(INSERT, '\nDownloading img.... %s.png' % img_name)
self.output.tag_add('fine', '1.0', '3.0')
self.output.tag_config('fine', background='lightGreen', foreground='#196619')
# Downloading image in pc
urlretrieve(url, '%s.png' % img_name)
except Exception as e:
self.output.insert(INSERT, e)
self.output.tag_add('error', '1.0', '3.0')
self.output.tag_config('error', background='#ff4d4d', foreground='black')
print(e)
if __name__ == '__main__':
app = Gui()
app.mainloop()
我除外:
有一个类,里面有一个名为splash()的方法,所以我如何创建Thread,一个用于constructor,第二个用于splash() method?
【问题讨论】:
-
你只需要线程来运行
call_splash,但你应该在运行线程threading.Thread(taget=self.call_splash, args=(self.name.get(), self.page.get(), self.size.get()))和def call_splash(self, image_name, pages, size):之前从GUI获取值 -
拜托,你能在代码中实现它吗?这样会更好理解。
-
有很多关于如何在 python 中创建线程的文档。你做过研究吗?
标签: python python-3.x multithreading tkinter