2017-06-01 51 views
0

我是tkinter的新手,我想创建一个带有“条目”,带图片的画布和按钮的tkinter接口。我期望只有一个tk窗口,但是当我运行我的代码时,还有第二个小的空tk窗口。我想这是因为我使用的类,但我不知道.. 这里是我的代码:两个tk窗口而不是一个

from tkinter import* 
import tkinter as tk 
import time 

class Application(Tk): 
    def __init__(self,transfo,nb_itération): 
     Tk.__init__(self) 
     self.transfo = transfo 
     self.nb_itération = nb_itération 



    def affichage_graphique(self): 

     self.matrix_hex = extraction_rgb(tk.PhotoImage(file='obama_128.gif')) 
     self.width , self.height = len(self.matrix_hex[0]) , len(self.matrix_hex) 
     self.WIDTH, self.HEIGHT = 8*self.width+6, 8*self.height+6 
     self.cnv = Canvas(self, width=self.WIDTH, height=self.HEIGHT, bg='white',highlightthickness=0) 
     self.cnv.grid(row = 2 , columnspan = 3) 
     self.txt1 = Label(self, text = 'Transformation :').grid(row = 0 , sticky = E) 
     self.txt2 = Label(self, text = 'Nombre d\'itérations : ').grid(row = 1 , sticky = E) 
     self.entr1 = Entry(self) 
     self.entr2 = Entry(self) 

     self.entr1.grid(row = 0, column = 1, sticky = W) 
     self.entr2.grid(row = 1, column = 1, sticky = W) 
     Button(self, text="Quitter", command=self.destroy).grid(row = 0 , column = 2) 

     if self.transfo == photomaton or self.transfo == boulanger: 

      print("valeur par défaut mauvaise") 
      self.cnv.delete(ALL) 
      self.img01 = self.PhotoImage(width=self.width*4, height=self.height*4) 
      self.img = self.PhotoImage(width=self.width*4, height=self.height*4) 

      self.matrix_hex4 = [[x for x in range(self.width*4)] for y in range(self.height*4)] 
      self.matrix_4 = [[x for x in range(self.width*4)] for y in range(self.height*4)] 


      self.img.put(data=self.matrix_4 , to=(0,0)) 
      self.cnv.create_image(0, 0, image=self.img, anchor=tk.NW) 

      self.img01.put(data=self.matrix_hex4, to=(0,0)) 
      self.cnv.create_image(self.WIDTH, 0, image=self.img01, anchor=tk.NE) 
      self.cnv.bind('<Button-1>',self.click_handler) 

     else: 

      self.img = tk.PhotoImage(width=self.width*4, height=self.height*4) 
      self.img.put(data=self.matrix_4 , to=(0,0)) 
      self.cnv.create_image(0, 0, image=self.img, anchor=tk.NW) 
      self.entr1.insert(0,"photomaton") 
      self.entr2.insert(0,"1") 
      self.entr2.bind("<Return>",Programme().Enter) 



class Programme(Application): 
    def __init__(self,transfo = 0, nb_itération = 0 ,orbites =[],période = []): 
     self.choice = 0 
     self.orbites = orbites 
     self.période = période 
     self.transfo = transfo 
     self.nb_itération = nb_itération 
     Application.__init__(self, self.transfo , self.nb_itération) 


    def Enter(self,event): 
     self.choix_transfo = self.entr1.get() 
     self.nb_itération = self.entr2.get() 
     return self.choix_transfo , self.nb_itération 

    def start(self): 
     self.affichage_graphique() 



prog = Programme() 
prog.start() 
prog.mainloop() 
+1

有一对夫妇在你的代码,阻止我运行它的错误,请发表[最小的,完整的,和可验证示例](https://stackoverflow.com/help/mcve)。例如,'Program .__ init__'在参数列表后面缺少冒号。另外,在'Program .__ init__'中有一个无限递归。 – FamousJameous

+0

我的猜测是(a)你有几个类都扩展了'Tk',或者(b)你有一个类扩展了'Tk'并且还手动创建了一个“root”Tk实例。但是,不能检查,因为你的代码有错误(语法和运行时)。我建议不要扩展'Tk',而是'Frame'。 –

+0

代码中没有任何内容会创建两个窗口。不过,我看到你使用'Program()',但没有这个名字的类或函数。你有一个名为“程序”的课程 - 是否是其中一个错误? –

回答

2

的问题似乎是在这条线:

self.entr2.bind("<Return>",Programme().Enter) 

此行有多个问题:

  1. 它会创建一个Program()实例(假设这是一个错字),因此形成了第二窗口Tk (因为Program延伸Tk
  2. 它会这么做立即,按钮被点击时不仅,而且新实例的方法绑定到按钮

相反,你可能想使用

self.entr2.bind("<Return>", self.Enter) 

调用当前Program实例的Enter方法,或

self.entr2.bind("<Return>", lambda: Program().Enter) 

如果你实际上想要创建第二个Program窗口时点击按钮;但是,在这种情况下,您还需要调用gui方法才能初始化窗口小部件。


注意有代码中的其他一些问题,如在评论中讨论,但我认为,那些不实际的代码存在,否则你不会得到这种行为。

+0

我编辑了我的问题并添加了完整的代码。 –

1

您正在两处创建一个新窗口。首先,这样的:

prog = Programme() 

第二个是在这里:

self.entr2.bind("<Return>",Programme().Enter) 

为什么?上面的代码在功能上与此相同:

p = Programme() 
self.entr2.bind("<Return>", p.Enter) 

调用程序类中定义的函数的正常方法是使用现有引用。因为你的代码是在属于Programme类的方法中运行,你可以这样做:

self.entr2.bind("<Return>", self.Enter) 
+0

“entry.bind”方法创建一个窗口?我能做些什么来避免这种情况?在应用程序类中放入“Enter”? –

+0

Thx为您提供帮助! –

+0

@NathanDubois:no,'entry.bind'不会创建一个窗口,'Program().Enter'会生成一个窗口,因为Program()会创建一个窗口。 –

相关问题