You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Pygame应用中触发Tkinter配置窗口时出现NSInvalidArgumentException错误的求助

在Pygame应用中触发Tkinter配置窗口时出现NSInvalidArgumentException错误的求助

我现在遇到一个头疼的问题——在MacOS Ventura(13.0.1)上,当我点击Pygame应用里的配置按钮,调用config()函数打开Tkinter窗口时,程序直接崩溃,抛出了NSInvalidArgumentException错误。如果我把Tkinter窗口的初始化放在函数外面,它能正常打开,但我只想在用户点击配置按钮的时候才弹出这个窗口,这就很矛盾了。

错误日志

pygame 2.1.2 (SDL 2.0.18, Python 3.8.5)
Hello from the pygame community. https://www.pygame.org/contribute.html

2022-12-10 14:00:50.109 python[94676:3249298] -[SDLApplication macMinorVersion]: unrecognized selector sent to instance 0x7fd205b71790

2022-12-10 14:00:50.113 python[94676:3249298] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SDLApplication macMinorVersion]: unrecognized selector sent to instance 0x7fd205b71790'

*** First throw call stack:

(
0   CoreFoundation                      0x00007ff80481843b __exceptionPreprocess + 242
1   libobjc.A.dylib                     0x00007ff804367e25 objc_exception_throw + 48
2   CoreFoundation                      0x00007ff8048af56b -[NSObject(NSObject) __retain_OA] + 0
3   CoreFoundation                      0x00007ff80478269b ___forwarding___ + 1324
4   CoreFoundation                      0x00007ff8047820d8 _CF_forwarding_prep_0 + 120
5   libtk8.6.dylib                      0x0000000109b64db9 SetCGColorComponents + 265
6   libtk8.6.dylib                      0x0000000109b6567a TkpGetColor + 250
7   libtk8.6.dylib                      0x0000000109a9faa9 Tk_GetColor + 153
8   libtk8.6.dylib                      0x0000000109a8f8e6 Tk_Get3DBorder + 134
9   libtk8.6.dylib                      0x0000000109a8f74f Tk_Alloc3DBorderFromObj + 127
10  libtk8.6.dylib                      0x0000000109aa0fad DoObjConfig + 941
11  libtk8.6.dylib                      0x0000000109aa0ae5 Tk_InitOptions + 357
12  libtk8.6.dylib                      0x0000000109aa09c5 Tk_InitOptions + 69
13  libtk8.6.dylib                      0x0000000109ad1b5c CreateFrame + 1548
14  libtk8.6.dylib                      0x0000000109ad1e37 TkListCreateFrame + 151
15  libtk8.6.dylib                      0x0000000109ac97f8 Initialize + 2168
16  _tkinter.cpython-38-darwin.so       0x000000010829f68b Tcl_AppInit + 91
17  _tkinter.cpython-38-darwin.so       0x000000010829f34e Tkapp_New + 590
18  _tkinter.cpython-38-darwin.so       0x000000010829f0ee _tkinter_create_impl + 222
19  _tkinter.cpython-38-darwin.so       0x000000010829ebd6 _tkinter_create + 182
20  python3.8                           0x00000001070a5644 cfunction_vectorcall_FASTCALL + 84
21  python3.8                           0x000000010717ef20 _PyEval_EvalFrameDefault + 45072
22  python3.8                           0x000000010717212d _PyEval_EvalCodeWithName + 557
23  python3.8                           0x000000010704919a _PyFunction_Vectorcall + 426
24  python3.8                           0x00000001070477dd _PyObject_FastCallDict + 93
25  python3.8                           0x00000001070cdf52 slot_tp_init + 178
26  python3.8                           0x00000001070dd4c1 type_call + 289
27  python3.8                           0x0000000107047ad7 _PyObject_MakeTpCall + 167
28  python3.8                           0x000000010717f086 _PyEval_EvalFrameDefault + 45430
29  python3.8                           0x00000001070490e8 _PyFunction_Vectorcall + 248
30  python3.8                           0x000000010717f2b0 _PyEval_EvalFrameDefault + 45984
31  python3.8                           0x000000010717212d _PyEval_EvalCodeWithName + 557
32  python3.8                           0x00000001071ea346 PyRun_FileExFlags + 358
33  python3.8                           0x00000001071e9a91 PyRun_SimpleFileExFlags + 529
34  python3.8                           0x00000001072122df pymain_run_file + 383
35  python3.8                           0x00000001072119ab pymain_run_python + 523
36  python3.8                           0x0000000107211745 Py_RunMain + 37
37  python3.8                           0x0000000107212e11 pymain_main + 49
38  python3.8                           0x000000010701b768 main + 56
39  dyld                                0x00007ff804394310 start + 2432
)

libc++abi: terminating with uncaught exception of type NSException
zsh: abort      /Users/amanbasra/opt/anaconda3/bin/python

我的代码片段

import pygame as py
import tkinter as tk
import serial.tools.list_ports

# Pygame initialisation
py.init()

width = 500
height = 500
py.display.set_caption('MEP')
screen = py.display.set_mode((width, height))

buttonColour = (133, 133, 133)
black = (51, 51, 51)
white = (202, 202, 202)
screen.fill(black)

clock = py.time.Clock()
py.display.flip()

gridstate = {}
sysfont = py.font.get_default_font()
font = py.font.SysFont(None, 20)

# Draw Grid
resx = 10
resy = 10
buttonSize = 25
grid = []
startFallProcess = False
lineGroup = py.sprite.Group()
gridHeight = resy*buttonSize
gridWidth = resx*buttonSize
delayInterval = 15
restoreList = []

ports = serial.tools.list_ports.comports()
portList = []

def restore():
    for x in restoreList:
        x.active()

def repeat():
    start = True
    restore()

def config():
    window = tk.Tk()
    window.geometry(100, 100)
    optionVariable = tk.StringVar(window)
    tk.Label(window, text='Choose serial port')
    for x in sorted(ports):
        portList.append(x)
    tk.OptionMenu(window, optionVariable, portList)

class gridLine:
    def __init__(self, start, end):
        self.start = start
        self.end = end
        py.draw.line(screen, white, start, end)

class Line(py.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.x = x
        self.y = y
        self.image = py.Surface([5, 10])
        self.image.fill(white)
        self.rect = self.image.get_rect()

    def update(self):
        self.rect.x = self.x
        self.rect.y += 2.27*10
        if self.rect.y > height + 50:
            self.kill()

class Button:
    def __init__(self, x, y, w, h, getCo=None, text=None, action=False):
        self.textval = text
        self.presstime = 0
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.text = font.render(self.textval, True, white)
        self.getCo = getCo
        self.colour = buttonColour
        self.clicked = False
        self.box = py.draw.rect(screen, self.colour, (x, y, w, h), 1)
        self.action = action

    def draw(self):
        pos = py.mouse.get_pos()
        if self.box.collidepoint(pos):
            if py.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                if self.action == False:
                    self.action = True
                    self.colour = (255, 0, 0)
                elif self.action == True:
                    self.action = False
                    self.colour = buttonColour
        if py.mouse.get_pressed()[0] == 0:
            self.clicked = False
        self.box = py.draw.rect(screen, self.colour,
                                (self.x, self.y, self.w, self.h), 3)
        gridstate.update({self.getCo: self.action})
        self.textrect = self.text.get_rect(center=(self.box.center))
        screen.blit(self.text, self.textrect)
        return self.action

    def oneTimeClick(self):
        pos = py.mouse.get_pos()
        if self.box.collidepoint(pos):
            if py.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                self.action = True
                self.presstime = py.time.get_ticks()
                self.colour = (255, 0, 0)
        if py.mouse.get_pressed()[0] == 0:
            self.clicked = False
            self.action = False
            self.colour = buttonColour
        self.box = py.draw.rect(screen, self.colour,
                                (self.x, self.y, self.w, self.h))
        self.textrect = self.text.get_rect(center=(self.box.center))
        screen.blit(self.text, self.textrect)
        return self.action

    def clear(self):
        self.colour = buttonColour
        self.action = False
        gridstate.update({self.getCo: self.action})
        self.box = py.draw.rect(screen, self.colour,
                                (self.x, self.y, self.w, self.h))

    def active(self):
        self.colour = (255, 0, 0)
        self.action = True
        gridstate.update({self.getCo: self.action})
        self.box = py.draw.rect(screen, self.colour,
                                (self.x, self.y, self.w, self.h))

# Create Action Buttons
startButton = Button(0, 475, 50, 25, None, 'Start')
clearButton = Button(75, 475, 50, 25, None, 'Clear')
restoreButton = Button(150, 475, 50, 25, None, 'Restore')
repeatButton = Button(225, 475, 50, 25, None, 'Repeat')
configButton = Button(450, 475, 50, 25, None, 'Conf')

for x in range(resx):
    for y in range(resy):
        grid.append(Button((x*buttonSize), (y*buttonSize),
                          buttonSize, buttonSize, (x, y)))

running = True
while running:
    clock.tick(50)
    for event in py.event.get():
        if event.type == py.QUIT:
            running = False

    screen.fill(black)
    gridLine((275, 0), (275, height))

    clear = clearButton.oneTimeClick()
    start = startButton.oneTimeClick()
    restoreState = restoreButton.oneTimeClick()
    repeatState = repeatButton.draw()
    configState = configButton.oneTimeClick()

    if startFallProcess:
        for index, (buttonreset, (key, value)) in enumerate(zip(reversed(grid), reversed(gridstate.items()))):
            if value == True:
                restoreList.append(buttonreset)
                delaytime = (delayInterval *
                            abs(key[1]-10)) + startButton.presstime
                currenttime = py.time.get_ticks()
                if currenttime > delaytime:
                    lineGroup.add(Line((key[0]*10)+300, 0))
                    buttonreset.clear()
        if all(value == False for value in gridstate.values()):
            startFallProcess = False

    if clear == True:
        restoreList.clear()
        for x in grid:
            x.clear()

    if start == True:
        startFallProcess = True

    if repeatState:
        repeat()

    if restoreState:
        restore()

    if configState:
        config()

    for row in grid:
        row.draw()

    lineGroup.draw(screen)
    lineGroup.update()

    py.display.flip()

环境信息

  • 操作系统:MacOS 13.0.1 (Ventura)
  • Python版本:3.8.5
  • Pygame版本:2.1.2 (SDL 2.0.18)
  • Tkinter版本:随Python 3.8.5自带的tk8.6

我查了一些相关帖子,但大多是其他语言的类似错误,和我的场景完全不搭边,也找不到有效的解决方案。现在完全不知道从哪里入手排查问题,有没有大佬能指点一下?

备注:内容来源于stack exchange,提问作者Aman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 07:15:28