2

I am creating a chinese checkers AI. I want to make the board, and check the mouse position meanwhile. I decided to use multithreading:

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()

But when I run it in terminal, I get:

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
)

What happened? Is there something wrong with the tkinter window?

martineau
  • 119,623
  • 25
  • 170
  • 301
F. Zeng
  • 85
  • 1
  • 2
  • 11
  • 1
    Don't use threading with Tkinter if you don't have to. If you really have to, use Tkinter's TopLevel widget for your UI element, and implement your own event loop. It's a nuisance, to be avoided if possible. – rd_nielsen Nov 12 '18 at 01:03
  • @rd_nielsen: the use of threads is completely unrelated to the use of `Toplevel`. The important thing with threads is that you can only access tkinter objects from a single thread. – Bryan Oakley Nov 12 '18 at 04:26

1 Answers1

3

Tkinter (like almost all GUI frameworks I'm aware of), require that modifications to the GUI state happen on a particular thread. See this question for more discussion on why. This doesn't mean that there can't be any other threads in your application- just that you can't modify the state of the GUI from those other threads.

If you must use other threads to keep long-running tasks from hogging the thread being used for the GUI, you can have worker threads that interact with the main thread via a Queue, as described here.

I can't caveat enough that multithreading will multiply the complexity of your application by 10x (especially if you are new to concepts like Queues). However, if you are unfamiliar with Queues and their typical use in concurrent programming and still want to get started, a good place to begin is with the producer/consumer pattern. For an even more foundational look at what the "queue" concept means in comp-sci, you can look at this page which describes a queue and has you implement your own simple version of one.

augray
  • 3,043
  • 1
  • 17
  • 30
  • I'm sorry, but i'm not good at python yet. I am, after all, in 5th grade. Can you explain to me what Queue is about? – F. Zeng Nov 12 '18 at 01:30
  • 2
    In general, queues are a data structure (like a `list` or `dict` that hold objects), but they're made to work so that the order you place things in the queue is the order they get removed. Think of a checkout line at the store. The queue in `from queue import Queue` in python is designed with other tools for concurrent programming. In particular, it can "block" when you try to `get` from one thread while other threads are working to create things to put on the queue. – augray Nov 12 '18 at 01:37
  • 1
    also added some useful references to the answer – augray Nov 12 '18 at 01:45