python - 使用 Tkinter 扫描线程违规

标签 python multithreading tkinter

我们即将完成对使用 python2.5 和 Tkinter 构建的应用程序的一次非常大的更新,但遗憾的是出现了以下错误:

alloc: invalid block: 06807CE7: 1 0 0

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

我们之前已经见过这种情况,通常是非 GUI 线程尝试通过 Tkinter 访问 TK 时导致的 Tcl 中断错误(TK 不是线程安全的)。在 python 中断器完成我们的代码后,应用程序关闭时会弹出错误。这个错误很难重现,我想我必须扫描系统中的所有线程,看看它们是否在不应该访问的时候访问了 TK。

我正在寻找一个神奇的Python技巧来帮助解决这个问题。我们使用的所有 Tkinter 小部件首先都是子类化的,并从我们自己的 Widget 基类继承。

考虑到这一点,我正在寻找一种方法将以下检查添加到小部件子类中每个方法的开头:

import thread
if thread.get_ident() != TKINTER_GUI_THREAD_ID:
    assert 0, "Invalid thread accessing Tkinter!"

装饰器作为部分解决方案浮现在脑海中。然而,我不想手动向每个方法添加装饰器。有没有一种方法可以将装饰器添加到从 Widget 基类继承的类的所有方法中?或者有更好的方法来完成这一切吗?或者有人有关于此错误的更多信息吗?

enter code here

最佳答案

我不知道你的方法是否好,因为我不了解 Tkinter。

但这里有一个如何使用元类装饰所有类方法的示例。

import functools

# This is the decorator
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print 'calling', func.__name__, 'from decorator'
        return func(*args, **kwargs)

    return wrapper

# This is the metaclass
class DecorateMeta(type):
    def __new__(cls, name, bases, attrs):
        for key in attrs:
            # Skip special methods, e.g. __init__
            if not key.startswith('__') and callable(attrs[key]):
                attrs[key] = my_decorator(attrs[key])

        return super(DecorateMeta, cls).__new__(cls, name, bases, attrs)

# This is a sample class that uses the metaclass
class MyClass(object):
    __metaclass__ = DecorateMeta

    def __init__(self):
        print 'in __init__()'

    def test(self):
        print 'in test()'

obj = MyClass()
obj.test()

元类会覆盖类的创建。它循环遍历正在创建的类的所有属性,并用 my_decorator 装饰所有具有“常规”名称的可调用属性。

关于python - 使用 Tkinter 扫描线程违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5177290/

相关文章:

python - 是否可以在 Django 中使用逻辑或查询

python - 在 Tornado 中使用 POST 请求删除数据?

java - 黑莓中异步列表字段实现时出现 IllegalThreadStateException

c - 如何将 Windows 消息从一个线程传递到另一个线程?

c# - 线程和 SqlFileStream。进程无法访问指定的文件,因为它已在另一个事务中打开

python - 循环中带有变量的 tkinter 绑定(bind)函数

python - 重命名对象内部repr,name//tkinter问题

python - 将值从一个 python 脚本发送到另一个 python 脚本

python - 如何将python 3.4.3脚本编译为exe?

python - 将每日数据按月份分组并计算每个用户的对象数