Python ctypes 中的消息框发生错误 PyEval_RestoreThread

MessageboxW in Python ctypes An error ocurred PyEval_RestoreThread

我在 Python 中使用以下方法创建了一个消息框:

import tkinter
import ctypes

class app:

    def __init__(self):
        self._root= tkinter.Tk()
        self._root.grid()
        self.menubar = tkinter.Menu(self._root)
        self.filemenu  = tkinter.Menu(self.menubar) 
        self.filemenu.add_command(label="Salva", command=self._save)
        self.filemenu.add_command(label="prova", command=self._save)
        self.menubar.add_cascade(label="File", menu=self.filemenu) 
        self._root.config(menu=self.menubar)

    def _save(self):
        MBW=ctypes.windll.user32.MessageBoxW(0, "Salvare le modifiche?", "Salva", 3)

    def mostra(self):
        self._root.mainloop()
a=app()
a.mostra()

通过单击 File, Salva 打开对话框,然后在对话框打开时选择 File, prova 来重现错误:

C:\>python test.py
Fatal Python error: PyEval_RestoreThread: NULL tstate

Current thread 0x00001f70 (most recent call first):
  File "C:\test.py", line 16 in _save
  File "C:\Python37\lib\tkinter\__init__.py", line 1705 in __call__
  File "C:\Python37\lib\tkinter\__init__.py", line 1283 in mainloop
  File "C:\test.py", line 19 in mostra
  File "C:\test.py", line 21 in <module>

如何修复错误?

要防止在对话框打开时访问其他菜单命令,请将句柄传递给活动 window MessageBoxW,这会阻止与主 window 的进一步交互,直到对话框打开已解决:

def _save(self):
    hwnd = ctypes.windll.user32.GetActiveWindow()
    MBW = ctypes.windll.user32.MessageBoxW(hwnd, "Salvare le modifiche?", "Salva", 3)

或者,使用内部做同样事情的 tkinter messageboxes 之一:

from tkinter import messagebox

def _save(self):
    answer = messagebox.askyesnocancel("Salvare le modifiche?", "Salva")