首页 > 解决方案 > 类型错误:on_quit() 缺少 1 个必需的位置参数:'self'

问题描述

我在尝试使用 tkinter 的主循环进行多线程时遇到了这个问题。如果我不尝试多线程,一切正常,但如果我这样做,它会给我一个错误。

我正在实现这个类来获取和设置某个游戏中的角色坐标,这部分工作,但是应用程序不会让我退出。我尝试将 self.root.protocol 的第二个参数设置为 self.on_quit() 和 self.on_quit(self),但它只是立即执行它。

class PositionGUI:

    EXIT_FLAG = False

    def __init__(self, process: DSProcess):

        self.root = Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.on_quit)
        ...
        Thread(target=self.update, args=(self, process)).start()
        self.root.mainloop()

    def update(self, process: DSProcess):
        while not self.EXIT_FLAG:
            ...

    def on_quit(self):
        self.EXIT_FLAG = True
        self.root.destroy()


class DarkShell(DSProcess):

    def __init__(self):
        super(DarkShell, self).__init__()
        ...
        Thread(target=PositionGUI.__init__, args=(PositionGUI, self)).start()

On-quit 方法应该为更新函数设置一个标志以完成并关闭应用程序的这一部分,但它却给了我这个错误:“TypeError: on_quit() missing 1 required positional argument: 'self'”

标签: pythontkinter

解决方案


  1. 如果你真的需要线程,Tkinter 需要在主线程中(通常你没有解决大多数问题的方法)

  2. EXIT_FLAG = False的未定义为类属性,因此调用self.EXIT_FLAG将不起作用。

  3. 而不是from tkinter import *使用import tkinter as tk这将防止任何重叠导入导致错误。

因此,如果没有我可以实际测试的东西,我只能猜测您的真正问题,但请以这个例子为例,让我知道它是否有帮助。

import tkinter as tk
from threading import Thread


class PositionGUI(tk.Tk):

    def __init__(self, process: DSProcess):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.on_quit)
        self.EXIT_FLAG = False
        ...
        Thread(target=self.update, args=(self, process)).start()
        self.mainloop()

    def update(self, process: DSProcess):
        while not self.EXIT_FLAG:
            pass

    def on_quit(self):
        self.EXIT_FLAG = True # note that this line does nothing useful 
        self.root.destroy()

推荐阅读