本文介绍了在Tkinter应用程序中可能的锁定问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为我的tkinter应用程序创建一个滑动菜单,但我遇到了一个问题,我怀疑来自我没有正确锁定线程。虽然我一直在使用Python一段时间,我对tkinter和线程应用程序是相对新的,我希望在这里的人可能能够阐明我做错了什么。

I'm trying to create a sliding menubar for my tkinter application, but I've run into an issue that I suspect comes from my not locking a thread properly. While I have been dabbling with Python for a while, I'm relatively new to both tkinter and threaded applications, and I hoped someone here might be able to shed a little light on what I'm doing wrong.

我的代码如下:

class MenuBar():

def slide_out(self, event = None):

    def helper():
        while self.canvas.coords(self.bg)[0] > 100 and self.mouseIn:
            self.canvas.move(self.bg, -5, 0)
            sleep(0.01)

    self.mouseIn = True
    Thread(target = helper).start()

def slide_in(self, event):
    self.mouseIn = False
    self.canvas.coords(self.bg, 750, 0)

def __init__(self, canvas):
    self.canvas = canvas

    self.bgImg = ImageTk.PhotoImage(file = "Options Bar.png")
    self.bg = canvas.create_image(750, 0, anchor = "nw", image = self.bgImg, tags = ("menubar", "menubarbackground"))

    self.mouseIn = False

    self.canvas.tag_bind("menubar", "<Enter>", self.slide_out)
    self.canvas.tag_bind("menubar", "<Leave>", self.slide_in)

程式化更简单。我在菜单栏上鼠标时收到的错误如下:

I'm working within a canvas widget as it makes stylization simpler. The error - which I receive upon mousing over the menu bar - is as follows:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python33\lib\threading.py", line 639, in _bootstrap_inner
    self.run()
  File "C:\Python33\lib\threading.py", line 596, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\alex\Desktop\Python - VN Work\readingscreen.py", line 12, in helper
    while self.canvas.coords(self.bg)[0] > 100 and self.mouseIn:
  File "C:\Python33\lib\tkinter\__init__.py", line 2264, in coords
    self.tk.call((self._w, 'coords') + args))]
  File "C:\Python33\lib\tkinter\__init__.py", line 2262, in <listcomp>
    return [getdouble(x) for x in
ValueError: could not convert string to float: 'None'

现在,当我在线程之外调用它时,它所抱怨的canvas方法起作用。还值得一提的是,如果我在self.canvas.coords调用之前的辅助函数中对self.bg进行任何引用,则不会发生错误。添加一些无用的引用,但是,几乎不像是一个修复。我担心,如果我现在不解决这个问题,以后只会加剧一些其他问题。

Now the canvas method about which it is complaining works when I call it outside of a thread. It also merits mentioning that if I make any reference to self.bg in the helper function prior to the self.canvas.coords call no error occurs. Adding some useless reference however, hardly seems like a fix. I'm worried that if I don't address this now it will only exacerbate some other issue later on.

我是对的,假设我需要锁定我的线程,以便让它引用self.bg没有问题,或者有什么在这里我缺少?我试着在MenuBar类中添加一个锁,获取它并在辅助方法中释放它,但是没有效果。

I'm I right to assume that I need to lock my thread so as to let it reference self.bg without issue, or is there something here I'm missing? I tried adding a lock to the MenuBar class, acquiring it and releasing it in the helper method, but to no avail.

任何人都有什么想法?感谢。

Any one have any idea? Thanks.

推荐答案

Tkinter不是线程安全的。您不能从任何线程调用小部件的方法,而不是从创建小部件的方法。添加锁定不会有帮助。

Tkinter isn't thread safe. You cannot call methods on widgets from any thread other than the one where the widget was created. Adding locking won't help.

对于像滑动菜单一样简单的东西,你不需要线程。有几个例子使用Tkinter通过利用事件循环进行动画。基本上算法如下:

For something as simple as sliding a menu in and out, you don't need threads. There are several examples of doing animation with Tkinter by leveraging the event loop. Basically the algorithm looks like this:

def animate(...):
    <move the widget one or two pixels>
    <if the widget needs to move some more>:
        self.canvas.after(100, animate)

它的作用是简单的:它移动你的窗口小部件一个或两个像素,检查它是否完全可见或不,如果不是,它重新安排自己在几毫秒内再次运行。您可以调整动画的速度和平滑度,方法是调整每次迭代移动的像素数量,以及动画每个帧之间的间隔时间。

What it does is simple: it moves your widget one or two pixels, checks to see if it's fully visible or not, and if not, it reschedules itself to run again in a few milliseconds. You can adjust the speed and smoothness of the animation by adjusting how many pixels you move on each iteration, and how many milliseconds between each frame of animation.

这篇关于在Tkinter应用程序中可能的锁定问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 10:03