hanzhi713 / image-collage-maker

A photo mosaic (pixel collage) maker. Use all your friends' profile pictures to approximate your profile picture! 如何用 Python 制作一个炫酷的微信好友图
MIT License
150 stars 14 forks source link

def limit_wh(w: int, h: int, max_width: int, max_height: int): #9

Closed Drjacky closed 2 years ago

Drjacky commented 2 years ago
Successfully installed altgraph-0.17.2 lapjv-1.3.1 macholib-1.15.2 opencv-contrib-python-4.5.3.56 pyinstaller-4.6 pyinstaller-hooks-contrib-2021.5 tqdm-4.62.3
➜  image-collage-maker git:(master) python gui.py
  File "gui.py", line 20
    def limit_wh(w: int, h: int, max_width: int, max_height: int):
                  ^
SyntaxError: invalid syntax
hanzhi713 commented 2 years ago

Hey, you need Python v3.6 or newer for this to work.

Drjacky commented 2 years ago

Python 3.9.9

➜  image-collage-maker git:(master) python3 gui.py
Traceback (most recent call last):
  File "image-collage-maker/gui.py", line 14, in <module>
    import cv2
  File "/usr/local/lib/python3.9/site-packages/cv2/__init__.py", line 9, in <module>
    from .cv2 import _registerMatType
ImportError: cannot import name '_registerMatType' from 'cv2.cv2' (/usr/local/lib/python3.9/site-packages/cv2/cv2.cpython-39-darwin.so)
Drjacky commented 2 years ago

I fixed the error by uninstalling the opencv-python, then run !pip install "opencv-python-headless<4.3". Now, it shows this error:

➜  image-collage-maker git:(master) python3 make_img.py --path ImagesAll --recursive --resize_opt stretch --sort rand
[Reading files]: 100%|████████████| 144971/144971 [00:00<00:00, 245103.27file/s]
Read 0 images
Traceback (most recent call last):
  File "image-collage-maker/make_img.py", line 795, in <module>
    main(parser.parse_args())
  File "image-collage-maker/make_img.py", line 740, in main
    grid, sorted_imgs = sort_collage(imgs, args.ratio, args.sort, args.rev_sort)
  File "image-collage-maker/make_img.py", line 248, in sort_collage
    grid = calc_grid_size(ratio[0], ratio[1], num_imgs)
  File "image-collage-maker/make_img.py", line 187, in calc_grid_size
    return min(possible_wh, key=lambda x: ((x[0] / x[1]) - (rw / rh)) ** 2)
ValueError: min() arg is an empty sequence
hanzhi713 commented 2 years ago

It seems that although there are a lot of files in your image path, none of them are readable/decodable. That's why you see

Read 0 images

In what formats are your images stored?

hanzhi713 commented 2 years ago

Python 3.9.9

➜  image-collage-maker git:(master) python3 gui.py
Traceback (most recent call last):
  File "image-collage-maker/gui.py", line 14, in <module>
    import cv2
  File "/usr/local/lib/python3.9/site-packages/cv2/__init__.py", line 9, in <module>
    from .cv2 import _registerMatType
ImportError: cannot import name '_registerMatType' from 'cv2.cv2' (/usr/local/lib/python3.9/site-packages/cv2/cv2.cpython-39-darwin.so)

Does gui.py work now after your fix?

Drjacky commented 2 years ago

No, after I fixed the issue by running this command: !pip install "opencv-python-headless<4.3", I get the error I mentioned above (https://github.com/hanzhi713/image-collage-maker/issues/9#issuecomment-1016284741).

They are all jpg and yes, there are a lot!

hanzhi713 commented 2 years ago

Are you running in a headless environment?

Drjacky commented 2 years ago

No

Drjacky commented 2 years ago

The issue has been solved with the new requirements you put.

➜  image-collage-maker git:(master) pip3 install -r requirements.txt
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Collecting opencv-contrib-python==4.5.5.62
  Downloading opencv_contrib_python-4.5.5.62-cp36-abi3-macosx_10_15_x86_64.whl (54.8 MB)
     |████████████████████████████████| 54.8 MB 842 kB/s
Requirement already satisfied: lapjv==1.3.1 in /usr/local/lib/python3.9/site-packages (from -r requirements.txt (line 2)) (1.3.1)
Collecting pyinstaller==4.8
  Downloading pyinstaller-4.8-py3-none-macosx_10_13_universal2.whl (1.6 MB)
     |████████████████████████████████| 1.6 MB 25.5 MB/s
Requirement already satisfied: tqdm in /usr/local/lib/python3.9/site-packages (from -r requirements.txt (line 4)) (4.62.3)
Requirement already satisfied: numpy>=1.14.5 in /usr/local/lib/python3.9/site-packages (from opencv-contrib-python==4.5.5.62->-r requirements.txt (line 1)) (1.21.4)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (59.0.1)
Requirement already satisfied: pyinstaller-hooks-contrib>=2020.6 in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (2021.5)
Requirement already satisfied: altgraph in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (0.17.2)
Requirement already satisfied: macholib>=1.8 in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (1.15.2)
Installing collected packages: pyinstaller, opencv-contrib-python
  Attempting uninstall: pyinstaller
    Found existing installation: pyinstaller 4.6
    Uninstalling pyinstaller-4.6:
      Successfully uninstalled pyinstaller-4.6
  Attempting uninstall: opencv-contrib-python
    Found existing installation: opencv-contrib-python 4.5.3.56
    Uninstalling opencv-contrib-python-4.5.3.56:
      Successfully uninstalled opencv-contrib-python-4.5.3.56
  DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Successfully installed opencv-contrib-python-4.5.5.62 pyinstaller-4.8
➜  image-collage-maker git:(master) python3 gui.py

Result:

Screen Shot 2022-01-21 at 10 25 20

But the UI is frozen. I cannot interact with the UI!

hanzhi713 commented 2 years ago

Can you try make_img.py now?

hanzhi713 commented 2 years ago

The issue has been solved with the new requirements you put.

➜  image-collage-maker git:(master) pip3 install -r requirements.txt
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Collecting opencv-contrib-python==4.5.5.62
  Downloading opencv_contrib_python-4.5.5.62-cp36-abi3-macosx_10_15_x86_64.whl (54.8 MB)
     |████████████████████████████████| 54.8 MB 842 kB/s
Requirement already satisfied: lapjv==1.3.1 in /usr/local/lib/python3.9/site-packages (from -r requirements.txt (line 2)) (1.3.1)
Collecting pyinstaller==4.8
  Downloading pyinstaller-4.8-py3-none-macosx_10_13_universal2.whl (1.6 MB)
     |████████████████████████████████| 1.6 MB 25.5 MB/s
Requirement already satisfied: tqdm in /usr/local/lib/python3.9/site-packages (from -r requirements.txt (line 4)) (4.62.3)
Requirement already satisfied: numpy>=1.14.5 in /usr/local/lib/python3.9/site-packages (from opencv-contrib-python==4.5.5.62->-r requirements.txt (line 1)) (1.21.4)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (59.0.1)
Requirement already satisfied: pyinstaller-hooks-contrib>=2020.6 in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (2021.5)
Requirement already satisfied: altgraph in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (0.17.2)
Requirement already satisfied: macholib>=1.8 in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (1.15.2)
Installing collected packages: pyinstaller, opencv-contrib-python
  Attempting uninstall: pyinstaller
    Found existing installation: pyinstaller 4.6
    Uninstalling pyinstaller-4.6:
      Successfully uninstalled pyinstaller-4.6
  Attempting uninstall: opencv-contrib-python
    Found existing installation: opencv-contrib-python 4.5.3.56
    Uninstalling opencv-contrib-python-4.5.3.56:
      Successfully uninstalled opencv-contrib-python-4.5.3.56
  DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Successfully installed opencv-contrib-python-4.5.5.62 pyinstaller-4.8
➜  image-collage-maker git:(master) python3 gui.py

Result:

Screen Shot 2022-01-21 at 10 25 20

But the UI is frozen. I cannot interact with the UI!

Not sure why this is the case until I got my hand on a macOS machine

Drjacky commented 2 years ago

Yes, this works now: python3 make_img.py --path /Users/drjacky/ImagesAll --sort rand --size 50 --out /Users/drjacky/outttt.jpg

But, images need to be at the root of the folder and not in subfolders. Is there any way to support subfolders?

hanzhi713 commented 2 years ago

--recursive flag will do. You can print all the available options with -h

Drjacky commented 2 years ago

Thanks! And is there any chance we define the width but not the height? So, it won't become a square; I mean we keep the aspect ratio of each picture.

hanzhi713 commented 2 years ago

It is possible with reasonable effort to support customizable aspect ratios of the tiles. It is just that all of the tiles must have or be resized to the same aspect ratio. This is not supported yet, but I do plan to support it sometime in the future.

If the tiles have different aspect ratios, we need very different algorithms to arrange the tiles.

hanzhi713 commented 2 years ago

The issue has been solved with the new requirements you put.

➜  image-collage-maker git:(master) pip3 install -r requirements.txt
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Collecting opencv-contrib-python==4.5.5.62
  Downloading opencv_contrib_python-4.5.5.62-cp36-abi3-macosx_10_15_x86_64.whl (54.8 MB)
     |████████████████████████████████| 54.8 MB 842 kB/s
Requirement already satisfied: lapjv==1.3.1 in /usr/local/lib/python3.9/site-packages (from -r requirements.txt (line 2)) (1.3.1)
Collecting pyinstaller==4.8
  Downloading pyinstaller-4.8-py3-none-macosx_10_13_universal2.whl (1.6 MB)
     |████████████████████████████████| 1.6 MB 25.5 MB/s
Requirement already satisfied: tqdm in /usr/local/lib/python3.9/site-packages (from -r requirements.txt (line 4)) (4.62.3)
Requirement already satisfied: numpy>=1.14.5 in /usr/local/lib/python3.9/site-packages (from opencv-contrib-python==4.5.5.62->-r requirements.txt (line 1)) (1.21.4)
Requirement already satisfied: setuptools in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (59.0.1)
Requirement already satisfied: pyinstaller-hooks-contrib>=2020.6 in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (2021.5)
Requirement already satisfied: altgraph in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (0.17.2)
Requirement already satisfied: macholib>=1.8 in /usr/local/lib/python3.9/site-packages (from pyinstaller==4.8->-r requirements.txt (line 3)) (1.15.2)
Installing collected packages: pyinstaller, opencv-contrib-python
  Attempting uninstall: pyinstaller
    Found existing installation: pyinstaller 4.6
    Uninstalling pyinstaller-4.6:
      Successfully uninstalled pyinstaller-4.6
  Attempting uninstall: opencv-contrib-python
    Found existing installation: opencv-contrib-python 4.5.3.56
    Uninstalling opencv-contrib-python-4.5.3.56:
      Successfully uninstalled opencv-contrib-python-4.5.3.56
  DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Successfully installed opencv-contrib-python-4.5.5.62 pyinstaller-4.8
➜  image-collage-maker git:(master) python3 gui.py

Result:

Screen Shot 2022-01-21 at 10 25 20

But the UI is frozen. I cannot interact with the UI!

It tested gui.py on macOS Big Sur (version 11.6.1) and it worked fine. What's your mac's version?

Drjacky commented 2 years ago

12.1 (21C52)

hanzhi713 commented 2 years ago

Thanks! And is there any chance we define the width but not the height? So, it won't become a square; I mean we keep the aspect ratio of each picture.

Basic support for non-square tile sizes is implemented in the nonsquare branch. https://github.com/hanzhi713/image-collage-maker/tree/nonsquare. --size option now can take up to 2 arguments.

You can either specify both the width and height of a tile directly like this

--size 80 60

or you can only specify the width. The height will be automatically calculated based on the statistics of the aspect ratios.

--size 80
Drjacky commented 2 years ago

I tried that branch but, it crops the image horizontally.

Just to giving you an idea, this project keeps the aspect ratio: https://github.com/delimitry/collage_maker But, I'm not sure why it loses the quality of each tile.

hanzhi713 commented 2 years ago

If you want to keep the aspect ratio of individual tiles, unfortunately, this is out of the scope of this project. This project is a photomosaic maker (albeit having simple collage-making functionality) which requires all tiles to have the same aspect ratio.

To be honest, I should've named the repository as "photomosaic maker".

dw61 commented 2 years ago

On my computer with the same OS version (12.1), running brew install python-tk@3.9 resolved the tkinter problem, and I can run gui.py smoothly with python 3.9.

Drjacky commented 2 years ago

@dw61 Thanks! that solved the black screen issue but, the software crashed after I clicked on load source images button for the first time but, the next time, it didn't crash:

➜  image-collage-maker git:(master) python3 gui.py
2022-04-08 21:52:00.493 Python[26916:409214] -[NSSavePanel runModal] caught non-fatal NSGenericException '-[NSApplication runModalForWindow:] may not be invoked inside of transaction begin/commit pair, or inside of transaction commit (usually this means it was invoked inside of a view's -drawRect: method.)' with backtrace (
    0   CoreFoundation                      0x00007ff80b3bc1e3 __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007ff80b11cc13 objc_exception_throw + 48
    2   CoreFoundation                      0x00007ff80b3bc04a +[NSException exceptionWithName:reason:userInfo:] + 0
    3   AppKit                              0x00007ff80e5e7dca _NSRunModal + 152
    4   AppKit                              0x00007ff80e014e76 -[NSApplication runModalForWindow:] + 241
    5   AppKit                              0x00007ff80e773b4e -[NSSavePanel runModal] + 519
    6   libtk8.6.dylib                      0x000000010744bfd4 showOpenSavePanel + 98
    7   libtk8.6.dylib                      0x000000010744cf96 Tk_ChooseDirectoryObjCmd + 1018
    8   libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    9   _tkinter.cpython-39-darwin.so       0x0000000106ea0f20 Tkapp_Call + 480
    10  Python                              0x0000000106aabf04 cfunction_call + 90
    11  Python                              0x0000000106a60e1a _PyObject_Call + 121
    12  Python                              0x0000000106b4a295 _PyEval_EvalFrameDefault + 3304
    13  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    14  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    15  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    16  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    17  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    18  Python                              0x0000000106b4e9bc _PyEval_EvalFrameDefault + 21519
    19  Python                              0x0000000106a60fc0 _PyFunction_Vectorcall + 192
    20  Python                              0x0000000106b4a295 _PyEval_EvalFrameDefault + 3304
    21  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    22  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    23  Python                              0x0000000106a63c94 method_vectorcall + 481
    24  _tkinter.cpython-39-darwin.so       0x0000000106ea537e PythonCmd + 206
    25  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    26  libtk8.6.dylib                      0x000000010743f808 Ttk_InvokeEnsemble + 212
    27  libtk8.6.dylib                      0x0000000107446287 WidgetInstanceObjCmd + 75
    28  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    29  libtk8.6.dylib                      0x0000000107446b3c TtkWidgetInstateCommand + 197
    30  libtk8.6.dylib                      0x000000010743f808 Ttk_InvokeEnsemble + 212
    31  libtk8.6.dylib                      0x0000000107446287 WidgetInstanceObjCmd + 75
    32  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    33  libtk8.6.dylib                      0x0000000107446b3c TtkWidgetInstateCommand + 197
    34  libtk8.6.dylib                      0x000000010743f808 Ttk_InvokeEnsemble + 212
    35  libtk8.6.dylib                      0x0000000107446287 WidgetInstanceObjCmd + 75
    36  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    37  libtcl8.6.dylib                     0x00000001070efe61 TclEvalEx + 1849
    38  libtcl8.6.dylib                     0x00000001070ef722 Tcl_EvalEx + 26
    39  libtk8.6.dylib                      0x00000001073a07c3 Tk_BindEvent + 5611
    40  libtk8.6.dylib                      0x00000001073a656d TkBindEventProc + 335
    41  libtk8.6.dylib                      0x00000001073adb90 Tk_HandleEvent + 839
    42  libtk8.6.dylib                      0x00000001073ae0db WindowEventProc + 100
    43  libtcl8.6.dylib                     0x0000000107196ff2 Tcl_ServiceEvent + 139
    44  libtcl8.6.dylib                     0x0000000107197283 Tcl_DoOneEvent + 320
    45  libtk8.6.dylib                      0x00000001073a714b Tk_UpdateObjCmd + 132
    46  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    47  _tkinter.cpython-39-darwin.so       0x0000000106ea0f20 Tkapp_Call + 480
    48  Python                              0x0000000106a6ce5e method_vectorcall_VARARGS + 112
    49  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    50  Python                              0x0000000106a60fc0 _PyFunction_Vectorcall + 192
    51  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    52  Python                              0x0000000106a60fc0 _PyFunction_Vectorcall + 192
    53  Python                              0x0000000106b4a295 _PyEval_EvalFrameDefault + 3304
    54  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    55  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    56  Python                              0x0000000106a63c20 method_vectorcall + 365
    57  _tkinter.cpython-39-darwin.so       0x0000000106ea537e PythonCmd + 206
    58  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    59  libtcl8.6.dylib                     0x00000001070efe61 TclEvalEx + 1849
    60  libtcl8.6.dylib                     0x00000001070ef722 Tcl_EvalEx + 26
    61  libtk8.6.dylib                      0x00000001073a07c3 Tk_BindEvent + 5611
    62  libtk8.6.dylib                      0x00000001073a656d TkBindEventProc + 335
    63  libtk8.6.dylib                      0x00000001073adb90 Tk_HandleEvent + 839
    64  libtk8.6.dylib                      0x0000000107461516 TkGenWMConfigureEvent + 246
    65  libtk8.6.dylib                      0x0000000107461411 -[TKApplication(TKWindowEvent) windowBoundsChanged:] + 345
    66  CoreFoundation                      0x00007ff80b33603c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    67  CoreFoundation                      0x00007ff80b3d3592 ___CFXRegistrationPost_block_invoke + 49
    68  CoreFoundation                      0x00007ff80b3d3510 _CFXRegistrationPost + 496
    69  CoreFoundation                      0x00007ff80b307ca8 _CFXNotificationPost + 735
    70  Foundation                          0x00007ff80c13c90e -[NSNotificationCenter postNotificationName:object:userInfo:] + 82
    71  AppKit                              0x00007ff80ddb5b75 -[NSWindow _setFrameCommon:display:fromServer:] + 1781
    72  AppKit                              0x00007ff80e5ed873 -[NSWindow _windowMovedToRect:dueToMoveEvent:] + 133
    73  AppKit                              0x00007ff80ded8b91 -[NSWindow _windowMoved:] + 1019
    74  AppKit                              0x00007ff80ded8776 -[NSWindow _internalHandleAppKitDefinedEvent:] + 239
    75  AppKit                              0x00007ff80ded77b3 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 3771
    76  AppKit                              0x00007ff80ded66de -[NSWindow(NSEventRouting) sendEvent:] + 352
    77  AppKit                              0x00007ff80ded54cc -[NSApplication(NSEvent) sendEvent:] + 2936
    78  libtk8.6.dylib                      0x000000010745d8d9 -[TKApplication(TKNotify) sendEvent:] + 124
    79  libtk8.6.dylib                      0x000000010745e13d TkMacOSXEventsCheckProc + 397
    80  libtcl8.6.dylib                     0x0000000107197275 Tcl_DoOneEvent + 306
    81  _tkinter.cpython-39-darwin.so       0x0000000106ea3077 _tkinter_tkapp_mainloop + 343
    82  Python                              0x0000000106a6cb86 method_vectorcall_FASTCALL + 95
    83  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    84  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    85  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    86  Python                              0x0000000106a63b53 method_vectorcall + 160
    87  Python                              0x0000000106b4feff _PyEval_EvalFrameDefault + 26962
    88  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    89  Python                              0x0000000106ba31de run_eval_code_obj + 128
    90  Python                              0x0000000106ba3136 run_mod + 96
    91  Python                              0x0000000106ba08f4 pyrun_file + 167
    92  Python                              0x0000000106ba02e4 pyrun_simple_file + 271
    93  Python                              0x0000000106ba01af PyRun_SimpleFileExFlags + 67
    94  Python                              0x0000000106bbfbfb pymain_run_file + 326
    95  Python                              0x0000000106bbf469 Py_RunMain + 993
    96  Python                              0x0000000106bc07c4 Py_BytesMain + 42
    97  dyld                                0x000000010997651e start + 462
)
2022-04-08 21:52:00.802 Python[26916:409214] *** Terminating app due to uncaught exception 'NSGenericException', reason: '-[NSAlert runModal] may not be invoked inside of transaction begin/commit pair, or inside of transaction commit (usually this means it was invoked inside of a view's -drawRect: method.)'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007ff80b3bc1e3 __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007ff80b11cc13 objc_exception_throw + 48
    2   CoreFoundation                      0x00007ff80b3bc04a +[NSException exceptionWithName:reason:userInfo:] + 0
    3   AppKit                              0x00007ff80e5e7dca _NSRunModal + 152
    4   AppKit                              0x00007ff80e09f8aa -[NSAlert runModal] + 225
    5   AppKit                              0x00007ff80e775074 -[NSSavePanel _startServiceFailedAlert] + 190
    6   AppKit                              0x00007ff80e773c66 -[NSSavePanel runModal] + 799
    7   libtk8.6.dylib                      0x000000010744bfd4 showOpenSavePanel + 98
    8   libtk8.6.dylib                      0x000000010744cf96 Tk_ChooseDirectoryObjCmd + 1018
    9   libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    10  _tkinter.cpython-39-darwin.so       0x0000000106ea0f20 Tkapp_Call + 480
    11  Python                              0x0000000106aabf04 cfunction_call + 90
    12  Python                              0x0000000106a60e1a _PyObject_Call + 121
    13  Python                              0x0000000106b4a295 _PyEval_EvalFrameDefault + 3304
    14  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    15  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    16  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    17  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    18  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    19  Python                              0x0000000106b4e9bc _PyEval_EvalFrameDefault + 21519
    20  Python                              0x0000000106a60fc0 _PyFunction_Vectorcall + 192
    21  Python                              0x0000000106b4a295 _PyEval_EvalFrameDefault + 3304
    22  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    23  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    24  Python                              0x0000000106a63c94 method_vectorcall + 481
    25  _tkinter.cpython-39-darwin.so       0x0000000106ea537e PythonCmd + 206
    26  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    27  libtk8.6.dylib                      0x000000010743f808 Ttk_InvokeEnsemble + 212
    28  libtk8.6.dylib                      0x0000000107446287 WidgetInstanceObjCmd + 75
    29  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    30  libtk8.6.dylib                      0x0000000107446b3c TtkWidgetInstateCommand + 197
    31  libtk8.6.dylib                      0x000000010743f808 Ttk_InvokeEnsemble + 212
    32  libtk8.6.dylib                      0x0000000107446287 WidgetInstanceObjCmd + 75
    33  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    34  libtk8.6.dylib                      0x0000000107446b3c TtkWidgetInstateCommand + 197
    35  libtk8.6.dylib                      0x000000010743f808 Ttk_InvokeEnsemble + 212
    36  libtk8.6.dylib                      0x0000000107446287 WidgetInstanceObjCmd + 75
    37  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    38  libtcl8.6.dylib                     0x00000001070efe61 TclEvalEx + 1849
    39  libtcl8.6.dylib                     0x00000001070ef722 Tcl_EvalEx + 26
    40  libtk8.6.dylib                      0x00000001073a07c3 Tk_BindEvent + 5611
    41  libtk8.6.dylib                      0x00000001073a656d TkBindEventProc + 335
    42  libtk8.6.dylib                      0x00000001073adb90 Tk_HandleEvent + 839
    43  libtk8.6.dylib                      0x00000001073ae0db WindowEventProc + 100
    44  libtcl8.6.dylib                     0x0000000107196ff2 Tcl_ServiceEvent + 139
    45  libtcl8.6.dylib                     0x0000000107197283 Tcl_DoOneEvent + 320
    46  libtk8.6.dylib                      0x00000001073a714b Tk_UpdateObjCmd + 132
    47  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    48  _tkinter.cpython-39-darwin.so       0x0000000106ea0f20 Tkapp_Call + 480
    49  Python                              0x0000000106a6ce5e method_vectorcall_VARARGS + 112
    50  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    51  Python                              0x0000000106a60fc0 _PyFunction_Vectorcall + 192
    52  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    53  Python                              0x0000000106a60fc0 _PyFunction_Vectorcall + 192
    54  Python                              0x0000000106b4a295 _PyEval_EvalFrameDefault + 3304
    55  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    56  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    57  Python                              0x0000000106a63c20 method_vectorcall + 365
    58  _tkinter.cpython-39-darwin.so       0x0000000106ea537e PythonCmd + 206
    59  libtcl8.6.dylib                     0x00000001070eed15 TclNRRunCallbacks + 79
    60  libtcl8.6.dylib                     0x00000001070efe61 TclEvalEx + 1849
    61  libtcl8.6.dylib                     0x00000001070ef722 Tcl_EvalEx + 26
    62  libtk8.6.dylib                      0x00000001073a07c3 Tk_BindEvent + 5611
    63  libtk8.6.dylib                      0x00000001073a656d TkBindEventProc + 335
    64  libtk8.6.dylib                      0x00000001073adb90 Tk_HandleEvent + 839
    65  libtk8.6.dylib                      0x0000000107461516 TkGenWMConfigureEvent + 246
    66  libtk8.6.dylib                      0x0000000107461411 -[TKApplication(TKWindowEvent) windowBoundsChanged:] + 345
    67  CoreFoundation                      0x00007ff80b33603c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    68  CoreFoundation                      0x00007ff80b3d3592 ___CFXRegistrationPost_block_invoke + 49
    69  CoreFoundation                      0x00007ff80b3d3510 _CFXRegistrationPost + 496
    70  CoreFoundation                      0x00007ff80b307ca8 _CFXNotificationPost + 735
    71  Foundation                          0x00007ff80c13c90e -[NSNotificationCenter postNotificationName:object:userInfo:] + 82
    72  AppKit                              0x00007ff80ddb5b75 -[NSWindow _setFrameCommon:display:fromServer:] + 1781
    73  AppKit                              0x00007ff80e5ed873 -[NSWindow _windowMovedToRect:dueToMoveEvent:] + 133
    74  AppKit                              0x00007ff80ded8b91 -[NSWindow _windowMoved:] + 1019
    75  AppKit                              0x00007ff80ded8776 -[NSWindow _internalHandleAppKitDefinedEvent:] + 239
    76  AppKit                              0x00007ff80ded77b3 -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] + 3771
    77  AppKit                              0x00007ff80ded66de -[NSWindow(NSEventRouting) sendEvent:] + 352
    78  AppKit                              0x00007ff80ded54cc -[NSApplication(NSEvent) sendEvent:] + 2936
    79  libtk8.6.dylib                      0x000000010745d8d9 -[TKApplication(TKNotify) sendEvent:] + 124
    80  libtk8.6.dylib                      0x000000010745e13d TkMacOSXEventsCheckProc + 397
    81  libtcl8.6.dylib                     0x0000000107197275 Tcl_DoOneEvent + 306
    82  _tkinter.cpython-39-darwin.so       0x0000000106ea3077 _tkinter_tkapp_mainloop + 343
    83  Python                              0x0000000106a6cb86 method_vectorcall_FASTCALL + 95
    84  Python                              0x0000000106b4eca4 _PyEval_EvalFrameDefault + 22263
    85  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    86  Python                              0x0000000106a61078 _PyFunction_Vectorcall + 376
    87  Python                              0x0000000106a63b53 method_vectorcall + 160
    88  Python                              0x0000000106b4feff _PyEval_EvalFrameDefault + 26962
    89  Python                              0x0000000106b4842c _PyEval_EvalCode + 398
    90  Python                              0x0000000106ba31de run_eval_code_obj + 128
    91  Python                              0x0000000106ba3136 run_mod + 96
    92  Python                              0x0000000106ba08f4 pyrun_file + 167
    93  Python                              0x0000000106ba02e4 pyrun_simple_file + 271
    94  Python                              0x0000000106ba01af PyRun_SimpleFileExFlags + 67
    95  Python                              0x0000000106bbfbfb pymain_run_file + 326
    96  Python                              0x0000000106bbf469 Py_RunMain + 993
    97  Python                              0x0000000106bc07c4 Py_BytesMain + 42
    98  dyld                                0x000000010997651e start + 462
)
libc++abi: terminating with uncaught exception of type NSException
[1]    26916 abort      python3 gui.py