Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python crashes when opening window on Mac with solution #10

Open
geosjackson opened this issue Jun 29, 2021 · 1 comment
Open

Python crashes when opening window on Mac with solution #10

geosjackson opened this issue Jun 29, 2021 · 1 comment

Comments

@geosjackson
Copy link

I am trying to run PebbleCounts on a 2013 Mac Pro (Catalina 10.15.7). I followed the installation instructions for Mac verbatim from the manual, and found that both PebbleCounts.py and PebbleCountsAuto.py run smoothly up until the program needs to open a window, at which point Python crashes and throws the following exception:

2021-06-17 10:06:50.916 python[11061:572913] -[NSApplication macMinorVersion]: unrecognized selector sent to instance 0x7ff0c5b33d90
2021-06-17 10:06:50.940 python[11061:572913] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSApplication macMinorVersion]: unrecognized selector sent to instance 0x7ff0c5b33d90'
*** First throw call stack:
(
	0   CoreFoundation                      0x00007fff204ee6af __exceptionPreprocess + 242
	1   libobjc.A.dylib                     0x00007fff202263c9 objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff20570c85 -[NSObject(NSObject) __retain_OA] + 0
	3   CoreFoundation                      0x00007fff2045607d ___forwarding___ + 1467
	4   CoreFoundation                      0x00007fff20455a38 _CF_forwarding_prep_0 + 120
	5   libtk8.6.dylib                      0x0000001a2ff0edb9 SetCGColorComponents + 265
	6   libtk8.6.dylib                      0x0000001a2ff0f67a TkpGetColor + 250
	7   libtk8.6.dylib                      0x0000001a2fe49aa9 Tk_GetColor + 153
	8   libtk8.6.dylib                      0x0000001a2fe398e6 Tk_Get3DBorder + 134
	9   libtk8.6.dylib                      0x0000001a2fe3974f Tk_Alloc3DBorderFromObj + 127
	10  libtk8.6.dylib                      0x0000001a2fe4afad DoObjConfig + 941
	11  libtk8.6.dylib                      0x0000001a2fe4aae5 Tk_InitOptions + 357
	12  libtk8.6.dylib                      0x0000001a2fe4a9c5 Tk_InitOptions + 69
	13  libtk8.6.dylib                      0x0000001a2fe7bb5c CreateFrame + 1548
	14  libtk8.6.dylib                      0x0000001a2fe7be37 TkListCreateFrame + 151
	15  libtk8.6.dylib                      0x0000001a2fe737f8 Initialize + 2168
	16  _tkinter.cpython-36m-darwin.so      0x0000001a2fca5a16 _tkinter_create + 1174
	17  python                              0x0000000109a3dd48 _PyCFunction_FastCallDict + 200
	18  python                              0x0000000109b1339f call_function + 143
	19  python                              0x0000000109b10ef4 _PyEval_EvalFrameDefault + 46836
	20  python                              0x0000000109b04649 _PyEval_EvalCodeWithName + 425
	21  python                              0x0000000109b1403c _PyFunction_FastCallDict + 364
	22  python                              0x00000001099bcdc0 _PyObject_FastCallDict + 320
	23  python                              0x00000001099e43d8 method_call + 136
	24  python                              0x00000001099c43de PyObject_Call + 62
	25  python                              0x0000000109a65285 slot_tp_init + 117
	26  python                              0x0000000109a697c1 type_call + 241
	27  python                              0x00000001099bcd31 _PyObject_FastCallDict + 177
	28  python                              0x0000000109b13498 call_function + 392
	29  python                              0x0000000109b10ef4 _PyEval_EvalFrameDefault + 46836
	30  python                              0x0000000109b04649 _PyEval_EvalCodeWithName + 425
	31  python                              0x0000000109b137fa fast_function + 362
	32  python                              0x0000000109b133fc call_function + 236
	33  python                              0x0000000109b10ef4 _PyEval_EvalFrameDefault + 46836
	34  python                              0x0000000109b1374c fast_function + 188
	35  python                              0x0000000109b133fc call_function + 236
	36  python                              0x0000000109b10ef4 _PyEval_EvalFrameDefault + 46836
	37  python                              0x0000000109b04649 _PyEval_EvalCodeWithName + 425
	38  python                              0x0000000109b5d12c PyRun_FileExFlags + 252
	39  python                              0x0000000109b5c604 PyRun_SimpleFileExFlags + 372
	40  python                              0x0000000109b83346 Py_Main + 3734
	41  python                              0x00000001099b4d99 main + 313
	42  libdyld.dylib                       0x00007fff20397621 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

I have reproduced everything on a 2019 MacBook Pro (Big Sur 11.2.1), and the errors are identical between the two machines.

I have found discussions of matplotlib backend issues on Mac, which generally advise using TkAgg (MTG/sms-tools#36). This solution is already implemented in PebbleCounts.py, and did not work for me. I am uncertain as to why Tk in general seems not to work in my pebblecounts Conda environment -- perhaps backwards incompatibility between Python 3.6 and Tk 8.6? Created as written in the manual, the pebblecounts environment uses Python 3.6.10 and Tk 8.6.10, both Conda’s default packages. These versions seem to be the only viable options, as PebbleCounts requires Python 3.6 for all necessary dependencies to work and Tk 8.5 has serious bugs that affect macOS (https://www.python.org/download/mac/tcltk/).

Solution

While I have not been able to get Tk to work in the pebblecounts environment, I was able to get PebbleCounts.py and PebbleCountsAuto.py running smoothly by making two edits:

  1. In PCfunctions.py, omitting the portion of resizeWin() that uses tkinter:

Original resizeWin()

def resizeWin(img, resize_factor=0.7):
    """
    Get the system screen resolution and resize input image by a factor. Factor
    must be in the range (0, 1].
    """
    from sys import platform as sys_pf
    if 'win' in sys_pf:
        # this import needs to be within the function or else openCV throws errors
        import tkinter as tk
        root = tk.Tk()
        resize_factor = (1 - resize_factor) + 1
        sys_w, sys_h = root.winfo_screenwidth()/resize_factor, root.winfo_screenheight()/resize_factor
        root.destroy()
        root.quit()
        del root
    else:
        resize_factor = (1 - resize_factor) + 1
        sys_w, sys_h = 1920/resize_factor, 1080/resize_factor
    scale_width = sys_w / img.shape[1]
    scale_height = sys_h / img.shape[0]
    dimensions = min(scale_width, scale_height)
    window_width = int(img.shape[1] * dimensions)
    window_height = int(img.shape[0] * dimensions)
    return window_width, window_height

Edited resizeWin()

def resizeWin(img, resize_factor=0.7):
    """
    Get the system screen resolution and resize input image by a factor. Factor
    must be in the range (0, 1].
    """
    resize_factor = (1 - resize_factor) + 1
    sys_w, sys_h = 1920/resize_factor, 1080/resize_factor
    scale_width = sys_w / img.shape[1]
    scale_height = sys_h / img.shape[0]
    dimensions = min(scale_width, scale_height)
    window_width = int(img.shape[1] * dimensions)
    window_height = int(img.shape[0] * dimensions)
    return window_width, window_height
  1. In PebbleCounts.py, omitting the statement shown below that sets the matplotlib backend to TkAgg on Mac:
# use a different backend for matplotlib on MacOS
from sys import platform as sys_pf
if sys_pf == 'darwin':
   import matplotlib
   matplotlib.use('TkAgg')

Without this statement, matplotlib uses the MacOSX backend.

>>> import matplotlib
>>> matplotlib.get_backend()
'MacOSX'
@bpurinton
Copy link
Owner

Thanks a lot of looking into this (I'm sure it took some time...)

I have had very similar issues in the past with compatibility between openCV, tkinter, and matplotlib. Most errors that have occurred for myself and other users have come at the window pop up stage with a "NSException".

Because this has been an ongoing issue (which I have previously changed bits of the code for), I will refrain from modifying and git-pushing a change to the code at this time. I fear that any change may break PebbleCounts on other machines, whereas nice comments like this can serve as a guide for other users to change a few import lines in the base code and try to get it working themselves.

Of course, as always, I'm available on GitHub or by email for trouble shooting.

Thanks again!

@bpurinton bpurinton reopened this Jul 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants