TypeError: 需要2个参数(给定1个) asksaveasnamefile

0 投票
1 回答
1546 浏览
提问于 2025-04-18 03:40

我正在尝试为一个跳棋游戏制作保存和加载功能。这个保存和加载的功能已经有了,我只需要制作按钮并让它在tkinter界面中工作。

这里是给出的两个函数:

def sauvegarder(self, nom_fichier):

    try:
        with open(nom_fichier, "w") as f:
            f.write("{}\n".format(self.couleur_joueur_courant))
            f.write("{}\n".format(self.doit_prendre))
            if self.position_source_forcee is not None:
                f.write("{},{}\n".format(self.position_source_forcee[0],self.position_source_forcee[1]))

            else:
                f.write("None\n")
            f.writelines(self.damier.convertir_en_chaine())
    except:
        raise ProblemeSauvegarde("Problème lors de la sauvegarde.")

def charger(self, nom_fichier):

    try:
        with open(nom_fichier) as f:
            self.couleur_joueur_courant = f.readline().rstrip("\n")
            doit_prendre_string = f.readline().rstrip("\n")
            if doit_prendre_string == "True":
                self.doit_prendre = True
            else:
                self.doit_prendre = False

            position_string = f.readline().rstrip("\n")
            if position_string == "None":
                self.position_source_forcee = None
            else:
                ligne_string, colonne_string = position_string.split(",")
                self.position_source_forcee = (int(ligne_string), int(colonne_string))

            self.damier.charger_dune_chaine(f.read())
    except:
        raise ProblemeChargement("Problème lors du chargement.")

在我正在工作的界面文件中,这里是我写的两个函数:

import tkinter as tk
from tkinter.filedialog import askopenfilename, asksaveasfilename
from dames.partie import Partie
from dames.exceptions import PositionSourceInvalide, PositionCibleInvalide

class InterfaceDamier(tk.Frame):

def __init__(self, parent, taille_case, damier):
    """taille_case est la taille d'un côté d'une case en pixels."""
    # Definition du damier : # de cases
    self.n_lignes = 8
    self.n_colonnes = 8

    # Definition du damier : taille des cases (en pixels)
    self.taille_case = taille_case

    # Defiz«nition du damier : couleur de cases
    self.couleur1 = "white"
    self.couleur2 = "gray"

    # Pièces sur le damier, on utilise le damier de la classe damier
    self.damier = damier

    # Calcul de la taille du dessin
    canvas_width = self.n_colonnes * self.taille_case
    canvas_height = self.n_lignes * self.taille_case


    # Initialisation de la fenêtre parent contenant le canvas
    tk.Frame.__init__(self, parent)

    # Initialisation du canvas
    self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0, width=canvas_width, height=canvas_height,
                           background="white")

    # On place le canvas et le plateau (self) à l'aide de "grid".
    self.canvas.grid(padx=2, pady=2, sticky=tk.N + tk.S + tk.E + tk.W)
    self.grid(padx=4, pady=4, sticky=tk.N + tk.S + tk.E + tk.W)

    # Fait en sorte que le redimensionnement de la fenêtre redimensionne le damier
    self.canvas.bind("<Configure>", self.actualiser)


    ##test sam
    self.piecesJoue ={}
    self.frame2 = ""


def charger_fichier(self):
    #fonction pour charger une partie déjà jouée à partir d'un fichier texte
    nom_fichier = tk.filedialog.askopenfilename(filetypes = [("Fichiers Texte","*.txt")]) 
    if len(nom_fichier) > 0:
        self.partie = Partie(nom_fichier)

        self.pieces = {}

        for position, piece in self.game.interfaceDames.InterfaceDamier.items():
            nom = self.obtenir_nom_piece_selon_caractere(str(piece))
            self.addpiece(nom, position[0], position[1], "blanc")

        self.frame2.destroy()
        self.frameMenu.destroy()
        self.piecesJoue.clear()
        self.__init__(self, parent)
        self.canvas.bind("<Configure>", self.actualiser)

def sauvegarder_fichier(self):
    "fonction pour enregistrer une partie  de jeu dans un fichier texte "

    mesformats = [("Fichiers Texte","*.txt")]
    root = Tkinter.Tk()

    nom_fichier = tk.FileDialog.asksaveasfilename(parent=root,filetypes =    [mesformats],title="Sauvegarder la partie sous...") 

    if len(nom_fichier) > 0:
        self.Partie.sauvegarder(nom_fichier)

按钮似乎可以正常工作,但在这两个函数中总是出现同样的错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python32\lib\tkinter\__init__.py", line 1399, in __call__
return self.func(*args)
TypeError: charger() takes exactly 2 arguments (1 given)

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python32\lib\tkinter\__init__.py", line 1399, in __call__
return self.func(*args)
TypeError: sauvegarder() takes exactly 2 arguments (1 given)

我觉得可能是init里缺少什么,但我找不到。(很多函数名和指令是用法语写的,抱歉)

1 个回答

2

如果你能把完整的源代码给我就好了(可以放在pastebin或者其他地方),但是,听起来你遇到的问题是这样的:

myButton = tk.Button(text='A Button!', command=charger)

这个方法是行不通的,因为按钮的回调方式有点问题。根据我所了解,Tkinter不能通过这种方式发送任何参数。Tkinter里有很多不同的回调格式。如果你像这样绑定一个事件:

<<Modified>>

给一个命令,Tkinter会期待一个只带一个参数的函数,这个参数就是Tkinter捕获到的事件。而按钮本身不需要任何参数。为了让这个工作,你可能需要用到lambda、partial(来自functools模块)或者函数包装器。如果我在一个类里有一个按钮需要打开(请原谅我,我不会法语),我可能会这样做:

myButton = tk.Button(text='A Better Button!', command = lambda: charger(self.someFileName))

根据你的实现方式,partial可能效果更好,或者谁知道呢。但如果我理解得没错,你需要像这样来使用你现在的保存/打开功能。

希望这能帮到你,如果没有,或许可以再发一些源代码,我们一起找出问题所在。

撰写回答