鱼C论坛

 找回密码
 立即注册
查看: 1513|回复: 4

线程会干扰其它函数的使用吗?

[复制链接]
发表于 2019-10-17 17:45:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我要将一些网络图片显示到tkinter的label上,以下是部分代码:
  1.     def zoom_image(url):
  2.         #将缩小后的图片转为label可以显示的格式
  3.         image_bytes = urlopen(url).read()
  4.         data_stream = io.BytesIO(image_bytes)
  5.         pil_image = Image.open(data_stream)
  6.         w,h = pil_image.size
  7.         def resize(w,h,pil_image):
  8.             #将网络图片按照比例缩小尺寸
  9.             f1 = 1.0*142/w
  10.             f2 = 1.0*172/h
  11.             factor = min([f1,f2])
  12.             width = int(w*factor)
  13.             height = int(h*factor)
  14.             return pil_image.resize((width,height),Image.ANTIALIAS)
  15.         pil_image_resize = resize(w,h,pil_image)
  16.        [color=Red] image = ImageTk.PhotoImage(pil_image_resize)[/color]
  17.         return image
复制代码


这部分代码直接运行的话很正常,但是如果想要通过线程去执行 zoom_image(url) ,就会在最后一行 'image = ImageTk.PhotoImage(pil_image_resize)' 出错。错误信息如下:
  1. Exception in thread Thread-2:
  2. Traceback (most recent call last):
  3.   File "D:\Program Files\Python\lib\threading.py", line 917, in _bootstrap_inner
  4.     self.run()
  5.   File "D:\Program Files\Python\lib\threading.py", line 865, in run
  6.     self._target(*self._args, **self._kwargs)
  7.   File "C:\Users\kangaroo\Desktop\1212112.py", line 166, in showtime
  8.     photo[i] = Data_Processing.zoom_image(image_list[i])
  9.   File "C:\Users\kangaroo\Desktop\1212112.py", line 86, in zoom_image
  10.     image = ImageTk.PhotoImage(image=pil_image_resize,size=pil_image_resize.size)
  11.   File "D:\Program Files\Python\lib\site-packages\PIL\ImageTk.py", line 118, in __init__
  12.     self.__photo = tkinter.PhotoImage(**kw)
  13.   File "D:\Program Files\Python\lib\tkinter\__init__.py", line 3545, in __init__
  14.     Image.__init__(self, 'photo', name, cnf, master, **kw)
  15.   File "D:\Program Files\Python\lib\tkinter\__init__.py", line 3501, in __init__
  16.     self.tk.call(('image', 'create', imgtype, name,) + options)
  17. RuntimeError: main thread is not in main loop

  18. Exception ignored in: <function PhotoImage.__del__ at 0x000001C5D056CD90>
  19. Traceback (most recent call last):
  20.   File "D:\Program Files\Python\lib\site-packages\PIL\ImageTk.py", line 124, in __del__
  21.     name = self.__photo.name
  22. AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'

复制代码



有没有高手可以告诉我是为什么吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-10-17 23:35:04 | 显示全部楼层
线程是会干扰函数的。(你的程序我没看)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-18 01:10:27 | 显示全部楼层
  1. from threading import Thread
  2. num = 0

  3. def run(n):
  4.     global num
  5.     for i in range(10):
  6.         num += n  #当线程同时执行到这里,num已经等于9,另外一个线程执行了 9 + 6 此时num=15
  7.         num -= n #这里执行就变成  15 - 6

  8. if __name__ == '__main__':
  9.     t1 = Thread(target=run,args=(6,))
  10.     t2 = Thread(target=run,args=(9,))
  11.     t1.start()
  12.     t2.start()
  13.     t1.join()
  14.     t2.join()

  15.     print("NUM =",num)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-18 11:43:19 | 显示全部楼层

你的这段代码我基本看懂了,2 个线程处理同一个事情,演示了子线程之间、子线程和主线程之间的先后顺序,但是对我的问题帮助不大。我的问题应该是子线程和主线程之间的问题。
主线程处理了UI,子线程处理 image = ImageTk.PhotoImage(pil_image_resize) 显示,只有当UI先处理再处理显示才会不报错。但不懂怎么去协调主线程和子线程之间的先后顺序,join()不行。
或者我可以将UI作为另一个子线程去处理。。。。。。可能比较麻烦了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-10-18 13:26:04 | 显示全部楼层
你的代码我没细看,但是我用wxpython时遇到过有的方法不在主线程运行,就会报错,解决方法是用回调函数。
https://fishc.com.cn/thread-146413-1-1.html

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-1-20 02:09

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表