我正在创建一个tkinter gui,我需要使其成为线程。但是线程不起作用

时间:2018-11-12 00:53:48

标签: python multithreading tkinter

我正在创建一个中国跳棋AI。我要制作电路板,并同时检查鼠标位置。我决定使用多线程:

from tkinter import *
from pyautogui import *
from threading import *

def create_board():
    #a lot of tkinter stuff
def check_mouse:
    if position()[0] > 390 & position()[0] < 455:
        print("mouse detected")

board = Thread(target=create_board)

board.start()

但是当我在终端中运行它时,我得到了:

2018-11-11 16:50:55.129 python[27074:8053445] WARNING: NSWindow drag regions should only be invalidated on the Main Thread! This will throw an exception in the future. Called from (
    0   AppKit                              0x00007fff44af22e3 -[NSWindow(NSWindow_Theme) _postWindowNeedsToResetDragMarginsUnlessPostingDisabled] + 386
    1   AppKit                              0x00007fff44aef68c -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1488
    2   AppKit                              0x00007fff44aef0b6 -[NSWindow initWithContentRect:styleMask:backing:defer:] + 45
    3   libtk8.6.dylib                      0x0000000101319426 TkMacOSXMakeRealWindowExist + 742
    4   libtk8.6.dylib                      0x0000000101318ffc TkWmMapWindow + 60
    5   libtk8.6.dylib                      0x0000000101261930 Tk_MapWindow + 192
    6   libtk8.6.dylib                      0x000000010126b541 MapFrame + 65
    7   libtcl8.6.dylib                     0x000000010119cc71 TclServiceIdle + 161
    8   libtcl8.6.dylib                     0x000000010117a39d Tcl_DoOneEvent + 397
    9   _tkinter.cpython-37m-darwin.so      0x000000010108a88e _tkinter_tkapp_mainloop + 286
    10  python                              0x000000010098eba6 _PyMethodDef_RawFastCallKeywords + 230
    11  python                              0x000000010099bae4 _PyMethodDescr_FastCallKeywords + 84
    12  python                              0x0000000100acf32e call_function + 382
    13  python                              0x0000000100accd19 _PyEval_EvalFrameDefault + 45065
    14  python                              0x0000000100ac0a42 _PyEval_EvalCodeWithName + 418
    15  python                              0x000000010098ea73 _PyFunction_FastCallKeywords + 195
    16  python                              0x0000000100acf265 call_function + 181
    17  python                              0x0000000100accdaf _PyEval_EvalFrameDefault + 45215
    18  python                              0x000000010098e368 function_code_fastcall + 120
    19  python                              0x0000000100acd1c6 _PyEval_EvalFrameDefault + 46262
    20  python                              0x000000010098e368 function_code_fastcall + 120
    21  python                              0x0000000100acf265 call_function + 181
    22  python                              0x0000000100accd19 _PyEval_EvalFrameDefault + 45065
    23  python                              0x000000010098e368 function_code_fastcall + 120
    24  python                              0x0000000100acf265 call_function + 181
    25  python                              0x0000000100accd19 _PyEval_EvalFrameDefault + 45065
    26  python                              0x000000010098e368 function_code_fastcall + 120
    27  python                              0x0000000100991782 method_call + 130
    28  python                              0x000000010098f1e2 PyObject_Call + 130
    29  python                              0x0000000100baf5cb t_bootstrap + 123
    30  libsystem_pthread.dylib             0x00007fff747a133d _pthread_body + 126
    31  libsystem_pthread.dylib             0x00007fff747a42a7 _pthread_start + 70
    32  libsystem_pthread.dylib             0x00007fff747a0425 thread_start + 13
)

发生了什么事? tkinter窗口有问题吗?

1 个答案:

答案 0 :(得分:2)

Tkinter(就像我所知道的几乎所有GUI框架一样),要求在特定线程上对GUI状态进行修改。有关原因的更多讨论,请参见this question。这并不意味着您的应用程序中就不能 其他任何线程,只是您不能从其他线程中修改GUI的状态。

如果必须使用其他线程来防止长时间运行的任务占用用于GUI的线程,则可以使工作线程通过Queue与主线程进行交互,如here所述。

我还不足以使多线程将应用程序的复杂性提高10倍(特别是如果您不熟悉Queue之类的概念时)。但是,如果您不熟悉Queue及其在并发编程中的典型用法,并且仍然想入门,那么producer/consumer pattern是一个不错的起点。要更深入地了解“队列”概念在comp-sci中的含义,您可以查看this page,它描述了一个队列,并实现了自己的简单版本。