gpt4 book ai didi

python - Tkinter 代码在 Windows 上运行,但不能在 Linux 上运行

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:27:21 25 4
gpt4 key购买 nike

我在 Windows 中编写了这段代码并且它可以工作但是当我将它复制到我的树莓派(运行基于 Jessie Debian 的系统)时它会出现运行时错误

我的代码:

from Tkinter import *
from PIL import ImageTk,Image
from time import sleep
import thread
root = Tk()
img=ImageTk.PhotoImage(Image.open("1.jpg").resize((root.winfo_screenwidth()-3,root.winfo_screenheight()-3)))
panel = Label(root, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
if __name__ == '__main__':
thread.start_new_thread(root.mainloop,())
for i in xrange(1,5):
sleep(1)
img2 = ImageTk.PhotoImage(Image.open(str(i)+".jpg").resize((root.winfo_screenwidth()-3,root.winfo_screenheight()-3)))
panel.configure(image = img2)
panel.image = img2

在 linux 中执行时会报错:

Unhandled exception in thread started by <bound method Tk.mainloop of <Tkinter.Tk instance at 0x75b605d0>>
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1124, in mainloop
self.tk.mainloop(n)
RuntimeError: Calling Tcl from different appartment

我应该怎么做才能在两个平台上运行这段代码

最佳答案

不能从不同的线程调用 Tcl 函数。它在 Windows 上运行的事实可能是因为对该条件的检查有误。

您需要做的是拥有一个与Tk 对话的“UI 线程”。通常,此线程显式执行的所有操作是:

  • 设置所有的小部件和事件处理程序
  • 调用root.mainloop()

如果您随后想要更改 UI,您应该在事件处理程序中进行。如果您想执行一些代码以响应非 UI 事件,您可以在 root 注册自定义事件处理程序或使用 after 在主循环上执行计划函数.

from Tkinter import *
from PIL import ImageTk, Image

root = Tk()
panel = Label(root)
panel.pack(side = "bottom", fill = "both", expand = "yes")

def showImage(i):
img = ImageTk.PhotoImage(Image.open(str(i)+".jpg"))
img = img.resize((root.winfo_screenwidth()-3, root.winfo_screenheight()-3))
panel.configure(image = img)
panel.image = img

class Task(object):
# A little helper to wrap a function with arguments.
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.args = args
self.kwargs = kwargs
def __call__(self):
self.fun(*self.args, **self.kwargs)

if __name__ == '__main__':
for i in range(1, 5):
# run showImage(i) on the mainloop after (i - 1) seconds
root.after((i - 1) * 1000, Task(showImage, i))
root.mainloop()

如果需要,您可以从另一个线程调度函数:

import thread

def doStuff():
for i in range(1, 5):
sleep(1)
root.after(0, Task(showImage, i))

thread.start_new_thread(doStuff, ())

注意:我创建了 Task 来轻松指定我想使用给定的 i 运行 showImage。通常,functools.partial 会很好,但由于 dynamic create method and decorator, got error 'functools.partial' object has no attribute '__module__',它显然不能很好地与 Tkinter 配合使用。

你也可以这样做:

(lambda ii: lambda: showImage(ii))(i)

但是当您稍后返回代码时,这可能会造成混淆。

如果您预计不会有其他任务,您可以这样做:

def showImage(i):
def newfun():
img = ImageTk.PhotoImage(Image.open(str(i)+".jpg"))
img = img.resize((root.winfo_screenwidth()-3, root.winfo_screenheight()-3))
panel.configure(image = img)
panel.image = img
return newfun

关于python - Tkinter 代码在 Windows 上运行,但不能在 Linux 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36369963/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com